I have been programming in COMAL ever since it came out on the C-64. I used version .14 on disk, then when version 2.00 on the cartridge came out, I bought a cartridge. I later bought an IBM computer, and purchased version 2.2 for that. Later, version 3.0 came out, and later still, version 3.11. I liked the language so much that I purchased 3.11, even though the price at that time was approx. $700. It was later reduced to a more reasonable price.
I have been trying to get more interest in the language, and have posted a checkbook program, and a database program on America On Line. The checkbook program can be found in the downloads section. The checkbook program was my most ambitious program. It is 1660 lines long. The database is generic. Once it is set up, the fields cannot be changed. It will give some idea of how to set up your own database by rewriting it as necessary.
I use System Commander when I wish to maximize memory, and load everything high, even COMAL. The reason for this is that in WINDOWS, some of the DOS memory is used up, and if you are USING a lot of modules in a program, COMAL will complain that there is not enough memory for externals. I load EMM386 and specify NOEMS, and I get 222,400 bytes of DOS memory free. That is plenty to load all of the modules supplied in version 3.11.
Hints, tips and 'wrinkles':
INPUT AT: The first is what happens when an input does not occur where it is expected. It will cause the cursor to disappear! The following code illustrates this:
// Trouble // By Nicholas L. Seachord // email@example.com USE system INPUT AT 10,10:nonsense# LOOP NULL // Do Nothing NULL // Do Nothing NULL // Do Nothing IF curcol=10 then INPUT nonsense# NULL // Do Nothing ENDLOOP
Further complicating matters is the fact that the program will stop at a random line within the loop, so there is apparently no one line that causes this. (It is in fact the second INPUT statement).
Error trapping: The second thing to watch out for is the TRAP-HANDLER-RETRY statement. If you TRAP an error, you should report the error. If you do not, for instance, report that the printer has a problem and cannot print, the user will have no clue and will continually press the ENTER key.
Random-access files: When writing the checkbook manager program, I tried to figure out the offset and pick out a certain byte in a random file. In the help file, it says that an integer occupies 4 bytes. This is apparently a maximum value. The solution is to read in the whole record, manipulate the variable, then write the record to disk again.
Rounding Errors: If you write a program that requires floating point figures, there is sometimes a small error when adding or subtracting. The following code illustrates this:
DIGITS(18) PRINT 8.2 - (6.1 + .1)
It will return a number which is NOT exactly 2. (Actually 1.99999999999999964 - Ed.). I encountered this problem when writing a checkbook manager program. The fix is to multiply dollars and cents by 100, and setting the answer into an integer variable, like this:
DIGITS(18) a# := (8.2-(6.1+.1)*100) PRINT a#/100
This will return the correct answer of 2.
Control keys and input termination: Here's an interesting little tip. If you want to know which letter to associate with a certain key, when in the COMAL environment, press the ESCape key, then the control key (up arrow, down arrow, home, page down, etc.) For instance, [ESC] then [up arrow] gives the letter H. So, your code might say,
IF termchar$=""0"H" THEN CURSOR(currow-1),(0)
Nicholas is referring to the 'termchars' procedure from the System Module, which allows the programmer to decide which keypresses can be used to tell COMAL when the user has finished making an input. This facility is very useful when designing a form-filling data entry screen, for example, because it lets the user type in an input, then press any one of the keys [ENTER], [CURSOR UP], [CURSOR DOWN] and so on to move to the next field on the display. Here is a short demo of using either [CURSOR UP] or [ENTER] to terminate an input:
0100 // INPUT termination demo 0110 // MacharSoft June 1999, thanks to N Seachord 0120 USE system // provides 'termchars' and 'termchar$' 0130 termchars(""0"H"13"") // Either [CURSOR UP] or [ENTER] 0140 PAGE 0150 CURSOR 10,5 0160 INPUT "Type something, then either ENTER or CURSOR UP ": temp$ 0170 IF termchar$=""0"H" THEN // User pressed [CURSOR UP] 0180 CURSOR 9,5 0190 PRINT "You terminated input with [CURSOR UP]." 0200 ELSE // User pressed [ENTER] 0210 CURSOR 11,5 0220 PRINT "You terminated input with [ENTER]." 0230 ENDIF 0240 CURSOR 15,15 0250 END "Termchar demo finished."
- Nicholas' tip about pressing ESCape then the control key makes it very easy to find out which characters are associated with which control keys.]
(Posted 30 June 1999)