Programación adicional

Otro programa

Aquí hay un programa ligeramente más complicado, cópielo en un fichero y grábelo como addition.cob.

       IDENTIFICATION DIVISION.
       PROGRAM-ID.    addition.
       ENVIRONMENT DIVISION.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       77  myvar PIC 999 .
       77  a  PIC 99V999 VALUE 1.777 .
       77  b  PIC 99V99  VALUE ZERO .
       77  c  PIC 9V9    VALUE 5.5 .
       77  d  PIC 9v9    VALUE 5.5 .
          
       PROCEDURE DIVISION.
           DISPLAY "Please enter a number"
           ACCEPT myvar
           DISPLAY "That number was ", myvar
           ADD a TO b ROUNDED
           DISPLAY "b is ", b
           ADD c TO d
           DISPLAY "d is ", d
           STOP RUN.

Usted puede compilarlo con los mismos pasos que empleó para hello.cob, si encuentra algún fallo de segmentación (literal: `Segmentation Fault', compruebe el código del programa antes de abandonar.

N.t.: Se refiere a errores de compilación.

Si usted es novato con Cobol, hay un poco que entender. En primer lugar tenemos algunas variblas declaradas en WORKING-STORAGE SECTION de DATA DIVISION. Cobol necesita que todas las variables se declaren de esta forma. Las otras secciones DATA DIVISION tratan con ficheros y el enlazado.

Aquí todas las declaraciones de variables empiezan por `77'. Esto significa que la variable seencuentra en el nivel 77: no tiene estructura interna y no hay una relación definida con otra variable, no forma parte de un registro (o lo que C llama estructuras). El nombre de la primera variable es myvar; los nombres de las variables pueden estar tanto en mayúsculas como en minúsculas, pero con Tiny Cobol debe ser consistente en todo su programa.

La claúsula PIC especifica el tipo de variable. Usando nueves se indica que se trata de una variable decimal y empleando 3 nueves decimos que la variable puede tomar los valores desde 0 a 999. Se puede poner una `S' delante de los nueves para que la variable sea con signo. Una `V' es la declaración PIC significa que la variable tiene un punto decimal asumido en la posición de V. Para variables grandes puede escribir 9(15), lo que describe a una variable que posee 15 posiciones. Empleando Aes (varias A) en lugar de nueves define una variable alfabética, y empleando Xes (varias X) se define una variable alfanumérica. Finalmente un valor inicial se puede asignar a la variable empleando VALUE.

Los programadores de Cobol sin experiencia pueden estar preguntándose como se indica un final de sentencia. Los finales de bloque se marcan con un punto y aparte, pero las sentencias no se marcan en absoluto, en su lugar el compilador de Cobol reconoce que una nueva sentencia comienza cuando lee una de las diferentes palabras reservadas de Cobol. Los finales de linea no son importantes en Cobol. Otra cosa a señalar en el código anterior son las comas añadidas. Las comas son completamete opcionales en Cobol, puede ponerlas en cualquier punto que desee o en ningún sitio y no hay ninguna diferencia. Úselas con mesura y conseguirá un código mucho más claro.

Cuando se ejecuta el programa debería preguntar por un número, y entonces mostrar ese número junto a los dos cálculos que realiza. El número no puede ser mayor de los 3 espacios reservados para él, sino tan solo los tres últimos caracteres se cogen. Si se proporcionan menos de tres caracteres, se completa con ceros a la izquierda. Caracteres no numéricos mostrarán código para corregir errores.

La suma de las variables a y b debería funcionar bien, aunque notará que la respuesta se redondea tal y como pedimos. La suma de c y de no se llevará a cabo debido a que la respuesta es demasiado grande para caber en la variable d. Cambie c a, digamos, 1.5 y todo funcionará correctamente.

Make

Actualización: Tiny Cobol ahora compila directamente a un programa ejecutable, en lugar de código ensamblador. Mucho de lo que sigue es por lo tanto obsoleto (aunque los conceptos deberían ser útiles).

Ya debería empezar a estar harto de la rutina de htconol, as, gcc. Bien, existe una forma mejor, make. Make toma como entrada un fichero llamado Makefile y usa las instruciones en él para realizar el trabajo sobre lo que necesita ser compilado en un sencillo paso. También comprueba que fichero necesita ser compilado antes de hacer nada, si ninguna de las dependencias del programa han cambiado desde la última compilación, no es necesario hacer nada.

Las reglas de Makefile tienen la siguiente forma:

objetivo: dependencias
	  orden

El objetivo (el cual debe ser escrito en la primera columna) es el fichero que quiere conseguir. Las dependencias son los ficheros que son necesarios para conseguir el objetivo. La orden (que debe estar en una segunda linea y precedida de un TAB) es la orden que normalmente se escribe en el shell para generar el objetivo. Aquí podemos ver el Makefile para addition:

#makefile simple para un programa cobol en un solo fichero

addition:addition.o
	gcc -o addition addition.o -lhtcobol -lm

addition.o:addition.s
	as -o addition addition.s

addition.s:addition.cob
	htcobol addition

Guárdelo como Makefile en el mismo directorio de addition.cob y escriba make. Debería compilar, ensamblar y enlazar por usted.

Por defecto make interpretará la primera regla en el fichero. Esta regla es para crear el binario addition, pero este último depende de addition.o, por lo que debe hacerse primero. addition.o depende de addition.s, así que esa es la primera regla que make ejecuta. Ahora se puede crear addition.o y finalmente addition.o está actualizado y permite crear addition. Si usted intenta escribir make otra vez, make no hará nada porque ninguno de los ficheros ha cambiado y no hay necesidad de hacer nada (make mira la fecha de los ficheros para determinarlo). Cambie addition.cob ligeramente y ejecute run, y el proceso se lleva a cabo otra vez.

Make avanzado

Pero el Makefile anterior tiene un problema: ¿qué ocurre si queremos adaptarlo para trabajar con otro programa? Hay algunos cuantos 'addition' a cambiar, y con un programa más complicado eso podría ser un trabajo importante. Afortunadamente make tiene bastantes buenos trucos en la manga. Aquí tiene un makefile más avanzado:

#makefile para un programa cobol de un solo fichero

PROGRAM := addition
LIBS := -lhtcobol -lm
OBJECTS := $(PROGRAM).o

$(PROGRAM):$(OBJECTS)
	gcc -o $(PROGRAM) $(OBJECTS) $(LIBS)

#regla para cualquier fichero acabando en .o
#depende de el mismo prefijo con .s
# $@ es el objetivo
%.o:%.s
	as -o $@ $<

%.s:%.cob
	htcobol $(PROGRAM)

El Makefile comienza con algunas variable. PROGRAM es el nombre del programa que estamos haciendo. Se puede observar que se usa en la primera regla (precedido de un signo dolar y delimitado por paréntesis). LIBS contiene las librerias que necesitamos para compilar el programa. OBJECTS contiene todos los nombres de objeto necesarios, en este caso es solo uno y tiene el mismo nombre que el programa pero con una .o al final, y así es como se ha declarado.

La segunda regla se ajusta a cualquier objetivo acabado en .o (%.o) y requiere el mismo fichero con un sufijo .s (%.s es una dependencia). La variable automática $@ se ajusta al nombre del objetivo y $< se ajusta a la primera dependencia. A partir de este punto usted ya debería poder seguir los pasos hasta el objetivo final.

Si quiere adaptar este Makefile a otro programa Cobol, todo lo que tiene que hacer es cambiar el valor de la variable $PROGRAM.