Documentation for Algol 68 Genie Mark 11
|
Context-free syntax summary· Notions and notation· Reserved symbols · Coercions · Tags · Particular program · Clauses · Expressions · Primaries · Secondaries · Tertiaries · Units · Declarations · Declarers · Formats · Pragments · Refinements |
|
|
This syntax summary provides a quick reference for Algol68G syntax. Predefined tags can be found in a different chapter. There is a separate chapter with sample programs.
The syntax described here is context-free. The advantage of presenting a context-free syntax is that the backbone of constructions can be explained quickly. The disadvantage is that a context-free grammar cannot reject programs that are semantically incorrect, for instance those that apply undeclared tags. The two-level Algol 68 syntax is described in the Revised Report.
This paragraph introduces notions and notation used in this reference text.
| Notion, notation | Meaning |
| a value |
TRUE or FALSE)
EMPTY)
(note that there is neither a united value nor a flexible value, id est there is no value with mode UNION or FLEX) |
| a name | a name is a value that refers to another value, or which can be NIL (that refers to no value) |
| ( ) | used to group notions |
| [SOME] | means "optional SOME" |
| a: b. | means "definition of a is b" |
| a, b | means "a or b" |
| `SOME' | means literal symbol SOME |
| SOME-list | SOME [`,' SOME-list] |
| SOME-sequence | SOME [SOME-sequence] |
Next symbols are reserved in Algol 68 Genie Mark 11:
ANDF,
ANDTH,
ASSERT,
ASSIGN,
AT,
BEGIN,
BITS,
COMMENT,
PRAGMAT,
BOOL,
BY,
BYTES,
CASE,
CHANNEL,
CHAR,
CODE,
COL,
COMPLEX,
COMPL,
DIAG,
DO,
DOWNTO,
EDOC,
ELIF,
ELSE,
ELSF,
EMPTY,
END,
ENVIRON,
ESAC,
EXIT,
FALSE,
FILE,
FI,
FLEX,
FORMAT,
FOR,
FROM,
GO,
GOTO,
HEAP,
IF,
IN,
INT,
ISNT,
IS,
LOC,
LONG,
MODE,
NIL,
OD,
OF,
OP,
OREL,
ORF,
OUSE,
OUT,
PAR,
PIPE,
PRIO,
PROC,
REAL,
REF,
ROW,
SEMA,
SHORT,
SKIP,
SOUND,
STRING,
STRUCT,
THEF,
THEN,
TO,
TRNSP,
TRUE,
UNION,
UNTIL,
VOID,
WHILE
The "strength" of a context determines what coercions are possible in that context. A "strong" context allows all coercions, and typically requires that the resulting mode is known a priori; for example in the case of initial values assigned in a declaration or parameters in procedure calls.
| Context strength | Allowed coercions |
| soft | deproceduring |
| weak | dereferencing or deproceduring, yielding a name |
| meek | dereferencing or deproceduring |
| firm | meek, followed by uniting |
| strong | firm, followed by widening, rowing or voiding |
In a strong context, Algol68G implements next widenings:
| From | To |
| INT | REAL LONG INT |
| LONG INT | LONG LONG INT LONG LONG REAL |
| LONG LONG INT | LONG LONG REAL |
| REAL | COMPLEX LONG REAL |
| LONG REAL | LONG LONG REAL LONG COMPLEX |
| LONG LONG REAL | LONG LONG COMPLEX |
| COMPLEX | LONG COMPLEX |
| LONG COMPLEX | LONG LONG COMPLEX |
| BITS | LONG BITS |
| LONG BITS | LONG LONG BITS |
| BITS LONG BITS LONG LONG BITS |
[ ] BOOL |
| BYTES LONG BYTES |
[ ] CHAR |
- TREE
NUMBER
identifier: lowercase-letter [(lowercase letter, digit)-sequence].
- pi
x mod 2pi # note that whitespace is irrelevant in identifiers #
label: identifier.
To avoid ambiguity in parsing operator tag sequences,
operator characters are divided into monads and nomads,
the latter group being inherently dyadic. Next rules force that for instance
1++-1 can only mean 1 `+' `+' `-' 2, and 1+>2 can only mean 1 `+>' 2.
Note that Algol 68 forbids operator tags that start with a double monad, such as `++' or `&&', though dyadic operator tags starting with a double nomad (`**', `>>', etcetera) are allowed.
monad: `+', `-', `!', `?', `%', `^', `&', `~'.
nomad: `<', `>', `/', `=', `*'.
operator: monadic operator, dyadic operator.
monadic operator: uppercase-letter-sequence, monad[nomad][`:=', `=:'].
- ABS, SIGN, CONJ
+, +=, +==:
dyadic operator: uppercase-letter-sequence, (monad, nomad)[nomad][`:=', `=:'].
- ELEM, OVER, MOD
*, **, **:=, **=:
A particular program is the actual application, embedded in the standard environ.
begin: start: BEGIN print ("Hello, world!") END
Serial - and enquiry clauses describe how declarations and units ("statements") are put in sequence. Algol 68 requires clauses to yield a value. As declarations yield no value, serial- and enquiry-clauses cannot end in a declaration.
EXIT leaves a serial-clause, yielding the value of the preceeding unit. If the unit following
EXIT would not be labeled, it could never be reached. Hence Revised Report syntax
for the serial-clause is more elaborate than presented here to require that the unit following EXIT is labeled.
In a serial-clause there cannot be labeled units before declarations to prevent re-entering declarations
once they have been executed.
- # Not a recommended style #
REAL sum := 0, INT k := 0; again: sum +:= k; IF (k +:= 1) <= limit THEN again FI
- # Serial clause yielding BOOL value #
IF INT child = fork; child > 0 THEN wait pid (child); TRUE ELSE print ("fork failed"); FALSE FI
# Serial clause yielding VOID #
print ("give two numbers"); INT n = read int, m = read int; print (("their sum is ", m + n))
An enquiry-clause provides a value to direct the conditional-clause, integer-case-clause, united-case-clause or while-part in a loop-clause. An enquiry-clause has no labels, so you cannot for instance jump back to the enquiry-clause at IF
from the serial-clause at THEN.
-
INT mid = (top + bottom) OVER 2; elem [mid] ~= sought
- n > 1
UNION (REAL, INT) z
Enclosed clauses provide structure for a particular program.
- BEGIN REAL z = read real; sin (z) END
2 * (k + 1) # Orthogonality! #
displays which are denotations for a row or structured value.
- COMPLEX z := (a * c - b * d, a * d + b * c)
- [ ] REAL origin = (0, 0, 0)
- print ( ("The sum is ", m + n") ) # display for [ ] SIMPLOUT #
FLEX [ ] INT k := ( ) # "vacuum" - display for an empty row #
- REAL max := (a > b | a | b)
IF INT k = read int; k > 0 THEN OP ! = (INT n) INT: (n = 0 | 1 | n * ! (n - 1)); print (! k) FI
CASE k IN option (1), option (2) OUT option error ESAC
CASE u IN (INT): print ("INT"), (REAL x): print (sin (x)) ESAC
- FOR i TO 10 DO item [i] := 0 OD
- FOR i FROM 10 DOWNTO WHILE item [i] ~= sought DO print (i) OD
DO print ("*") OD # will write "*" until the end of time #
Expressions are orthogonal, for instance an enclosed-clause can be an operand in a formula. The constituent constructs of expressions are primaries, secondaries, tertiaries and units.
- sin (x)
- put (stand error, (new line, x, y, z := x + y))
fun(1)(x)
- putf (, (new line, x, y, z := x + y)) (standout)
PROC (CHAR, STRING) BOOL strchr = char in string (, HEAP INT,)
- z [1 : 10, 3]
- z [n] [3]
- z [2 : ]
(condition | x | y) [10,, @0]
- VOID (open (file, "idf", standin channel)) # Discard result of open #
REF TREE (root) :=: NIL # Force comparison of a REF TREE value #
0, SHORT 1, LONG 10000000000000
1.0, 1E3, SHORT 3.1415927, LONG 3.141592653589793238462643383
2r1010, 8r377, LONG 16rffffffffffff
- "a"
"""" # Since two adjacent denotations cannot occur in Algol 68, "" within "" denotes a quote #
"Hello, world!"
UNION (INT, VOID) uiv := (value available | value | EMPTY)
- re OF z
im OF (end point OF z)
- HEAP INT
- LOC [1 : 10] REAL
LOC PROC (INT) INT
- - 1
- - SIGN z * ARG z # means (- (SIGN z)) * (ARG z)
- x ** 2 # means (- x) ** 2, not - (x ** 2) ! #
[3, 3] BOOL z; DIAG z := (TRUE, TRUE, TRUE) # same as z[1, 1] := z[2, 2] := z[3, 3] := TRUE #
- x := pi + phase shift
- z := z1 := IF in plane THEN (0, 1) ELSE (0, 0) FI
(selector | x, y, z) := 1 # assigns to either x, y or z depending on selector #
- REF TREE (root) IS NIL, REF TREE (root) :=: NIL
name 1 :/=: name 2
on file end (standin, PROC (REF FILE f) VOID: stop)
# Pitfall - failure to write the jump as a routine-text here will jump immediately! #
ASSERT (n /= 0 AND m > n)
- (z ISNT NIL) ANDF freq OF z > 0 # avoid dereferencing NIL #
IF a = b THEF b = c THEN print ("a = b = c") FI
- REF STRING: HEAP STRING := "xyzzy"
- (REAL x) REAL: sin (2 * z)
(INT k) INT: (k > 0 | k | -k)
Declarations introduce definitions of tags. Algol 68 does not require that a tag is defined before it is used (although Algol 68 does require that a tag is assigned a value before it is used). Hence there is no need for forward declarations when defining mutually recursive procedures, or recursive modes.
MODE TREE = STRUCT (INFO info, NODE smaller, larger), INFO = STRING, NODE = REF TREE
INT number = 1000, [ ] INT first primes = (1, 3, 5, 7, 11)
- REAL sum := 0, max := - max real
HEAP INT k := read int, LOC BOOL z := k = 1
PROC inc = (INT n) INT: n + 1
LOC PROC inc := (INT n) INT: n + 1
- OP F = (INT i) INT: (i > 0 | i * F (i - 1) | 1)
OP (REAL) REAL SQRT = sqrt, LN = ln, TAN = tan
PRIO + = 6, * = 7, / = 7
Declarers describe modes. The context determines whether a mode must be formal, virtual, or actual. Formal- or virtual-declarers are needed where the size of rows is irrelevant. Actual declarers are needed where the size of rows must be known, for instance when allocating memory for rows.
Algol 68 employs structural equivalence for modes. Note that field identifiers in structured values are part of the mode, but bounds of a row are not (these are part of the value). For example:
MODE PERPLEX = [1 : 2] STRUCT (REAL re, im) introduces a mode equivalent to
[1 : 3] COMPL # COMPL is a primitive mode, defined as STRUCT (REAL re, im) #
- LONG LONG COMPLEX
- MODE ROW = [1 : n] STRUCT (INT re, im)
- REF [,, ] INT
- STRUCT (UNION (FORM, RULE, VOID) value, UNION (PROC (FORM) RULE, VOID) action)
PROC (INT, STRING) REF FLEX [ ] STRING
Formats describe the lay-out for transputting data. Formats are values so you can have format-variables, procedures yielding formats etcetera. A format-text can be considered as a (dynamic) "format-denotation".
printf (($2l"The sum is:"x, g(0)$, m + n)) prints the same as
print ((new line, new line, "The sum is:", space, whole (m + n, 0))
- 9
n (um | (INT): int width, (REAL): real width)
- 3p # 3 calls to newpage #
- l # calls newline #
- x, q # calls space #
- n (10 * j) k # advances to position 10 * j in the current line #
- "The result is" # literal text #
l3x"$" # transputs new line, 3 spaces, and a dollar-sign #
- g # default format as used by read and print #
- g (0) # calls "whole" #
- g (12, 8) # calls "fixed" #
g (-12, 3, 2) # calls "float" #
General-pattern `h� is an Algol68G extension that calls procedure real for conversion of NUMBER values.
- h # for NUMBER values, conversion adjusted to make the exponent a multiple of 3,
otherwise as pattern `g� #
- h (14) #
L REAL conversion to 14 decimal places (without adjustment of the exponent) #
- h (14, 3) # as h(14) but adjusted to make the exponent a multiple of 3 #
- h (24, 14, 3) # as h(14, 3) with total width of 24 positions #
h (24, 14, 5, 3) # as h (24, 14, 3) with exponent width of 5 positions #
- 4d # transputs 9 as "0009", error on negative number since there is no sign-mould #
- zzz-d, 3z-d # transputs -9 as " -9" #
3z","2z-d # transputs 100000 as " 100,000" #
- +, -
zzz+, 3z+
- 4d, dddd, zzzd
3d"-"3d"-"4d # transputs 5551234567 as 555-123-4567 #
- d.3d # transputs pi as "3.142" #
- d.3dez-d # transputs 0.3333 as "3.333e -1" #
ds.","3dse"^"z-d # transputs 0.3333 as "3,333^ -1" #
- -d.3di-d.3d # transputs f.i. 0.000i-1.000 #
-d.3dsi-d.3d, "j" # transputs f.i. 0.000-1.000j #
- 2r7zd # binary 8-bit byte with trailing zero-bit suppression #
16r8d # hexadecimal 32 bit word without trailing zero-digit suppression #
- printf ($7a$, "Algol68") # prints "Algol68" #
- printf ($5a"-"2a, "Algol68") # prints "Algol-68" #
printf ($5a2sa, "Algol68") # prints "Algol" #
printf ($b ("true", "not true")$, read bool)
printf ($c ("one", "two", "three")$, read int)
f (um | (INT): $g(0)$, (REAL): $g(0, 4)$)
Pragments are either pragmats or comments. Pragmats contain preprocessor directives, or set options from within an Algol 68 program.
- PR heap=32M PR
- COMMENT do not use for n > 100 COMMENT
The refinement preprocessor is a low-level tool for top-down programming. It is not really a part of Algol68G syntax, but superimposed on top of it. Note that refinements interfere somewhat with labels.
(read and add). read and add: INT m = read int, n = read int; INT sum := m + n.
read and add: INT m = read int, n = read int; INT sum := m + n.
INT m = read int, n = read int; INT sum := m + n
Copyright © 2001-2007 J. Marcel van der Veer.
Algol 68 Genie Mark 11 (November 2007)