Further Programming

Another Program

Here is a slightly more complicated program, enter it into a file and save it as 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.

You can compile this with the same routine as you did with hello.cob, if you encounter any Segmentation Faults double check your program before complaining.

If you are new to Cobol, there is a bit to take in here. Firstly we have some variables declared in the WORKING-STORAGE SECTION of the DATA DIVISION. Cobol requires that all variables be declared in this way. The other DATA DIVISION sections deal with files and linkage.

The variable declarations here all start off with `77'. This means the variable is at level 77: it has no internal structure and no defined relationship to any other variable, it isn't part of a record (or what C calls structs). The name of the first variable is myvar; variable names can be in either upper or lower case, but with Tiny Cobol you must be consistent throughout your program.

The PIC clause specifies the type of variable. Using 9s means it is a decimal variable and using 3 9s makes a variable which can take the numbers 0 to 999. You can also have an `S' before the 9s to make a signed variable. A `V' in the PIC declaration means a variable with an assumed decimal point at the V position. For large variables you can write 9(15), which is a variable that has 15 places. Using As instead of 9s makes an alphabetic variable, and using Xs makes an alphanumeric variable. Finally an initial VALUE can be assigned to the variable.

Inexperienced Cobol programmers may be wondering how an end of a statement is marked. The ends of blocks are marked with a full stop but statements aren't marked at all, instead the Cobol compiler recognises when a new statement begins by noticing one of Cobol's large number of verb words. The end of lines is not important in Cobol. Another thing to notice in the above code is the added commas. Commas are completely optional in Cobol, you can put them in anywhere you like or nowhere at all and it makes no difference. Use them sparingly and they will make your program neater.

When running the program it should ask you for a number, then print that number along with the two other calculations it just performed. The number given can't be longer than the 3 spaces allocated to it, else only the final three characters are taken. If fewer than three characters are given then it will print out with leading zeros. Non numeric characters will output some debugging code.

The adding of variables a and b should work fine, although you'll notice that the answer is rounded as we asked for. Adding c and d won't do anything since the answer is too big to fit in the variable d. Try changing c to, say, 1.5 and everything will work fine.

Make

Update: Tiny-cobol now compiles directly to an executable programme, rather than assembly code. Much of this is therefore obsolete (but the concepts should be useful).

By now you might be getting a little bored of the htcobol, as, gcc routine. Well there is a better way, make. Make takes in a file called a Makefile and uses the instructions in it to work out what need compiled in one easy step. It also checks that a file needs compiling before it does anything, if none of the program's dependancies have changed since the last compile, nothing has to be done.

Makefile rules are in the form:

target:dependencies
	  command

The target (which must begin in the first column) is the file you're trying to get. The dependencies are the files that it depends on. The command (which must be on a second line and preceded by a tab) is the command you would normally type at the shell to make your file. Here's a Makefile for addition:

#simple makefile for a one file cobol program

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

Save this as Makefile in the same directory as addition.cob and type make. It should compile, assemble and link for you.

By default make will compile the first rule in the file. This is to create the addition binary, but this depends on addition.o so that must be made first. addition.o depends on addition.s so this is the first command that make runs. Now it can create addition.o and finally addition.o is up to date so it can create addition. If you try typing make again it won't do anything because none of the files have changed so there's no need (make looks at the file's timestamp to determine this). Change addition.cob slightly and run make and the whole process runs again.

Advanced Make

But the previous Makefile has a problem: what if you want to adapt it to work with another program? There are quite a few addition's to change and with a more complicated program that would take ages. Fortunately make has a good many tricks up it's sleeve. Here is a more advanced makefile:

#makefile for a one file cobol program

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

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

#rule for any file ending in .o
#depends on same prefix with .s
# $@ is the target
%.o:%.s
	as -o $@ $<

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

The Makefile starts off with some variables. PROGRAM is the name of the program we are making. You can see it used in the first rule (preceded by a dollar sign and delimited with brackets). LIBS is just the libraries that we need to compile the program. OBJECTS is any object files needed, in this case it's just the one and that has the same name as the program with a .o on the end, which is just how it's declared.

The second rule matches any target ending in .o (%.o) and it requires the same file with a .s suffix (%.s as a dependency). The automatic variable $@ matches the name of the target and $< matches the first dependancy. By now you should be also to work your way through the final target.

If you want to adapt this Makefile to another Cobol program, all you have to do is change the value of the $PROGRAM variable.