|
|
ALGOL68G implements an extended subset of the language described in the Revised Report. ALGOL68G is an interpreter that offers many runtime checks, in this sense ALGOL68G bears resemblance to FLACC. ALGOL68G is intended for small to medium sized algorithms, solving not too complex problems.
ALGOL68G actually is a Mailloux-type implementation. A hand coded parser makes several passes resolving the program text hence tags can be applied before they are declared, etcetera. This type of implementation also produces few spurious errors while parsing since ALGOL68G only allows a pass to start when the preceeding ones terminated succesfully.
ALGOL68G implements flexible names, transient names and proceduring of jumps to proc void.ALGOL68G implements the Revised Report in this respect, hence symbols can be applied before they are declared. This allows for top down programming:OP ELEM = (ELEMENT sought, NODE root) BOOL:
.. ;
PRIO ELEM = 8;
.. ;
MODE NODE = REF STRUCT (ELEMENT record, .. );
.. ;
MODE ELEMENT = .. ;
ALGOL68G elaborates bounds as the Revised Report requires it, that is, at any generator. Example:MODE A = [1 : n] INT;
INT n := read int;
A row 1;
n *:= 2;
A row 2;
ALGOL68G correctly executes this oddity.
ALGOL68C never had a working one.GNU plotutils through extension of Algol 68 transput.C type double. Note that there is no implementation of a single precision short real.ALGOL68G implements long long real with user defined precision.ALGOL68G appear more strict than applied by some former implementations, since ALGOL68G identifies scope violations in some programs of the MC Revised Algol 68 Test Set. This is because ALGOL68G enforces the (Revised Report) rules:
Examples:
[n] REF INT i; BEGIN INT j; i[1 + ENTIER (n * random)] := j; ... END; ...REF INT i; BEGIN INT j; i := j; ... END; ...PROC VOID pp; INT n := 0; (PROC p = VOID: print (n); pp := p);PROC pp = INT: (HEAP INT n := 0; INT: n);ALGOL68G sees files as things to read data from or to write data to, not as books.
() INT must be written as [] INT. The rationale for having alternative notations was that in the sixties and seventies when Algol 68 was developed, not all IO devices featured `[' and `]' symbols.MODE A = [1 .. n] INT;
INT n := read int;
A z;
z [1 .. n - 1] := ... ;
ALGOL68G's interpreter emulates a stack machine with a heap. Two stacks are used, one to evaluate expressions, and one to stack call frames. Heap management in Algol 68 is implicit; when the heap is full, a garbage collector will compact it. This requires pointers in the heap to be actually handles, as to allow the garbage collector to shift data in the heap.
The stacks and the heap - and handle pool are separate blocks with presetable size. The reason for memory being set up this way is that fixed-size blocks prevent ALGOL68G from allocating all memory available to it before the garbage collector is called, which would impede overall system performance.
The sizes of the four blocks can be controlled using options, and are specified as the number of 1 kB blocks. Current default values are expression stack 512, frame stack 512, handle pool 1024 and heap 4096.
ALGOL68G is rated with the Whetstone benchmark and currently peaks at 3.3 MWhets on a 100 MWhets G3 PowerPC (233 MHz) running LinuxPPC 2000. Note that this performance is reached with all run time checks enabled. For comparison, a VAX 11/785 rated approximately 1.1 MWhets and a VAX 8650 rated approximately 3.8 MWhets, both running FORTRAN.
ALGOL68G offers many runtime checks, and arguments to math functions are checked, overflow and underflow may go undetected when hardware does not trap such condition.PRIO+=1 will be scanned as `PRIO' `+=' `1', resulting in an error message.ALGOL68G was not designed with size efficiency in mind. A program may need more memory than a comparable program in another high level language. This is due to several reasons: not all recursion is removed from the interpreter, basic types have overhead as to check values for emptiness etcetera.ALGOL68G supports an extension called assertions. Assertions can be viewed in two ways. First, they provide a notation for invariants that can be used to code a proof of correctness together with an algorithm. Hardly anyone does this, but assertions make for debugging statements. The syntax for assertions reads
Under control of the `assertions' and `noassertions' pragmat items, the enquiry clause of an assertion is elaborated at runtime. If the enquiry clause yields false, the program is terminated and a runtime error is generated. Example:
OP FACULTY = (INT n) INT: ({n >= 0}; n > 0 | n * FACULTY (n - 1) | 1);
will produce a runtime error when faculty is called with a negative argument.
GNU plotutilsALGOL68G offers a number of routines for drawing. To this end it implements a subset of libplot from GNU plotutils. This allows for drawing in for example X windows and pnm files from Algol 68. Note that ALGOL68G is not an Algol 68 binding for libplot.
A plotter (window, postscript file, etcetera) can be considered as a stream to which plotting commands are `written', hence ALGOL68G considers plotters to be objects of mode ref file. To interface with libplot, the transput model has been augmented as to accommodate plotters. A plotter must be opened and closed, just like any file. To specify the file to be a drawing device, stand draw channel is declared in the standard environment, that yields true when inspected by draw possible. To specify details on the plotter type and page size, a procedure make device has to be used. For example:
FILE window; |
|
make device (window, "X", "600x400"); |
# `window' is an X window with 600x400 pixels # |
open (window, "Hello!", stand draw channel); |
# The string will be the X window name # |
draw erase (window); |
# Only now does the window appear on the screen # |
draw move (window, 0.25, 0.5); |
# Goto pixel 0.25x600, 0.5x400 # |
draw color (window, 1, 0, 0); |
# Color will be 100% red, 0% green, 0% blue # |
draw text (window, "c", "c", "Hello!"); |
# Writes an aligned text # |
VOID (read char); |
# Give audience a chance to read the message # |
close (window); |
# The window disappears from the screen # |
Implemented drawing routines are part of the standard environment.
ALGOL68G alpha release only supports these two). X plotters write graphics to an X Window System display rather than to an output stream. Error messages from libplot are written to the ALGOL68G log file. A runtime error results when the plotter could not be opened.16r0001 .. 16rffff, indicates that objects should be filled. A value of 1 signifies 100% filling; the fill color will be the color specified by calling draw color. If level = 16rffff, the fill color will be white. Values 16r0002 .. 16rfffe represent a proportional saturation level, for instance 16r8000 denotes 50%."solid" -------------------------------- "dotted" - - - - - - - - "dotdashed" ---- - ---- - ---- - "shortdashed" ---- ---- ---- ---- "longdashed" ------- ------- ------- "dotdotdashed" ---- - - ---- - - "dotdotdotdashed" ---- - - - ---- - - -In the preceding patterns, each hyphen stands for one line thickness. This is the case for sufficiently thick lines, at least. So for sufficiently thick lines, the distance over which a dash pattern repeats is scaled proportionately to the line thickness. The "disconnected" line style is special. A "disconnected" path is rendered as a set of filled circles, each of which has diameter equal to the nominal line thickness. One of these circles is centered on each of the juncture points of the path (i.e., the endpoints of the line segments or arcs from which it is constructed). Circles with "disconnected" line style are invisible. Disconnected circles are not filled. All line styles are supported by all plotters.
`l', `c', or `r', then the string will be drawn with left, centre or right justification, relative to the current graphics cursor position. If vert_justify is equal to `b', `x', `c', or `t', then the bottom, baseline, centre or top of the string will be placed even with the current graphics cursor position. The graphics cursor is moved to the right end of the string if left justification is specified, and to the left end if right justification is specified. The string may contain escape sequences of various sorts (see section Text string format and escape sequences in the plotutils manual), though it should not contain line feeds or carriage returns; in fact it should include only printable characters. The string may be plotted at a nonzero angle, if draw textangle has been called.
plotutils manual.
Options are passed to ALGOL68G either from the command line or through pragmats. Options are not case sensitive. In the table below, bold letters denote letters mandatory for recognition. Listing and tracing options, and also -pragmat, -nopragmat, take their effect when they are encountered in a left-to-right pass of the program text, and can thus be used, for example, to generate a cross reference for a particular part of the user program.
-print unitALGOL68G can execute one-liners from the command line. See also -execute.-execute unitALGOL68G can execute one-liners from the command line. See also -print.ALGOL68G manages allocation and deallocation of heap space. However, if memory would be unbound, ALGOL68G might claim all available memory before the garbage collector is called. This would impede overall system performance. Therefore memory size is bound.
-heap numberALGOL68G will use the heap to store temporary arrays, so even a program that has no heap generators requires some heap space, and might even invoke the garbage collector.-handles number-frame number-stack number-extensive-listing-moids-preludelisting-source, -nosource-statistics-terminalstdout.-tree, -notree-unused-xref, -noxref-assertions, -noassertions-help-norun-nowarnings-pragmats, -nopragmats-pragmats.-precision numberALGOL68G algorithms for extended precision are not really suited for precisions larger than a few hundred digits.-trace, -notrace-verboseALGOL68G will inform you on its actions.-versionALGOL68G, including date of compilation.$ a68g -p 'long long pi' -prec 250
+3.141592653589793238462643383279502884197169399375105820974944592307816
406286208998628034825342117067982148086513282306647093844609550582231725
359408128481117450284102701938521105559644622948954930381964428810975665
933446128475648233786783165271201909E +0
$
$ a68g -e "INT m = read int, n = read int; print ((m + n, m - n))"
20 10
+30 +10
$
ALGOL68G#
ALGOL68G#ALGOL68G#
| Operator tag | Alternative |
| = | eq |
| /= | ne, ~=, ^= |
| < | lt |
| <= | le |
| > | gt |
| >= | ge |
| & | and |
| +* | i |
| %* | mod |
| ~ | not |
| % | over |
| ** | up, ^ |
| +:= | plusab |
| -:= | minusab |
| *:= | timesab |
| /:= | divab |
| %:= | overab |
| %*:= | modab |
| +=: | plusto |
| Priority | Operators |
| 1 | +:=, -:=, *:=, /:=, %:=, %*:=, +=: |
| 2 | or |
| 3 | &, xor |
| 4 | =, /= |
| 5 | <, <=, >, >= |
| 6 | +, - |
| 7 | *, /, %, %*, elem |
| 8 | **, lwb, upb |
| 9 | +* |
| mode a | Implemented operators |
| int real complex long int long real long complex long long real |
op (a) a +, -, abs, sign |
| real long real long long real |
op (a) a nint |
| real | op (a) int round, entier |
| long real | op (a) long int round, entier |
| complex long complex |
op (a) real re, im, abs, arg |
| complex long complex |
op (a) a conj |
| bool bits |
op (a) a ~ |
| char bits |
op (a) int abs |
| int | op (a) char repr op (a) bits bin |
| int long int |
op (a) bool odd |
| ?rows | op (a) int lwb, upb |
| mode a | Implemented operators |
| int | op (a) long int leng |
| long int | op (a) int shorten |
| real | op (a) long real leng |
| long real | op (a) real shorten |
| complex | op (a) long complex leng |
| long complex | op (a) complex shorten |
| long real | op (a) long long real leng |
| long long real | op (a) long real shorten |
| mode a | mode b | Implemented operators |
| int | int | op (a, b) int +, -, *, %, *%, ** op (a, b) real / op (a, b) complex +* op (a, b) bool =, /=, <, <=, >, >= op (ref a, b) ref a +:=, -:=, *:=, %:=, %*:= |
| real | real int |
op (a, b) real +, -, *, /, ** op (b, a) real +, -, *, /, ** op (a, b) complex +* op (b, a) complex +* op (a, b) bool =, /=, <, <=, >, >= op (b, a) bool =, /=, <, <=, >, >= op (ref a, b) ref a +:=, -:=, *:=, /:= |
| complex | complex real int</ td> |
op (a, b) complex +, -, *, /, ** op (b, a) complex +, -, *, /, ** op (a, b) bool =, /= op (b, a) bool =, /= op (ref a, b) ref a +:=, -:=, *:=, /:= |
| long int | long int int |
op (a, b) long int +, -, *, %, *%, ** op (b, a) long int +, -, *, %, *%, ** op (a, b) long real / op (b, a) long real / op (a, b) long complex +* op (b, a) long complex +* op (a, b) bool =, /=, <, <=, >, >= op (b, a) bool =, /=, <, <=, >, >= op (ref a, b) ref a +:=, -:=, *:=, %:=, %*:= |
| long real | long real long int real int |
op (a, b) long real +, -, *, /, ** op (b, a) long real +, -, *, /, ** op (a, b) long complex +* op (b, a) long complex +* op (a, b) bool =, /=, <, <=, >, >= op (b, a) bool =, /=, <, <=, >, >= op (ref a, b) ref a +:=, -:=, *:=, /:= |
| long complex | long complex long real long int complex real int |
op (a, b) long complex +, -, *, /, ** op (b, a) long complex +, -, *, /, ** op (a, b) bool =, /= op (b, a) bool =, /= op (ref a, b) ref a +:=, -:=, *:=, /:= |
| long long real | long long real long real long int real int |
op (a, b) long long real +, -, *, /, ** op (b, a) long long real +, -, *, /, ** op (a, b) bool =, /=, <, <=, >, >= op (b, a) bool =, /=, <, <=, >, >= op (ref a, b) ref a +:=, -:=, *:= |
| bool | bool | op (a, b) bool &, or, xor, =, /= |
| string char |
string char |
op (a, b) string + op (a, b) bool =, /=, <, <=, >, >= |
| string | string char |
op (ref a, b) ref a +:= op (b, ref a) ref a +=: |
| string char |
int | op (a, b) string * op (b, a) string * |
| string | int | op (ref a, b) ref a *:= op (a, b) char elem |
| bits | bits | op (a, b) bits &, or, xor op (a, b) bool =, /=, <, <=, >, >= |
| bits | int | op (a, b) bits shl, shr op (a, b) bool elem |
| int | ?rows | op (a, b) int upb, lwb |
plotutils Package.After a program from the MC Revised Algol 68 Test Set.
# After `P. G. Hibbard, Proc. Int. Conf. A68 III, Winnipeg, June, 1974' # # Applied occurrence of mode-indication in actual-bounds of its actual-declarer # INT n := read int;
CHAR a := "a", b := "b", c := "c"; PROC swap = (REF CHAR c1, c2) VOID: (CHAR d = c1; c1 := c2; c2 := d); MODE HANOI = [ IF n > 0 THEN n -:= 1; swap(b, c); HANOI h1; swap(b, c); print((newline, "move ", whole(LWB h1 + 1, 0), " from ", a, " to ", c, ".")); swap(a, b); HANOI h2; swap(a, b); n +:= 1 ELSE 0 FI : 1] INT; LOC HANOI