├── .gitignore ├── CHANGES ├── COPYING ├── COPYING.LESSER ├── COPYRIGHTS ├── Examples ├── List │ ├── BEGIN │ ├── END │ ├── Makefile │ ├── README │ ├── argv-library.c │ ├── argv.alw │ ├── expected.output │ ├── io-library.c │ ├── io.alw │ ├── list.alw │ ├── test1.txt │ ├── test2.txt │ └── test3.txt ├── Logic │ ├── Makefile │ ├── README │ ├── argv.c │ ├── expected.output │ ├── logic.alw │ ├── logic.py │ ├── logic68.a68 │ ├── logicpas.pas │ └── tests.sh ├── Macro │ ├── Makefile │ ├── macro.1.md │ ├── macro.1.src │ ├── macro.alw │ ├── man.py │ ├── stip_begin.alw │ ├── stip_end.alw │ ├── test.expected │ └── test.input ├── Roman │ ├── BEGIN │ ├── END │ ├── Makefile │ ├── argv-library.c │ ├── argv.alw │ ├── expected.output │ ├── number.alw │ └── roman.alw ├── Wumpus │ ├── Makefile │ └── wumpus.alw └── test-cords │ ├── BEGIN │ ├── END │ ├── Makefile │ ├── README │ ├── cords.alw │ ├── cords.c │ ├── cords │ ├── README.txt │ ├── cord.h │ ├── cordbscs.c │ ├── cordprnt.c │ ├── cordtest.c │ ├── cordxtra.c │ ├── ec.h │ └── private │ │ └── cord_pos.h │ ├── file.alw │ ├── file.c │ └── try-it.alw ├── INSTALL.md ├── Makefile ├── Makefile.awe ├── Makefile.testparsing ├── OCamlMakefile ├── README.md ├── Tests ├── Argv-Multisource │ ├── Makefile │ ├── argv-headers.alw │ ├── argv.c │ ├── begin │ ├── end │ ├── expected.output │ └── program.alw ├── Argv │ ├── Makefile │ ├── argv.c │ ├── expected.output │ └── program.alw ├── ExternalRecords │ ├── Makefile │ ├── expected.output │ ├── external.txt │ ├── io-library.c │ └── program.alw ├── InitFlag │ └── withinit.alw ├── Makefile ├── Multifile-Error │ ├── Makefile │ ├── argv-headers.alw │ ├── begin.alw │ ├── end.alw │ ├── expected.output │ └── program.alw ├── OldParse │ ├── GRAMMAR │ ├── Makefile │ ├── expected.output │ └── original-parse.alw ├── Separate │ ├── Makefile │ ├── expected.output │ ├── program.alw │ └── separate.alw ├── SeparateC │ ├── Makefile │ ├── cprocedure.c │ ├── expected.output │ └── program.alw ├── Stderr-redirection │ ├── Makefile │ ├── expected-stderr.output │ ├── expected-stdout.output │ └── program.alw ├── Strings-as-bytes │ ├── Makefile │ ├── byte-access.c │ └── program.alw ├── Tracing │ ├── Makefile │ ├── expected.output │ ├── program.alw │ └── tracing.c ├── array-bounds-empty-arrays-2.alw ├── array-bounds-empty-arrays.alw ├── array-bounds-subscript-count.alw ├── array-bounds.alw ├── array-designator-as-parameter.alw ├── array-parameters-type-cast.alw ├── array-parameters-type-error.alw ├── array-parameters.alw ├── array-range.alw ├── array-references-init.alw ├── array-strings.alw ├── array.alw ├── arrays-multidimensional-range.alw ├── arrays-multidimensional.alw ├── begin ├── constants-range-bits-too-big.alw ├── constants-range-integer-too-big.alw ├── constants-range.alw ├── directives-lexical-error.alw ├── directives-source-position.alw ├── directives.alw ├── end ├── exceptions-divzero-complex.alw ├── exceptions-divzero.alw ├── exceptions-establishment.alw ├── exceptions-intdivzero.alw ├── expressions-case-incompatible.alw ├── expressions-case-too-high.alw ├── expressions-case-too-low.alw ├── expressions-case.alw ├── expressions-if-then-incompatible.alw ├── expressions-if-then-needs-else.alw ├── expressions-if-then-string-expressions.alw ├── expressions-if-then.alw ├── lexing-unclosed-comment.alw ├── lexing-unclosed-string.alw ├── long-comment-error-1.alw ├── long-comment-error-2.alw ├── long-comment-error-3.alw ├── long-comment.alw ├── operators-bits.alw ├── operators-integer-divide-by-0.alw ├── operators-integer-division.alw ├── operators-integer.alw ├── operators-logical-comparison.alw ├── operators-logical.alw ├── operators-pwr.alw ├── operators-real-divide-by-0.alw ├── operators-string-substring-negative-index.alw ├── operators-string-substring-too-long.alw ├── operators-string-substring.alw ├── operators-string.alw ├── operators-triplet-rule.alw ├── parser-declarations.dat ├── parser-expressions.dat ├── parser-lexing-operators.dat ├── parser-lexing.dat ├── parser-statements.dat ├── procedure-external-invalid.alw ├── procedure-external.alw ├── procedure-misnamed-block.alw ├── procedure-parameters-equality-2.alw ├── procedure-parameters-equality.alw ├── procedure-parameters-general.alw ├── procedure-parameters-hendrik.alw ├── procedure-parameters-incompatable.alw ├── procedure-parameters-manorboy.alw ├── procedure-parameters-name-manorboy.alw ├── procedure-parameters-name-name.alw ├── procedure-parameters-name.alw ├── procedure-parameters-procedure-incompatible.alw ├── procedure-parameters-procedure.alw ├── procedure-parameters-result-incompatible-2.alw ├── procedure-parameters-result-incompatible.alw ├── procedure-parameters.alw ├── procedure-result.alw ├── procedure-value-result.alw ├── procedure-value.alw ├── procedure-visibility.alw ├── program-exit-code-int.alw ├── program-exit-code-none.alw ├── program-exit-code-statement.alw ├── program-exit-code-wrong-type.alw ├── prototypes.alw ├── records-0.alw ├── records-allocation-expressions.alw ├── records-class-set-compatibility-error.alw ├── records-class-set-compatibility.alw ├── records-field-of-null-run-time.alw ├── records-fields-do-not-work-on-null.alw ├── records-fields-wrong-class-compile-time.alw ├── records-fields-wrong-class-run-time.alw ├── records-is-never-of-class.alw ├── records-is-null.alw ├── records-is.alw ├── records-parameters.alw ├── records-record-designator-class.alw ├── records-record-designators.alw ├── records-string-fields.alw ├── records-uninitialized-element.alw ├── records-uninitialized-field.alw ├── records-uninitialized-variable.alw ├── records-visibility.alw ├── records.alw ├── roman4.alw ├── standard-analysis-exp.alw ├── standard-analysis.alw ├── standard-predefined-variables.alw ├── standard-read-complex.alw ├── standard-read-exception-null.alw ├── standard-read-exception.alw ├── standard-read-integer.alw ├── standard-read-iocontrol.alw ├── standard-read-real.alw ├── standard-read-strings.alw ├── standard-read.alw ├── standard-readcard-eof.alw ├── standard-readcard-exception-eof.alw ├── standard-readcard-exception-null.alw ├── standard-readcard-exception.alw ├── standard-readcard.alw ├── standard-transfer-base.alw ├── standard-transfer-roundtoreal.alw ├── standard-transfer.alw ├── standard-write-eject-last-page.alw ├── standard-write-example.alw ├── standard-write-i_w.alw ├── standard-write-line-wrap.alw ├── standard-write-page-breaks-off.alw ├── standard-write-page-breaks.alw ├── standard-write-reference.alw ├── standard-writecard-error.alw ├── standard-writecard.alw ├── statements-assignment.alw ├── statements-block-empty.alw ├── statements-block-out-of-scope.alw ├── statements-block-overshadowed-2.alw ├── statements-block-overshadowed-3.alw ├── statements-block-overshadowed.alw ├── statements-block.alw ├── statements-case-too-high.alw ├── statements-case-too-low.alw ├── statements-case.alw ├── statements-for-control-variable-scope.alw ├── statements-for-list.alw ├── statements-for-step-0.alw ├── statements-for-step.alw ├── statements-for.alw ├── statements-goto-scope.alw ├── statements-goto-wrong-direction.alw ├── statements-goto.alw ├── statements-if.alw ├── statements-while-body-is-statement.alw ├── statements-while-is-statement.alw ├── statements-while.alw ├── string-case.alw ├── string-character-order.alw ├── string-comparisions.alw ├── string-constants-non-printing.alw ├── string-constants.alw ├── string-result-parameters.alw ├── string-substring-1.alw ├── string-substring-all-of-length-1.alw ├── string-substring-assignment-off-end.alw ├── string-substring-assignment-too-long.alw ├── string-substring-assignment.alw ├── string-substring-io.alw ├── string-substring-multiple-assignment.alw ├── string-substring-name-parameter.alw ├── string-substring-of-short-string.alw ├── string-too-long.alw ├── string-value-parameters.alw └── string.alw ├── Tools ├── Makefile ├── algolw.lang ├── algolw.ssh ├── awnest-test-file.alw ├── awnest.1 ├── awnest.mll └── expected.output ├── VERSION ├── algolw.pdf ├── algolw.tex ├── awe.1.md ├── awe.c ├── awe.h ├── awe.md ├── awe.mk ├── awe.mk.7.md ├── awe.ml ├── awearray.c ├── aweexcept.c ├── aweio.c ├── aweio.h ├── awestd.c ├── awestr.c ├── class.ml ├── class.mli ├── code.ml ├── code.mli ├── compiler.ml ├── dynArray.ml ├── dynArray.mli ├── email_address.png ├── github-markdown.css ├── htmltext.py ├── lexer.mll ├── location.ml ├── location.mli ├── man.py ├── markdown-to-html.py ├── options.ml ├── parser.mly ├── predeclared.ml ├── scanner.py ├── scope.ml ├── scope.mli ├── table.ml ├── table.mli ├── testparsing.mll ├── testprograms.ml ├── tree.ml ├── tree.mli ├── type.ml └── type.mli /.gitignore: -------------------------------------------------------------------------------- 1 | /awe.1 2 | /awe.mk.7 3 | *.o 4 | *.cmi 5 | *.cmo 6 | *.awe.c 7 | *.awe.h 8 | test.output 9 | actual*.output 10 | *.zip 11 | .hg 12 | .hgignore 13 | ._d 14 | ._bcdi 15 | .vscode 16 | .idea 17 | /scratch 18 | /awe.1.html 19 | /awe.html 20 | /awe.mk.7.html 21 | /awe 22 | /libawe.a 23 | /lexer.ml 24 | /parser.ml 25 | /parser.mli 26 | /scanner.dot 27 | /scanner.inc 28 | /testparsing 29 | /testparsing.ml 30 | /Tools/awnest.ml 31 | /Tools/awnest 32 | /Tests/Argv-Multisource/program 33 | /Tests/Argv/program 34 | /Tests/ExternalRecords/program 35 | /Tests/OldParse/parse 36 | /Tests/OldParse/parse.alw 37 | /Tests/Separate/program 38 | /Tests/Separate/program.c 39 | /Tests/Separate/separate.c 40 | /Tests/SeparateC/program 41 | /Tests/Stderr-redirection/program 42 | /Tests/Strings-as-bytes/program 43 | /Tests/Tracing/program 44 | /INSTALL.html 45 | /Examples/List/list 46 | /Examples/Macro/macro 47 | /Examples/Roman/roman 48 | /Examples/test-cords/test-cords 49 | /Examples/Logic/logicpas 50 | /Examples/Logic/logic 51 | /Examples/Logic/Logic.tar.gz 52 | testme* 53 | a.out 54 | x.c 55 | -------------------------------------------------------------------------------- /COPYRIGHTS: -------------------------------------------------------------------------------- 1 | ────────────────────────────────────────────────────────────────────── 2 | AWE COPYRIGHTS 3 | ────────────────────────────────────────────────────────────────────── 4 | 5 | The Awe test suite contains 'parser.alw', a parser generator by 6 | Hendrik Boom, it remains copyright to its author, but is used here 7 | with permission. 8 | 9 | An Awe example program uses Hans Boehm's Cords library, it is 10 | copyright to Xerox Corporation, under an open source licence. 11 | 12 | The example program "macro" is derived from the source code 13 | provided for the book Software Tools in Pascal by Brian W. Kernighan 14 | and P. J. Plauger, Copyright (C) 1981 by Bell Laboratories, Inc. 15 | and Whitesmiths Ltd. 16 | 17 | The Awe makefile uses OCamlMakefile, copyright Markus Mottl, 18 | under the GPL licence. 19 | 20 | Otherwise, Copyright 2012, 2020 by Glyn Webster. 21 | 22 | Awe is free software: you can redistribute it and/or modify it 23 | under the terms of the GNU General Public and Lesser GNU General 24 | Public licenses as published by the Free Software Foundation, either 25 | version 3 of the License, or (at your option) any later version. 26 | 27 | Awe is distributed in the hope that it will be useful, 28 | but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 | GNU General Public License for more details. 31 | 32 | You should have received a copy of the GNU General Public 33 | License along with Awe. If not, see . 34 | -------------------------------------------------------------------------------- /Examples/List/BEGIN: -------------------------------------------------------------------------------- 1 | comment 2 | A "begin" to let the contents of a following 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -o prog.c ; 8 | BEGIN 9 | -------------------------------------------------------------------------------- /Examples/List/END: -------------------------------------------------------------------------------- 1 | comment 2 | An "end" to let the contents of a preceeding 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -c prog.c 8 | 9 | (Note that prog.alw cannot end on a fullstop.) ; 10 | END. 11 | -------------------------------------------------------------------------------- /Examples/List/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = list 2 | ALGOLW_SOURCES = BEGIN argv.alw io.alw list.alw END 3 | C_SOURCES = argv-library.c io-library.c 4 | C_INCLUDES = 5 | EXTRA_FILES = README test?.txt expected.output 6 | 7 | include awe.mk 8 | 9 | test : clean build 10 | ./list test1.txt test2.txt test3.txt test4.txt > actual.output 11 | diff --strip-trailing-cr expected.output actual.output 12 | rm actual.output 13 | echo "Success!" 14 | -------------------------------------------------------------------------------- /Examples/List/README: -------------------------------------------------------------------------------- 1 | This program lists files to the standard output with line numbers: 2 | 3 | list [files]... 4 | 5 | It's nothing fancy. 6 | 7 | But the code demonstrates how to use multiple Algol W source files as 8 | a primitive module system, how to write and use external procedures in 9 | C, and shows you a general-purpose Makefile for Algol W programs, 10 | which you can reuse. 11 | 12 | --Glyn -------------------------------------------------------------------------------- /Examples/List/argv-library.c: -------------------------------------------------------------------------------- 1 | /* argc.c -- external procedures to let Algol W programs to access argc and argv. */ 2 | 3 | #include "awe.h" 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | #define STRING_LENGTH 100 /* This MUST match the string length in the Algol W declarations. */ 10 | 11 | 12 | /* Note: '_awe_argc' and '_awe_argc' are global copies of the 'main' function's arguments. */ 13 | 14 | 15 | int 16 | get_argc (void) 17 | { 18 | return _awe_argc; 19 | } 20 | 21 | 22 | int 23 | get_argv_length (int index) 24 | { 25 | assert(_awe_argv != NULL); 26 | if (index < 0 || index > _awe_argc) 27 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 28 | assert(_awe_argv[index] != NULL); 29 | return strlen(_awe_argv[index]); 30 | } 31 | 32 | 33 | _awe_str 34 | get_argv (int index) 35 | { 36 | int len; 37 | 38 | assert(_awe_argv != NULL); 39 | if (index < 0 || index > _awe_argc) 40 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 41 | assert(_awe_argv[index] != NULL); 42 | len = strlen(_awe_argv[index]); 43 | if (len > STRING_LENGTH) 44 | _awe_error(_awe_HERE, "strlen(argv[%i] == %i: greater than target string's length of %i", index, len, STRING_LENGTH); 45 | return _awe_str_cast(_awe_argv[index], len, STRING_LENGTH); 46 | } 47 | 48 | /* end */ 49 | -------------------------------------------------------------------------------- /Examples/List/argv.alw: -------------------------------------------------------------------------------- 1 | integer procedure argc; algol "get_argc"; 2 | string(100) procedure argv (integer value index); algol "get_argv"; 3 | integer procedure argv_length (integer value index); algol "get_argv_length"; 4 | -------------------------------------------------------------------------------- /Examples/List/expected.output: -------------------------------------------------------------------------------- 1 | test1.txt 2 | 0 |A rule appears in the makefile and says when and how to remake certain 3 | 1 |files, called the rule's targets (most often only one per rule). It 4 | 2 |lists the other files that are the dependencies of the target, and 5 | 3 |commands to use to create or update the target. 6 | test2.txt 7 | 0 |The order of rules is not significant, except for determining the 8 | 1 |default goal: the target for make to consider, if you do not otherwise 9 | 2 |specify one. The default goal is the target of the first rule in the 10 | 3 |first makefile. If the first rule has multiple targets, only the first 11 | 4 |target is taken as the default. There are two exceptions: a target 12 | 5 |starting with a period is not a default unless it contains one or more 13 | 6 |slashes, `/', as well; and, a target that defines a pattern rule has 14 | 7 |no effect on the default goal. (See section Defining and Redefining 15 | 8 |Pattern Rules.) 16 | test3.txt 17 | 0 |Therefore, we usually write the makefile so that the first rule is the 18 | 1 |one for compiling the entire program or all the programs described by 19 | 2 |the makefile (often with a target called `all'). See section Arguments 20 | 3 |to Specify the Goals. 21 | Cannot open test4.txt 22 | -------------------------------------------------------------------------------- /Examples/List/io-library.c: -------------------------------------------------------------------------------- 1 | /* io.c --very simple I/O library for Algol W programs */ 2 | 3 | /* This provides the functions for the external procdure declarations in io.alw. */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "awe.h" 11 | 12 | 13 | #define LINE_LENGTH 256 /* This MUST match the result string lengths in io.alw. */ 14 | #define PATH_LENGTH 256 /* This MUST match the path string lengths in io.alw. */ 15 | 16 | 17 | void * 18 | algolw_open (_awe_str path, _awe_str mode) 19 | { 20 | FILE *f; 21 | 22 | char c_path [PATH_LENGTH + 1]; 23 | char c_mode [3]; 24 | 25 | _awe_str_unpadded_copy(c_path, path, PATH_LENGTH); 26 | _awe_str_unpadded_copy(c_mode, mode, 2); 27 | 28 | f = fopen(c_path, c_mode); 29 | if (f == NULL) 30 | /* We want to demonstrate returning a NULL pointer as a reference here, so: */ 31 | return NULL; 32 | /* _awe_error(_awe_HERE, "algolw_open: '%s': %s", c_path, strerror(errno)); */ 33 | else 34 | return (void*)f; 35 | } 36 | 37 | 38 | void 39 | algolw_readline (void *f, _awe_str line, int *success) 40 | { 41 | char *s; 42 | size_t size; 43 | ssize_t len; 44 | 45 | size = LINE_LENGTH + 2; /* allow for "\n\0" at end of line */ 46 | s = (char *)malloc(size); 47 | assert(s); 48 | 49 | len = getline(&s, &size, (FILE*)f); /* Note: this a GNU C function. */ 50 | if (ferror((FILE*)f)) 51 | _awe_error(_awe_HERE, "algolw_readline: %s", strerror(errno)); 52 | assert (len >= -1); 53 | 54 | if (len == -1) { /* at EOF */ 55 | _awe_str_init(line, LINE_LENGTH); /* clear the string */ 56 | *success = 0; 57 | } 58 | else { 59 | if (len > 0 && s[len - 1] == '\n') --len; 60 | assert(len <= LINE_LENGTH); 61 | _awe_str_cpy(line, LINE_LENGTH, s, len); 62 | *success = 1; 63 | } 64 | free(s); 65 | }; 66 | 67 | 68 | void 69 | algolw_writeline (void * f, _awe_str line) 70 | { 71 | int i, len; 72 | 73 | assert(line); 74 | if (f == NULL) 75 | _awe_error(_awe_HERE, "algolw_writeline: File handle is NULL"); 76 | 77 | len = _awe_str_unpadded_length(line, LINE_LENGTH); 78 | for (i = 0; i < len; ++i) 79 | if (fputc(line[i], (FILE*)f) == EOF) 80 | _awe_error(_awe_HERE, "algolw_writeline: %s", strerror(errno)); 81 | if (fputc('\n', (FILE*)f) == EOF) 82 | _awe_error(_awe_HERE, "algolw_writeline: %s", strerror(errno)); 83 | } 84 | 85 | 86 | void 87 | algolw_close (void * f) 88 | { 89 | if (f == NULL) 90 | _awe_error(_awe_HERE, "algolw_close: File handle is NULL"); 91 | 92 | if (fclose((FILE*)f) != 0) 93 | _awe_error(_awe_HERE, "algolw_close: %s", strerror(errno)); 94 | } 95 | 96 | /* end */ 97 | -------------------------------------------------------------------------------- /Examples/List/io.alw: -------------------------------------------------------------------------------- 1 | % io.alw -- simple file I/O procedures % 2 | 3 | % (This file is a header for functions in io-library.c) % 4 | 5 | record file_handle (integer dummy); 6 | 7 | reference(file_handle) procedure open ( string(256) value path; 8 | string(2) value mode ); 9 | algol "algolw_open"; 10 | 11 | procedure readline ( reference(file_handle) value handle; 12 | string(256) result line; 13 | logical result success ); 14 | algol "algolw_readline"; 15 | 16 | procedure writeline ( reference(file_handle) value handle; 17 | string(256) value line ); 18 | algol "algolw_writeline"; 19 | 20 | procedure close (reference(file_handle) value handle); 21 | algol "algolw_close"; 22 | -------------------------------------------------------------------------------- /Examples/List/list.alw: -------------------------------------------------------------------------------- 1 | % list -- list the files named in this program's arguments % 2 | 3 | % This program requires io.alw amd argv.alw % 4 | 5 | begin 6 | iocontrol(11000); % ignore line widths % 7 | for i := 1 until argc - 1 do 8 | begin 9 | reference(file_handle) file; 10 | string(256) path; 11 | path := argv(i); 12 | file := open(path, "r"); 13 | if file = null then 14 | write("Cannot open ", path) 15 | else 16 | begin 17 | logical continue; 18 | string(256) line; 19 | integer linenum; 20 | linenum := 0; 21 | write(path); 22 | continue := true; 23 | while continue do 24 | begin 25 | readline(file, line, continue); 26 | if continue then 27 | write(i_w := 3, linenum, "|", line); 28 | linenum := linenum + 1 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /Examples/List/test1.txt: -------------------------------------------------------------------------------- 1 | A rule appears in the makefile and says when and how to remake certain 2 | files, called the rule's targets (most often only one per rule). It 3 | lists the other files that are the dependencies of the target, and 4 | commands to use to create or update the target. 5 | -------------------------------------------------------------------------------- /Examples/List/test2.txt: -------------------------------------------------------------------------------- 1 | The order of rules is not significant, except for determining the 2 | default goal: the target for make to consider, if you do not otherwise 3 | specify one. The default goal is the target of the first rule in the 4 | first makefile. If the first rule has multiple targets, only the first 5 | target is taken as the default. There are two exceptions: a target 6 | starting with a period is not a default unless it contains one or more 7 | slashes, `/', as well; and, a target that defines a pattern rule has 8 | no effect on the default goal. (See section Defining and Redefining 9 | Pattern Rules.) 10 | -------------------------------------------------------------------------------- /Examples/List/test3.txt: -------------------------------------------------------------------------------- 1 | Therefore, we usually write the makefile so that the first rule is the 2 | one for compiling the entire program or all the programs described by 3 | the makefile (often with a target called `all'). See section Arguments 4 | to Specify the Goals. 5 | -------------------------------------------------------------------------------- /Examples/Logic/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = logic 2 | ALGOLW_SOURCES = logic.alw 3 | C_SOURCES = argv.c 4 | EXTRA_FILES = expected.output README logic68.a68 logicpas.pas tests.sh 5 | 6 | test : clean logic 7 | bash tests.sh ./logic 8 | ./logic '~a \/ b, a -> b' > actual.output 9 | diff --strip-trailing-cr expected.output actual.output 10 | 11 | # an additional cleaning rule: 12 | clean :: 13 | rm -f actual.output logicpas logicpas.o logic68 logic68.c logic68.o 14 | 15 | # Bonus Algol 68 program! You need Algol 68RS to compile this. 16 | logic68: logic68.a68 17 | ca -u AAAAAAA logic68.a68 18 | bash tests.sh ./logic68 19 | ./logic68 '~a \/ b, a -> b' > actual.output 20 | diff --strip-trailing-cr expected.output actual.output 21 | 22 | # Bonus Pascal program! You need Free Pascal to compile this. 23 | logicpas: logicpas.pas 24 | fpc logicpas.pas 25 | bash tests.sh ./logicpas 26 | ./logicpas '~a \/ b, a -> b' > actual.output 27 | diff --strip-trailing-cr expected.output actual.output 28 | 29 | include ../../awe.mk 30 | -------------------------------------------------------------------------------- /Examples/Logic/README: -------------------------------------------------------------------------------- 1 | This is a toy intepreter for predicates (boolean expressions). 2 | It produces a table of all possible valuations. You can put in 3 | multiple predicates separated by commas, all of them will be 4 | shown in the right hand columns. 5 | 6 | a b | ~a \/ b, a -> b 7 | 0 0 | 1 1 8 | 0 1 | 1 1 9 | 1 0 | 0 0 10 | 1 1 | 1 1 11 | 12 | The program compiles an infix expression into RPN notion and 13 | interprets that on a stack machine. It is the toy program that I write 14 | when learning a new computer language. (I've included my Pascal and 15 | Algol 68 versions for comparison.) 16 | 17 | This program is also a demonstration of how to mix Algol W and C code. 18 | The Algol W program uses C functions to access the command line. 19 | 20 | Boolean expression syntax: 21 | 22 | predicates = equivalence ("," equivalence)* 23 | equivalence = implication ("<->" implication)* 24 | implication = exclusiveOR ("->" exclusiveOR)* 25 | exclusiveOR = disjunction ("@" disjunction)* 26 | disjunction = conjunction ("\/" conjunction)* 27 | conjunction = unary ("/\" unary)* 28 | unary = "0" | "1" | variable | "~" unary | "(" equivalence ")" 29 | 30 | Variables are any letter but "T" or "F". Spaces are ignored. 31 | 32 | Alternative symbols: 33 | 34 | "/\" --> "." 35 | "\/" --> "+" 36 | "<->" --> "=" 37 | "->" --> ">" 38 | "0" --> "F" 39 | "1" --> "T" 40 | -------------------------------------------------------------------------------- /Examples/Logic/argv.c: -------------------------------------------------------------------------------- 1 | /* argc.c -- external procedures to let Algol W programs to access argc and argv. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "logic.awe.h" /* Prototypes for external procedures. Generated by the Makefile. */ 9 | 10 | 11 | #define STRING_LENGTH 100 /* This MUST match the string length in the Algol W declarations. */ 12 | 13 | 14 | /* Note: '_awe_argc' and '_awe_argc' are global copies of the 'main' function's arguments. */ 15 | 16 | 17 | int 18 | get_argc (void) 19 | { 20 | return _awe_argc; 21 | } 22 | 23 | 24 | int 25 | get_argv_length (int index) 26 | { 27 | assert(_awe_argv != NULL); 28 | if (index < 0 || index > _awe_argc) 29 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 30 | assert(_awe_argv[index] != NULL); 31 | return strlen(_awe_argv[index]); 32 | } 33 | 34 | 35 | _awe_str 36 | get_argv (int index) 37 | { 38 | int len; 39 | 40 | assert(_awe_argv != NULL); 41 | if (index < 0 || index > _awe_argc) 42 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 43 | assert(_awe_argv[index] != NULL); 44 | len = strlen(_awe_argv[index]); 45 | if (len > STRING_LENGTH) 46 | _awe_error(_awe_HERE, "strlen(argv[%i] == %i: greater than target string's length of %i", index, len, STRING_LENGTH); 47 | return _awe_str_cast(_awe_argv[index], len, STRING_LENGTH); 48 | } 49 | 50 | 51 | void 52 | do_exit (int code) 53 | { 54 | _awe_finalize(_awe_HERE); 55 | exit(code); 56 | } 57 | 58 | 59 | /* end */ 60 | -------------------------------------------------------------------------------- /Examples/Logic/expected.output: -------------------------------------------------------------------------------- 1 | 2 | a b | ~a \/ b, a -> b 3 | 0 0 | 1 1 4 | 0 1 | 1 1 5 | 1 0 | 0 0 6 | 1 1 | 1 1 7 | 8 | -------------------------------------------------------------------------------- /Examples/Logic/tests.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | $1 -t 'A = A' 3 | $1 -t '~F = T' 4 | $1 -t '~T = F' 5 | $1 -t 'A \/ A = A' 6 | $1 -t 'A /\ A = A' 7 | $1 -t 'A /\ B = B /\ A' 8 | $1 -t 'A \/ B = B \/ A' 9 | $1 -t 'A /\ (B /\ C) = (A /\ B) /\ C' 10 | $1 -t 'A \/ (B \/ C) = (A \/ B) \/ C' 11 | $1 -t 'A /\ (B \/ C) = A /\ B \/ A /\ C' 12 | $1 -t 'A \/ (B /\ C) = (A \/ B) /\ (A \/ C)' 13 | $1 -t '~(A /\ B) = ~A \/ ~B' 14 | $1 -t '~(A \/ B) = ~A /\ ~B' 15 | $1 -t '~~A = A' 16 | $1 -t 'A /\ ~A = F' 17 | $1 -t 'A \/ ~A = T' 18 | $1 -t 'A /\ T = A' 19 | $1 -t 'A \/ F = A ' 20 | $1 -t 'A /\ F = F' 21 | $1 -t 'A \/ T = T' 22 | $1 -t 'A -> B = ~A \/ B' 23 | $1 -t '(A <-> B) = (A -> B) /\ (B -> A)' 24 | $1 -t 'A @ B = A /\ ~B \/ ~A /\ B' 25 | $1 -t 'A @ B = ~(A <-> B)' 26 | $1 -t '(A <-> (B <-> C)) = ((A <-> B) <-> C)' 27 | $1 -t 'T -> F = F' 28 | $1 -t 'A /\ B \/ C = (A /\ B) \/ C' 29 | $1 -t 'A \/ B /\ C = A \/ (B /\ C)' 30 | $1 -t 'A -> B -> C = (A -> B) -> C' 31 | $1 -t 'a.b = a /\ b' 32 | $1 -t 'a+b = a \/ b' 33 | $1 -t 'a>b = a -> b' 34 | $1 -t '(a=b) = (a <-> b)' 35 | $1 -t '0 = F' 36 | $1 -t '1 = T' 37 | -------------------------------------------------------------------------------- /Examples/Macro/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = macro 2 | ALGOLW_SOURCES = stip_begin.alw macro.alw stip_end.alw 3 | OTHER_FILES = test.input test.expected man.py macro.1.src 4 | 5 | BINDIR = /usr/local/bin 6 | MANDIR = /usr/local/share/man/man1 7 | 8 | .PHONY: build test install uninstall 9 | 10 | build: macro macro.1 test 11 | 12 | test: macro 13 | ./macro < test.input > test.output 14 | diff --strip-trailing-cr test.expected test.output 15 | 16 | install: 17 | install -m 755 -d $(BINDIR) $(MANDIR) 18 | install -m 755 -t $(BINDIR) macro 19 | install -m 644 -t $(MANDIR) macro.1 20 | 21 | uninstall: 22 | rm -f $(BINDIR)/macro 23 | rm -f $(MANDIR)/macro.1 24 | 25 | macro.1: 26 | python3 man.py macro.1.md macro.1 27 | 28 | clean:: 29 | rm -f test.output macro.1 30 | 31 | include awe.mk 32 | -------------------------------------------------------------------------------- /Examples/Macro/man.py: -------------------------------------------------------------------------------- 1 | #!/usr/env python3 2 | # man.py -- very simple markup preprocessor for man pages 3 | 4 | 5 | import re, time, sys 6 | 7 | def usage(): 8 | print('''usage: python3 man.py manpage.1.md manpage.1 MACRO="value"... 9 | 10 | This is a rough preprocessor to convert a subset of Markdown to man pages. 11 | A summary of the markup commands you can use in your src file: 12 | 13 | # PAGE TITLE / program name / program description 14 | ## heading 15 | *itatics* 16 | **bold** 17 | `monospace` 18 | {{MACRO}} 19 | ``` 20 | example code block 21 | ``` 22 | ''') 23 | sys.exit(1) 24 | 25 | if len(sys.argv) < 3: usage() 26 | 27 | macros = {'DATE': time.strftime("%Y-%m-%d"), 28 | 'YEAR': time.strftime("%Y")} 29 | for arg in sys.argv[3:]: 30 | m = re.match(r'([A-Z][A-Za-z0-9_]+)=(.*)', arg) 31 | if m: 32 | macros[m.group(1)] = m.group(2) 33 | else: 34 | usage() 35 | 36 | repls = [ 37 | (r'^###? +(.+?)$', r'.SH "\1"'), # ## heading 38 | (r'\*\*(.+?)\*\*', r'\\fB\1\\fR'), # **bold** 39 | (r'\*(.+?)\*', r'\\fI\1\\fR'), # *itatics* 40 | (r'`(.+?)`', r'\\fI\1\\fR'), # `monospace` 41 | (r'^(.+?) -$', r'\n.TP\n.B \1'), # definition - 42 | (r'^# +(.+?) */ *(.+?) */ *(.+?) *$', 43 | r'.TH \1 "{{DATE}}" "\2" "\3"'), # man page heading 44 | (r'{{(.+?)}}', 45 | lambda m: macros[m.group(1)]) ] # {{macro}} substitution 46 | 47 | 48 | with open(sys.argv[1], "r") as f: 49 | page = f.read() 50 | 51 | # split into text and code example sections, 52 | # odd-numbered sections will be code: 53 | sections = re.split('```[A-Za-z]*', page) 54 | 55 | with open(sys.argv[2], "w") as f: 56 | for i, s in enumerate(sections): 57 | if i % 2 == 0: # text section 58 | for pattern, repl in repls: 59 | s = re.sub(pattern, repl, s, flags=re.MULTILINE) 60 | else: # code section 61 | s = s.replace('\n', '\n ') 62 | s = '\n.nf\n' + s + '\n.fi\n' 63 | f.write(s) 64 | -------------------------------------------------------------------------------- /Examples/Macro/stip_end.alw: -------------------------------------------------------------------------------- 1 | % stip_end.alw -- 'Software Tools in Pascal' library for Algol W % 2 | 3 | % stip_begin.alw and stip_end.alw provide an outer block 4 | for programs writen in the 'Software Tools in Pascal' style, 5 | they define string and I/O functions very like those found in C. 6 | 7 | This file cleans up after the library and closes the block. % 8 | 9 | end; % program section % 10 | 11 | EXIT_POINT: 12 | 13 | stip_finialize; 14 | 15 | end; % library section % 16 | 17 | end. % global constants section % 18 | -------------------------------------------------------------------------------- /Examples/Macro/test.expected: -------------------------------------------------------------------------------- 1 | 2 | inc(abc) ---> inc(abc) 3 | define(inc,$1:=$1+1) inc(abc) ---> abc:=abc+1 4 | define(incr,$1 := $1 + $2) incr(x,3) ---> x := x + 3 5 | incr ---> := + 6 | incr() ---> := + 7 | incr(x) ---> x := x + 8 | incr(x,`6') ---> x := x + 6 9 | define(`dbl',(($1) * 2)) dbl(42) ---> ((42) * 2) 10 | incr(x,dbl(3)) ---> x := x + ((3) * 2) 11 | 12 | 13 | define(def,`define($1,$2)') 14 | def(a,xyz) a ---> xyz 15 | 16 | substr(123456789,1,1) ---> 1 17 | substr(123456789,9,1) ---> 9 18 | substr(123456789,9,2) ---> 9 19 | substr(123456789,3,5) ---> 34567 20 | substr(123456789,3,1) ---> 3 21 | substr(123456789,3,0) ---> 22 | substr(123456789,0,1) ---> 23 | substr(,1,1) ---> 24 | 25 | len(xyz) ---> 3 26 | len() ---> 0 27 | len ---> 0 28 | len(len(a)) ---> 1 29 | len(len(abcdeABCDE)) ---> 2 30 | 31 | ifelse(123,123,a,b) ---> a 32 | ifelse(123,,a,b) ---> b 33 | ifelse(123,456,a,b) ---> b 34 | ifelse(,,a,b) ---> a 35 | ifelse(test,,a,b) ---> b 36 | define(test,`') 37 | ifelse(test,,a,b) ---> a 38 | 39 | expr(100) ---> 100 40 | expr(20+30) ---> 50 41 | expr(2*5+10) ---> 20 42 | expr(10+2*5) ---> 20 43 | expr((10+2)*5) ---> 60 44 | expr(5*(10+2)) ---> 60 45 | expr(2*5+10/5) ---> 12 46 | expr(10+2*10/5) ---> 14 47 | expr((10+2)*(10/5)) ---> 24 48 | expr(x) ---> 0 49 | expr(1x) ---> 1 50 | expr(1+1x) ---> 2 51 | expr(x1) ---> 0 52 | expr(1&1) ---> 1 53 | expr(1&) ---> 1 54 | expr ---> 0 55 | 56 | changeq({}) {ab} `ab' ---> ab `ab' 57 | changeq() `ab' {ab} ---> ab {ab} 58 | -------------------------------------------------------------------------------- /Examples/Macro/test.input: -------------------------------------------------------------------------------- 1 | 2 | `inc(abc)' ---> inc(abc) 3 | `define(inc,$1:=$1+1) inc(abc)' ---> define(inc,$1:=$1+1) inc(abc) 4 | `define(incr,$1 := $1 + $2) incr(x,3)' ---> define(incr,$1 := $1 + $2) incr(x,3) 5 | `incr' ---> incr 6 | `incr()' ---> incr() 7 | `incr(x)' ---> incr(x) 8 | `incr(x,`6')' ---> incr(x,`6') 9 | `define(`dbl',(($1) * 2)) dbl(42)' ---> define(`dbl',(($1) * 2)) dbl(42) 10 | `incr(x,dbl(3))' ---> incr(x,dbl(3)) 11 | 12 | 13 | `define(def,`define($1,$2)')' define(def,`define($1,$2)') 14 | `def(a,xyz) a' ---> def(c,xyz) c 15 | 16 | `substr(123456789,1,1)' ---> substr(123456789,1,1) 17 | `substr(123456789,9,1)' ---> substr(123456789,9,1) 18 | `substr(123456789,9,2)' ---> substr(123456789,9,2) 19 | `substr(123456789,3,5)' ---> substr(123456789,3,5) 20 | `substr(123456789,3,1)' ---> substr(123456789,3,1) 21 | `substr(123456789,3,0)' ---> substr(123456789,3,0) 22 | `substr(123456789,0,1)' ---> substr(123456789,0,1) 23 | `substr(,1,1)' ---> substr(,1,1) 24 | 25 | `len(xyz)' ---> len(xyz) 26 | `len()' ---> len() 27 | `len' ---> len 28 | `len(len(a))' ---> len(len(a)) 29 | `len(len(abcdeABCDE))' ---> len(len(abcdeABCDEabcde)) 30 | 31 | `ifelse(123,123,a,b)' ---> ifelse(123,123,a,b) 32 | `ifelse(123,,a,b)' ---> ifelse(123,,a,b) 33 | `ifelse(123,456,a,b)' ---> ifelse(123,456,a,b) 34 | `ifelse(,,a,b)' ---> ifelse(,,a,b) 35 | `ifelse(test,,a,b)' ---> ifelse(test,,a,b) 36 | `define(test,`')' define(test,`') 37 | `ifelse(test,,a,b)' ---> ifelse(test,,a,b) 38 | 39 | `expr(100)' ---> expr(100) 40 | `expr(20+30)' ---> expr(20+30) 41 | `expr(2*5+10)' ---> expr(2*5+10) 42 | `expr(10+2*5)' ---> expr(10+2*5) 43 | `expr((10+2)*5)' ---> expr((10+2)*5) 44 | `expr(5*(10+2))' ---> expr(5*(10+2)) 45 | `expr(2*5+10/5)' ---> expr(2*5+10/5) 46 | `expr(10+2*10/5)' ---> expr(10+2*10/5) 47 | `expr((10+2)*(10/5))' ---> expr((10+2)*(10/5)) 48 | `expr(x)' ---> expr(x) 49 | `expr(1x)' ---> expr(1x) 50 | `expr(1+1x)' ---> expr(1+1x) 51 | `expr(x1)' ---> expr(x1) 52 | `expr(1&1)' ---> expr(1&1) 53 | `expr(1&)' ---> expr(1&) 54 | `expr' ---> expr 55 | 56 | `changeq({}) {ab} `ab'' ---> changeq({}) {ab} `ab' 57 | {changeq() `ab' {ab}} ---> changeq() `ab' {ab} 58 | -------------------------------------------------------------------------------- /Examples/Roman/BEGIN: -------------------------------------------------------------------------------- 1 | comment 2 | A "begin" to let the contents of a following 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -o prog.c ; 8 | BEGIN 9 | -------------------------------------------------------------------------------- /Examples/Roman/END: -------------------------------------------------------------------------------- 1 | comment 2 | An "end" to let the contents of a preceeding 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -c prog.c 8 | 9 | (Note that prog.alw cannot end on a fullstop.) ; 10 | END. 11 | -------------------------------------------------------------------------------- /Examples/Roman/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = roman 2 | ALGOLW_SOURCES = BEGIN argv.alw number.alw roman.alw END 3 | C_SOURCES = argv-library.c 4 | EXTRA_FILES = README expected.output 5 | 6 | test : build 7 | ./$(PROGRAM) 1 3999 849 ' + 83 ' 4890 -1 lolwut > actual.output 8 | diff --strip-trailing-cr expected.output actual.output 9 | rm actual.output 10 | 11 | clean:: 12 | rm -f actual.output 13 | 14 | include awe.mk 15 | -------------------------------------------------------------------------------- /Examples/Roman/argv-library.c: -------------------------------------------------------------------------------- 1 | /* argc.c -- external procedures to let Algol W programs to access argc and argv. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "roman.awe.h" 9 | 10 | #define STRING_LENGTH 100 /* This MUST match the string length in the Algol W declarations. */ 11 | 12 | 13 | /* Note: '_awe_argc' and '_awe_argc' are global copies of the 'main' function's arguments. */ 14 | 15 | 16 | int 17 | get_argc (void) 18 | { 19 | return _awe_argc; 20 | } 21 | 22 | 23 | int 24 | get_argv_length (int index) 25 | { 26 | assert(_awe_argv != NULL); 27 | if (index < 0 || index > _awe_argc) 28 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 29 | assert(_awe_argv[index] != NULL); 30 | return strlen(_awe_argv[index]); 31 | } 32 | 33 | 34 | _awe_str 35 | get_argv (int index) 36 | { 37 | int len; 38 | 39 | assert(_awe_argv != NULL); 40 | if (index < 0 || index > _awe_argc) 41 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 42 | assert(_awe_argv[index] != NULL); 43 | len = strlen(_awe_argv[index]); 44 | if (len > STRING_LENGTH) 45 | _awe_error(_awe_HERE, "strlen(argv[%i]) == %i: greater than the Algol W target string's length of %i", index, len, STRING_LENGTH); 46 | return _awe_str_cast(_awe_argv[index], len, STRING_LENGTH); 47 | } 48 | 49 | /* end */ 50 | -------------------------------------------------------------------------------- /Examples/Roman/argv.alw: -------------------------------------------------------------------------------- 1 | integer procedure argc; algol "get_argc"; 2 | string(100) procedure argv (integer value index); algol "get_argv"; 3 | integer procedure argv_length (integer value index); algol "get_argv_length"; 4 | -------------------------------------------------------------------------------- /Examples/Roman/expected.output: -------------------------------------------------------------------------------- 1 | I 2 | MMMCMXCIX 3 | DCCCXLIX 4 | LXXXIII 5 | The Romans didn't think that big. 6 | The Romans didn't think that small. 7 | Not an number. 8 | -------------------------------------------------------------------------------- /Examples/Roman/number.alw: -------------------------------------------------------------------------------- 1 | comment number.alw --- read a decimal number out of a string; 2 | 3 | procedure number (string(256) value s; integer result r; logical result okay); 4 | begin 5 | integer i; 6 | logical negative; 7 | logical procedure inside; i < 256; 8 | procedure spaces; while inside and s(i|1) = " " do i := i + 1; 9 | r := 0; 10 | i := 0; 11 | negative := false; 12 | okay := true; 13 | spaces; 14 | if inside and s(i|1) = "+" then 15 | i := i + 1 16 | else if inside and s(i|1) = "-" then 17 | begin negative := true; i := i + 1 end; 18 | spaces; 19 | if ~inside then okay := false; 20 | while okay and inside and s(i|1) >= "0" and s(i|1) <= "9" do 21 | begin 22 | integer r0; 23 | r0 := r; 24 | r := r * 10 + (decode(s(i|1)) - decode("0")); 25 | if r < r0 then okay := false; % overflow % 26 | i := i + 1; 27 | end; 28 | spaces; 29 | if inside then okay := false; % there is something after the spaces % 30 | if negative then r := -r 31 | end number; 32 | -------------------------------------------------------------------------------- /Examples/Roman/roman.alw: -------------------------------------------------------------------------------- 1 | comment roman.alw -- converts a numeric argument to roman; 2 | comment depends on number.alw, argv.alw; 3 | 4 | begin 5 | procedure roman (integer value number; string(15) result characters; integer result length); 6 | comment 7 | Returns the Roman number of an integer between 1 and 3999. 8 | "MMMDCCCLXXXVIII" (15 characters long) is the longest Roman number under 4000; 9 | begin 10 | integer place, power; 11 | 12 | procedure append (string(1) value c); 13 | begin characters(length|1) := c; length := length + 1 end; 14 | 15 | procedure i; append(case place of ("I","X","C","M")); 16 | procedure v; append(case place of ("V","L","D")); 17 | procedure x; append(case place of ("X","C","M")); 18 | 19 | assert (number >= 1) and (number < 4000); 20 | 21 | characters := " "; 22 | length := 0; 23 | power := 1000; 24 | place := 4; 25 | while place > 0 do 26 | begin 27 | case number div power + 1 of begin 28 | begin end; 29 | begin i end; 30 | begin i; i end; 31 | begin i; i; i end; 32 | begin i; v end; 33 | begin v end; 34 | begin v; i end; 35 | begin v; i; i end; 36 | begin v; i; i; i end; 37 | begin i; x end 38 | end; 39 | number := number rem power; 40 | power := power div 10; 41 | place := place - 1 42 | end 43 | end roman; 44 | 45 | for i := 1 until argc - 1 do 46 | begin 47 | integer n; 48 | logical success; 49 | number(argv(i), n, success); 50 | if not success then 51 | write("Not an number.") 52 | else if n < 1 then 53 | write("The Romans didn't think that small.") 54 | else if n > 3999 then 55 | write("The Romans didn't think that big.") 56 | else 57 | begin 58 | string(15) r; 59 | integer len; 60 | roman(n, r, len); 61 | write(r) 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /Examples/Wumpus/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = wumpus 2 | ALGOLW_SOURCES = wumpus.alw 3 | include awe.mk 4 | -------------------------------------------------------------------------------- /Examples/test-cords/BEGIN: -------------------------------------------------------------------------------- 1 | comment 2 | A "begin" to let the contents of a following 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -o prog.c ; 8 | BEGIN 9 | -------------------------------------------------------------------------------- /Examples/test-cords/END: -------------------------------------------------------------------------------- 1 | comment 2 | An "end" to let the contents of a preceeding 3 | sequence of source files exist in the same scope, 4 | which gives you a primitive module system. 5 | The idea is that you do something like this: 6 | 7 | awe BEGIN defs1.alw defs1.alw prog.alw END -c prog.c 8 | 9 | (Note that prog.alw cannot end on a fullstop.) ; 10 | END. 11 | -------------------------------------------------------------------------------- /Examples/test-cords/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = test-cords 2 | ALGOLW_SOURCES = BEGIN file.alw cords.alw try-it.alw END 3 | C_SOURCES = file.c cords.c cords/cordbscs.c cords/cordxtra.c 4 | C_INCLUDES = cords/cord.h cords/private/cord_pos.h 5 | EXTRA_FILES = cords/README.txt cords/*.[hc] 6 | 7 | CFLAGS = -Icord -I/usr/include/gc # For the cords/* code. 8 | LDLIBS = 9 | 10 | include awe.mk 11 | 12 | test : clean build 13 | ./$(PROGRAM) 14 | echo "Success!" 15 | -------------------------------------------------------------------------------- /Examples/test-cords/README: -------------------------------------------------------------------------------- 1 | This is an example of interfacing an Algol program to an existing C 2 | library: Hans Boehm's Cord data type. 3 | 4 | (I've made the lazy assumption that 'char', 'size_t' are represented 5 | by the same type as 'int'. It works on my 32-bit 686 system. I suspect 6 | the interface would have to be defined more strictly on others.) 7 | 8 | --Glyn 9 | -------------------------------------------------------------------------------- /Examples/test-cords/cords.alw: -------------------------------------------------------------------------------- 1 | % cord.alw -- cord string datatype % 2 | 3 | record CORD (integer cord_dummy); % NULL is the empty string % 4 | 5 | % transfer functions ------------------------------------------------------------------------------------ 6 | 7 | CORD_OF_TEXT(s) copies all of the string except the padding on the right. 8 | CORD_OF_STRING(s,i,n) copies n characters of string s starting at position i (where 0 < i+n <= 256) 9 | STRING_OF_CORD(x) copies cord into the string, (where 0 < cord_len(x) <= 256) 10 | 11 | To create a space: space := cord_of_string(" ",1,1) 12 | % 13 | 14 | reference(cord) procedure CORD_OF_TEXT (string(256) value S); algol "CORD_of_text"; 15 | reference(cord) procedure CORD_OF_STRING (string(256) value S; integer value I, N); algol "CORD_of_string"; 16 | reference(cord) procedure CORD_OF_CHARS (string(1) value C; integer value N); algol "CORD_of_chars"; 17 | string(256) procedure STRING_OF_CORD (reference(cord) value SRC); algol "string_of_CORD"; 18 | 19 | % string functions. ------------------------------------------------------------------------------------- % 20 | 21 | integer procedure CHR (string(1) value S); algol "chr"; % returns Latin-1 code of s % 22 | string(1) procedure ORD (integer value I); algol "ord"; % returns character with Latin-1 code of i % 23 | % Note: CODE and DECODE work on EBCDIC codes. % 24 | 25 | integer procedure TEXT_LEN (string(256) value S); algol "text_len"; % length of s, ignoring its padding % 26 | 27 | % Cord functions. --------------------------------------------------------------------------------------- % 28 | 29 | reference(cord) procedure CORD_CAT (reference(cord) value X, Y); algol "CORD_cat"; 30 | integer procedure CORD_LEN (reference(cord) value X); algol "CORD_len"; 31 | reference(cord) procedure CORD_SUBSTR (reference(cord) value X; integer value I, N); algol "CORD_substr"; 32 | integer procedure CORD_CMP (reference(cord) value X, Y); algol "CORD_cmp"; 33 | 34 | integer procedure CORD_CHR (reference(cord) value X; integer value I; string(1) value C); algol "CORD_chr"; 35 | integer procedure CORD_RCHR (reference(cord) value X; integer value I; string(1) value C); algol "CORD_rchr"; 36 | 37 | % (I've made the wild and wrong assumption that size_t int and char are interchangeable above.) % 38 | 39 | 40 | % I/O functions. ---------------------------------------------------------------------------------------- % 41 | 42 | integer procedure CORD_PUT (reference(cord) value X; reference(file) value F); algol "CORD_put"; 43 | reference(cord) procedure CORD_FROM_FILE (reference(file) value F); algol "CORD_from_file"; 44 | reference(cord) procedure CORD_FROM_FILE_EAGER (reference(file) value F); algol "CORD_from_file_eager"; 45 | 46 | % end % 47 | -------------------------------------------------------------------------------- /Examples/test-cords/cords.c: -------------------------------------------------------------------------------- 1 | /* cords_a.c -- adapts cords functions to the data types that Algol W uses */ 2 | 3 | /* Mostly size_t --> int */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include "cords/cord.h" 9 | 10 | #define AWE_STRING_LEN 256 11 | 12 | 13 | CORD 14 | CORD_of_text (_awe_str src) 15 | { 16 | int length; 17 | 18 | char s [AWE_STRING_LEN + 1]; 19 | 20 | _awe_str_unpadded_copy(s, src, AWE_STRING_LEN); 21 | 22 | length = strlen(s); 23 | return CORD_from_char_star(s); 24 | } 25 | 26 | 27 | CORD 28 | CORD_of_string (_awe_str src, int index, int length) 29 | { 30 | char s [AWE_STRING_LEN + 1]; 31 | if (index < 0 || length <= 0 || index + length > AWE_STRING_LEN) 32 | _awe_error( _awe_HERE, 33 | "Cannot take substring (%d|%d) of a STRING(%d).", 34 | index, length, AWE_STRING_LEN ); 35 | strncpy(s, src + index, length); 36 | s[length] ='\0'; 37 | return CORD_from_char_star(s); 38 | } 39 | 40 | 41 | CORD 42 | CORD_of_chars (unsigned char c, int n) 43 | { 44 | return CORD_chars(c, (size_t)n); 45 | } 46 | 47 | 48 | _awe_str 49 | string_of_CORD (CORD src) 50 | { 51 | int length; 52 | const char *s; 53 | 54 | length = CORD_len(src); 55 | if (length > AWE_STRING_LEN) 56 | _awe_error( _awe_HERE, 57 | "A CORD of length(%d) will not fit in a string(%d)", 58 | length, AWE_STRING_LEN ); 59 | 60 | s = CORD_to_const_char_star(src); 61 | return _awe_str_cast((_awe_str)s, length, AWE_STRING_LEN); 62 | } 63 | 64 | 65 | int 66 | ord (unsigned char c) 67 | { 68 | return c; 69 | } 70 | 71 | 72 | unsigned char 73 | chr (int i) 74 | { 75 | if (i < 0 || i > 255) _awe_error(_awe_HERE, "chr: %d is not a Latin-1 code", i); 76 | return i; 77 | } 78 | 79 | 80 | int 81 | text_len (_awe_str src) 82 | { 83 | return _awe_str_unpadded_length(src, AWE_STRING_LEN); 84 | } 85 | 86 | 87 | /* end */ 88 | -------------------------------------------------------------------------------- /Examples/test-cords/cords/README.txt: -------------------------------------------------------------------------------- 1 | These files are copied from: 2 | 3 | http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/bdwgc-7_2alpha5-20110107.tar.bz2 4 | 5 | They require the libgc-dev package to be intalled. 6 | 7 | To test: 8 | 9 | gcc -lgc -I. -I/usr/include/gc cord*.c && ./a.out 10 | -------------------------------------------------------------------------------- /Examples/test-cords/cords/ec.h: -------------------------------------------------------------------------------- 1 | # ifndef EC_H 2 | # define EC_H 3 | 4 | # ifndef CORD_H 5 | # include "cord.h" 6 | # endif 7 | 8 | /* Extensible cords are strings that may be destructively appended to. */ 9 | /* They allow fast construction of cords from characters that are */ 10 | /* being read from a stream. */ 11 | /* 12 | * A client might look like: 13 | * 14 | * { 15 | * CORD_ec x; 16 | * CORD result; 17 | * char c; 18 | * FILE *f; 19 | * 20 | * ... 21 | * CORD_ec_init(x); 22 | * while(...) { 23 | * c = getc(f); 24 | * ... 25 | * CORD_ec_append(x, c); 26 | * } 27 | * result = CORD_balance(CORD_ec_to_cord(x)); 28 | * 29 | * If a C string is desired as the final result, the call to CORD_balance 30 | * may be replaced by a call to CORD_to_char_star. 31 | */ 32 | 33 | # ifndef CORD_BUFSZ 34 | # define CORD_BUFSZ 128 35 | # endif 36 | 37 | typedef struct CORD_ec_struct { 38 | CORD ec_cord; 39 | char * ec_bufptr; 40 | char ec_buf[CORD_BUFSZ+1]; 41 | } CORD_ec[1]; 42 | 43 | /* This structure represents the concatenation of ec_cord with */ 44 | /* ec_buf[0 ... (ec_bufptr-ec_buf-1)] */ 45 | 46 | /* Flush the buffer part of the extended chord into ec_cord. */ 47 | /* Note that this is almost the only real function, and it is */ 48 | /* implemented in 6 lines in cordxtra.c */ 49 | void CORD_ec_flush_buf(CORD_ec x); 50 | 51 | /* Convert an extensible cord to a cord. */ 52 | # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord) 53 | 54 | /* Initialize an extensible cord. */ 55 | # define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf) 56 | 57 | /* Append a character to an extensible cord. */ 58 | # define CORD_ec_append(x, c) \ 59 | { \ 60 | if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \ 61 | CORD_ec_flush_buf(x); \ 62 | } \ 63 | *((x)[0].ec_bufptr)++ = (c); \ 64 | } 65 | 66 | /* Append a cord to an extensible cord. Structure remains shared with */ 67 | /* original. */ 68 | void CORD_ec_append_cord(CORD_ec x, CORD s); 69 | 70 | # endif /* EC_H */ 71 | -------------------------------------------------------------------------------- /Examples/test-cords/file.alw: -------------------------------------------------------------------------------- 1 | % io.alw -- simple file I/O procedures % 2 | 3 | record file (integer file_dummy); 4 | 5 | reference(file) procedure file_open (string(256) value path; string(2) value mode); algol "file_open"; 6 | 7 | procedure file_close (reference(file) value handle); algol "file_close"; 8 | -------------------------------------------------------------------------------- /Examples/test-cords/file.c: -------------------------------------------------------------------------------- 1 | /* io.c --very simple I/O library for Algol W programs */ 2 | 3 | /* This provides the functions for the external procdure declarations in io.alw. */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "awe.h" 11 | 12 | 13 | #define LINE_LENGTH 256 /* This MUST match the result string lengths in io.alw. */ 14 | #define PATH_LENGTH 256 /* This MUST match the path string lengths in file.alw. */ 15 | 16 | 17 | void * 18 | file_open (_awe_str path, _awe_str mode) 19 | { 20 | FILE *f; 21 | 22 | char c_path [PATH_LENGTH + 1]; 23 | char c_mode [3]; 24 | 25 | _awe_str_unpadded_copy(c_path, path, PATH_LENGTH); 26 | _awe_str_unpadded_copy(c_mode, mode, 2); 27 | 28 | f = fopen(c_path, c_mode); 29 | if (f == NULL) 30 | _awe_error(_awe_HERE, "file_open: '%s': %s", c_path, strerror(errno)); 31 | else 32 | return (void*)f; 33 | } 34 | 35 | 36 | void 37 | file_close (void * f) 38 | { 39 | if (f == NULL) 40 | _awe_error(_awe_HERE, "file_close: File handle is NULL"); 41 | 42 | if (fclose((FILE*)f) != 0) 43 | _awe_error(_awe_HERE, "file_close: %s", strerror(errno)); 44 | } 45 | 46 | /* end */ 47 | -------------------------------------------------------------------------------- /Examples/test-cords/try-it.alw: -------------------------------------------------------------------------------- 1 | comment cord.alw -- test Boehm's CORD library; 2 | 3 | begin 4 | reference(cord) a, b, c, space; 5 | integer i; 6 | 7 | space := cord_of_string(" ", 1, 1); 8 | 9 | a := cord_of_text("Now we see"); 10 | b := cord_of_text("if this works."); 11 | 12 | c := cord_cat(cord_cat(a, space), b); 13 | 14 | assert(string_of_cord(c) = "Now we see if this works."); 15 | assert(cord_cmp(c, cord_of_text("Now we see if this works.")) = 0); 16 | assert(cord_len(c) = text_len("Now we see if this works.")); 17 | 18 | i := cord_chr(c, 0, "e"); 19 | assert(i = 5) 20 | end 21 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # INSTALLING AWE 2 | 3 | 4 | ## Requirements 5 | 6 | A Unix-like operating system, Gnu C, Python 3, OCaml 4.08 or later, 7 | make, ar, markdown and the Boehm GC. 8 | 9 | Ubuntu or Debian Linux are ideal. Awe is reported to successfully compile 10 | and run the test and example programs on macOS. 11 | 12 | On Debian or Ubuntu install these packages: 13 | 14 | gcc ocaml-nox python3 python3-markdown binutils make libgc-dev 15 | 16 | 17 | ## Building Awe 18 | 19 | These are commands to compile and install Awe, to be run from within 20 | the `awe/` source code directory: 21 | 22 | `make` 23 | 24 | This builds Awe, then performs a large number of automated tests on it. 25 | 26 | `sudo make install` 27 | 28 | This installs Awe. 29 | 30 | The default destination is the standard "/usr/local" directories. 31 | Edit `Makefile` if you do not want this. 32 | 33 | `man awe` 34 | 35 | Learn how to run your new Algol W compiler. 36 | 37 | 38 | That's it, it should be that simple. 39 | 40 | Feel free to ask me any questions. 41 | My email address is in the distribution files. 42 | 43 | --- 44 | Glyn Webster, 2024 45 | -------------------------------------------------------------------------------- /Makefile.awe: -------------------------------------------------------------------------------- 1 | # Makefile.awe -- Make the 'awe' compiler executable. 2 | 3 | OCAMLMAKEFILE = OCamlMakefile 4 | 5 | RESULT = awe 6 | 7 | LIBS = unix 8 | 9 | ML = options.ml \ 10 | dynArray.mli dynArray.ml \ 11 | location.mli location.ml \ 12 | table.mli table.ml \ 13 | class.mli class.ml \ 14 | type.mli type.ml \ 15 | scope.mli scope.ml \ 16 | tree.mli tree.ml \ 17 | code.mli code.ml \ 18 | predeclared.ml \ 19 | compiler.ml 20 | 21 | SOURCES = $(ML) parser.mly lexer.mll awe.ml 22 | 23 | DEP_MODULES = $(ML) parser.mli parser.ml lexer.ml awe.ml 24 | 25 | include $(OCAMLMAKEFILE) 26 | -------------------------------------------------------------------------------- /Makefile.testparsing: -------------------------------------------------------------------------------- 1 | # Makefile.testP -- make for the lexer/parser tester 2 | 3 | OCAMLMAKEFILE = OCamlMakefile 4 | 5 | RESULT = testparsing 6 | 7 | SOURCES = dynArray.mli dynArray.ml \ 8 | location.mli location.ml \ 9 | table.mli table.ml \ 10 | tree.ml \ 11 | parser.mly \ 12 | lexer.mll \ 13 | testparsing.mll 14 | 15 | include $(OCAMLMAKEFILE) 16 | 17 | #end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Awe 2 | ALGOL W is a successor to Algol 60 closely based on A Contribution to the Development of ALGOL by Niklaus Wirth and C. A. R. Hoare. It includes dynamically allocated records, string handling, complex numbers and a standard I/O system. 3 | 4 | Awe is a new compiler for the ALGOL W language. It is a complete implementation of the language described in the [ALGOL W Language Description, June 1972](algolw.pdf). Awe should be able to compile code intended for the OS/360 ALGOL W compilers with little or no modification. For details read the [Awe manual](awe.md), [awe](awe.1.md)(1) and [awe.mk](awe.mk.7.md)(7). 5 | 6 | The main requirements for compiling Awe are a Unix-like operating system, GCC, Python3, OCaml and Boehm GC. For details read [INSTALL](INSTALL.md) and awe(1). 7 | 8 | ## Thank You 9 | 10 | Thank you to: Hendrick Boom, Tony Marsland, Carey Bloodworth, John Boutland and Nicolas Brouard for a great deal of expert advice, encouragement and testing; and the authors of the *Algol W Language Description* for creating such an unambiguous work. 11 | 12 | ## By the Way 13 | 14 | If you have found this software useful or enlightening, please consider buying one of the late Frank Key's [books](https://www.lulu.com/search/?contributor=Frank+Key). Frank kept me sane, somehow. -------------------------------------------------------------------------------- /Tests/Argv-Multisource/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = begin argv-headers.alw program.alw end 3 | C_SOURCES = argv.c 4 | OTHER_FILES = expected.output 5 | 6 | test : clean build 7 | ./program Argument1 Arg2 'argument 3' > actual.output 8 | diff --strip-trailing-cr expected.output actual.output 9 | 10 | clean:: 11 | rm -f actual.output 12 | 13 | include awe.mk -------------------------------------------------------------------------------- /Tests/Argv-Multisource/argv-headers.alw: -------------------------------------------------------------------------------- 1 | integer procedure argc; algol "get_argc"; 2 | string(100) procedure argv (integer value index); algol "get_argv"; 3 | integer procedure argv_length (integer value index); algol "get_argv_length"; 4 | 5 | -------------------------------------------------------------------------------- /Tests/Argv-Multisource/argv.c: -------------------------------------------------------------------------------- 1 | /* argc.c -- external procedures to let Algol W programs to access argc and argv. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | #define STRING_LENGTH 100 /* This MUST match the string length in the Algol W declarations. */ 10 | 11 | 12 | /* Note: '_awe_argc' and '_awe_argc' are global copies of the 'main' function's arguments. */ 13 | 14 | 15 | int 16 | get_argc (void) 17 | { 18 | return _awe_argc; 19 | } 20 | 21 | 22 | int 23 | get_argv_length (int index) 24 | { 25 | assert(_awe_argv != NULL); 26 | if (index < 0 || index > _awe_argc) 27 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 28 | assert(_awe_argv[index] != NULL); 29 | return strlen(_awe_argv[index]); 30 | } 31 | 32 | 33 | _awe_str 34 | get_argv (int index) 35 | { 36 | int len; 37 | 38 | assert(_awe_argv != NULL); 39 | if (index < 0 || index > _awe_argc) 40 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 41 | assert(_awe_argv[index] != NULL); 42 | len = strlen(_awe_argv[index]); 43 | if (len > STRING_LENGTH) 44 | _awe_error(_awe_HERE, "strlen(argv[%i] == %i: greater than target string's length of %i", index, len, STRING_LENGTH); 45 | return _awe_str_cast(_awe_argv[index], len, STRING_LENGTH); 46 | } 47 | 48 | /* end */ 49 | -------------------------------------------------------------------------------- /Tests/Argv-Multisource/begin: -------------------------------------------------------------------------------- 1 | begin 2 | -------------------------------------------------------------------------------- /Tests/Argv-Multisource/end: -------------------------------------------------------------------------------- 1 | end. 2 | -------------------------------------------------------------------------------- /Tests/Argv-Multisource/expected.output: -------------------------------------------------------------------------------- 1 | 0 9 ./program 2 | 1 9 Argument1 3 | 2 4 Arg2 4 | 3 10 argument 3 5 | -------------------------------------------------------------------------------- /Tests/Argv-Multisource/program.alw: -------------------------------------------------------------------------------- 1 | for i := 0 until argc - 1 do 2 | write(i_w := 2, i, argv_length(i), argv(i)) 3 | -------------------------------------------------------------------------------- /Tests/Argv/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | C_SOURCES = argv.c 4 | OTHER_FILES = expected.output 5 | 6 | test : clean program 7 | ./program Argument1 Arg2 'argument 3' > actual.output 8 | diff --strip-trailing-cr expected.output actual.output 9 | 10 | # an additional cleaning rule: 11 | clean :: 12 | rm -f actual.output 13 | 14 | include awe.mk 15 | 16 | -------------------------------------------------------------------------------- /Tests/Argv/argv.c: -------------------------------------------------------------------------------- 1 | /* argc.c -- external procedures to let Algol W programs to access argc and argv. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "program.awe.h" /* Prototypes for external procedures. Generated by the Makefile. */ 9 | 10 | 11 | #define STRING_LENGTH 100 /* This MUST match the string length in the Algol W declarations. */ 12 | 13 | 14 | /* Note: '_awe_argc' and '_awe_argc' are global copies of the 'main' function's arguments. */ 15 | 16 | 17 | int 18 | get_argc (void) 19 | { 20 | return _awe_argc; 21 | } 22 | 23 | 24 | int 25 | get_argv_length (int index) 26 | { 27 | assert(_awe_argv != NULL); 28 | if (index < 0 || index > _awe_argc) 29 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 30 | assert(_awe_argv[index] != NULL); 31 | return strlen(_awe_argv[index]); 32 | } 33 | 34 | 35 | _awe_str 36 | get_argv (int index) 37 | { 38 | int len; 39 | 40 | assert(_awe_argv != NULL); 41 | if (index < 0 || index > _awe_argc) 42 | _awe_error(_awe_HERE, "attempted to access argv[%i], argc is %i\n", index, _awe_argc); 43 | assert(_awe_argv[index] != NULL); 44 | len = strlen(_awe_argv[index]); 45 | if (len > STRING_LENGTH) 46 | _awe_error(_awe_HERE, "strlen(argv[%i] == %i: greater than target string's length of %i", index, len, STRING_LENGTH); 47 | return _awe_str_cast(_awe_argv[index], len, STRING_LENGTH); 48 | } 49 | 50 | /* end */ 51 | -------------------------------------------------------------------------------- /Tests/Argv/expected.output: -------------------------------------------------------------------------------- 1 | 0 9 ./program 2 | 1 9 Argument1 3 | 2 4 Arg2 4 | 3 10 argument 3 5 | -------------------------------------------------------------------------------- /Tests/Argv/program.alw: -------------------------------------------------------------------------------- 1 | % Test argc/argv access. % 2 | begin 3 | integer procedure argc; algol "get_argc"; 4 | 5 | string(100) procedure argv (integer value index); algol "get_argv"; 6 | 7 | integer procedure argv_length (integer value index); algol "get_argv_length"; 8 | 9 | for i := 0 until argc - 1 do 10 | write(i_w := 2, i, argv_length(i), argv(i)) 11 | end. 12 | -------------------------------------------------------------------------------- /Tests/ExternalRecords/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | C_SOURCES = io-library.c 4 | OTHER_FILES = expected.output 5 | 6 | test : clean build 7 | ./program > actual.output 8 | diff --strip-trailing-cr expected.output actual.output 9 | 10 | clean:: 11 | rm -f actual.output 12 | 13 | include awe.mk 14 | -------------------------------------------------------------------------------- /Tests/ExternalRecords/expected.output: -------------------------------------------------------------------------------- 1 | 1 |Empty arrays 2 | 2 |============ 3 | 3 | 4 | 4 |Hendrik Boom wrote to me that the OS/360 ALGOLW compiler allowed 5 | 5 |"empty arrays" to be declared, with the semantics defined below, and 6 | 6 |that using them made some algorithms considerably clearer. Awe allows 7 | 7 |them also, for the sake of backward compatibility. 8 | 8 | 9 | 9 |**Definition** 10 | 10 | 11 | 11 |Replace the last sentence of 5.2.2. *Array Declarations, Semantics* with this: 12 | 12 | 13 | 13 | In order to be valid, for every bound pair, the value of the upper 14 | 14 | bound may be no lower than one less than the upper bound. If a valid 15 | 15 | array has any bound pair where the upper bound is one less than the 16 | 16 | lower bound then it is an empty array. 17 | 17 | 18 | 18 |Replace the second sentence of 6.1.2. *Variables, Semantics* with this: 19 | 19 | 20 | 20 | An array designator is invalid if its array identifier denotes an 21 | 21 | empty array (Cf. 5.2.2) or if any of its subscripts lie outside 22 | 22 | the declared bounds for that subscript's position. 23 | -------------------------------------------------------------------------------- /Tests/ExternalRecords/external.txt: -------------------------------------------------------------------------------- 1 | Empty arrays 2 | ============ 3 | 4 | Hendrik Boom wrote to me that the OS/360 ALGOLW compiler allowed 5 | "empty arrays" to be declared, with the semantics defined below, and 6 | that using them made some algorithms considerably clearer. Awe allows 7 | them also, for the sake of backward compatibility. 8 | 9 | **Definition** 10 | 11 | Replace the last sentence of 5.2.2. *Array Declarations, Semantics* with this: 12 | 13 | In order to be valid, for every bound pair, the value of the upper 14 | bound may be no lower than one less than the upper bound. If a valid 15 | array has any bound pair where the upper bound is one less than the 16 | lower bound then it is an empty array. 17 | 18 | Replace the second sentence of 6.1.2. *Variables, Semantics* with this: 19 | 20 | An array designator is invalid if its array identifier denotes an 21 | empty array (Cf. 5.2.2) or if any of its subscripts lie outside 22 | the declared bounds for that subscript's position. 23 | -------------------------------------------------------------------------------- /Tests/ExternalRecords/io-library.c: -------------------------------------------------------------------------------- 1 | /* io.c --very simple I/O library for Algol W programs, to demonstrate external records. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "awe.h" 9 | 10 | 11 | #define LINE_LENGTH 256 /* This MUST match the result string length in the Algol W declarations. */ 12 | #define PATH_LENGTH 256 /* This MUST match the path string length in the Algol W declarations. */ 13 | 14 | 15 | void * 16 | algolw_open (_awe_str path, _awe_str mode) 17 | { 18 | FILE *f; 19 | 20 | char c_path [PATH_LENGTH + 1]; 21 | char c_mode [3]; 22 | 23 | _awe_str_unpadded_copy(c_path, path, PATH_LENGTH); 24 | _awe_str_unpadded_copy(c_mode, mode, 2); 25 | 26 | f = fopen(c_path, c_mode); 27 | if (f == NULL) 28 | /* _awe_error(_awe_HERE, "algolw_open: '%s': %s", c_path, strerror(errno)); */ 29 | /* We want to demonstrate returning a NULL pointer as a reference here, so: */ 30 | return NULL; 31 | else 32 | return (void*)f; 33 | } 34 | 35 | 36 | void 37 | algolw_readline (void *f, _awe_str line, int *success) 38 | { 39 | char *s; 40 | size_t size; 41 | int len; 42 | 43 | size = LINE_LENGTH + 2; /* allow for "\n\0" at end of line */ 44 | s = (char *)malloc(size); 45 | assert(s); 46 | 47 | len = getline(&s, &size, (FILE*)f); /* Note: this a GNU C function. */ 48 | if (ferror((FILE*)f)) 49 | _awe_error(_awe_HERE, "algolw_readline: %s", strerror(errno)); 50 | assert (len >= -1); 51 | 52 | if (len == -1) { /* at EOF */ 53 | _awe_str_init(line, LINE_LENGTH); /* clear the string */ 54 | *success = 0; 55 | } 56 | else { 57 | if (len > 0 && s[len - 1] == '\n') --len; 58 | assert(len <= LINE_LENGTH); 59 | _awe_str_cpy(line, LINE_LENGTH, s, len); 60 | *success = 1; 61 | } 62 | free(s); 63 | }; 64 | 65 | 66 | void 67 | algolw_writeline (void * f, _awe_str line) 68 | { 69 | int i, len; 70 | 71 | assert(line); 72 | if (f == NULL) 73 | _awe_error(_awe_HERE, "algolw_writeline: File handle is NULL"); 74 | 75 | len = _awe_str_unpadded_length(line, LINE_LENGTH); 76 | for (i = 0; i < len; ++i) 77 | if (fputc(line[i], (FILE*)f) == EOF) 78 | _awe_error(_awe_HERE, "algolw_writeline: %s", strerror(errno)); 79 | if (fputc('\n', (FILE*)f) == EOF) 80 | _awe_error(_awe_HERE, "algolw_writeline: %s", strerror(errno)); 81 | } 82 | 83 | 84 | void 85 | algolw_close (void * f) 86 | { 87 | if (f == NULL) 88 | _awe_error(_awe_HERE, "algolw_close: File handle is NULL"); 89 | 90 | if (fclose((FILE*)f) != 0) 91 | _awe_error(_awe_HERE, "algolw_close: %s", strerror(errno)); 92 | } 93 | 94 | /* end */ 95 | -------------------------------------------------------------------------------- /Tests/ExternalRecords/program.alw: -------------------------------------------------------------------------------- 1 | BEGIN 2 | RECORD file (INTEGER dummy); 3 | 4 | REFERENCE(file) PROCEDURE open ( STRING(256) VALUE path; STRING(2) VALUE mode ); 5 | ALGOL "algolw_open"; 6 | 7 | PROCEDURE readline ( REFERENCE(file) VALUE handle; 8 | STRING(256) RESULT line; LOGICAL RESULT success ); 9 | ALGOL "algolw_readline"; 10 | 11 | PROCEDURE writeline ( REFERENCE(file) VALUE handle; STRING(256) VALUE line ); 12 | ALGOL "algolw_writeline"; 13 | 14 | PROCEDURE close ( REFERENCE(file) VALUE handle ); 15 | ALGOL "algolw_close"; 16 | 17 | STRING(256) path; 18 | REFERENCE(file) f; 19 | STRING(256) s; 20 | LOGICAL continue; 21 | INTEGER n; 22 | 23 | iocontrol(11000); % 1000-column pages (no enforced linebreaks) % 24 | path := "external.txt"; 25 | f := open(path, "r"); 26 | IF f = NULL THEN 27 | write("could not open ", path) 28 | ELSE 29 | BEGIN 30 | n := 1; 31 | continue := TRUE; 32 | WHILE continue DO 33 | BEGIN 34 | readline(f, s, continue); 35 | IF continue THEN 36 | write(i_w := 3, n, "|", s); 37 | n := n + 1; 38 | END; 39 | close(f); 40 | END 41 | END. 42 | -------------------------------------------------------------------------------- /Tests/InitFlag/withinit.alw: -------------------------------------------------------------------------------- 1 | comment Tests that initializations 2 | begin 3 | integer i, j; 4 | real r; 5 | logical l; 6 | bits b; 7 | string(1) c; 8 | string(4) s; 9 | 10 | record rec (integer field_i; real field_i; string(4) field_i); 11 | reference(rec) ref_rec; 12 | record ext; 13 | reference(ext) ref_ext; 14 | 15 | integer array (1::10) a; 16 | integer array (1::10, 1::10) a2; 17 | string(4) array (1::10) sa; 18 | 19 | procedure p (integer result x); assert(x = 0); 20 | 21 | assert(i = 0); 22 | assert(j = 0); 23 | assert(r = 0.0); 24 | assert(b = #0); 25 | assert(c = " "); 26 | assert(s = " "); 27 | 28 | assert(ref_rec = null); 29 | ref_rec := rec; 30 | assert(field_i(rec) = 0); 31 | assert(field_r(rec) = 0.0); 32 | assert(field_s(rec) = " "); 33 | 34 | assert(ext_ref = null); 35 | 36 | for i := 1 until 10 do 37 | assert(a(i) = 0); 38 | 39 | for i := 1 until 10 do 40 | for j := 1 until 10 do 41 | assert(a(i,j) = 0); 42 | 43 | for i := 1 until 10 do 44 | assert(s(i) = 0); 45 | 46 | i := 1; 47 | p(i) 48 | end. 49 | -------------------------------------------------------------------------------- /Tests/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make -C .. -k -f Makefile test 3 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/Makefile: -------------------------------------------------------------------------------- 1 | AWE=../../awe 2 | LIBAWE=../../libawe.a 3 | AWEH_PATH=../.. 4 | 5 | CFLAGS= -z execstack -I$(AWEH_PATH) 6 | LDLIBS=-lm -lgc $(LIBAWE) 7 | LDFLAGS += -z execstack 8 | 9 | .SUFFIXES: .alw 10 | .PHONY: test clean 11 | 12 | test : clean 13 | $(AWE) begin.alw argv-headers.alw program.alw end.alw 2> actual.output || diff --strip-trailing-cr expected.output actual.output 14 | echo "testprograms: argv test passed!" 15 | 16 | clean: 17 | rm -f *.c actual.output 18 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/argv-headers.alw: -------------------------------------------------------------------------------- 1 | integer procedure argc; algol "get_argc"; 2 | string(100) procedure argv (integer value index); algol "get_argv"; 3 | integer procedure argv_length (integer value index); algol "get_argv_length"; 4 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/begin.alw: -------------------------------------------------------------------------------- 1 | begin 2 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/end.alw: -------------------------------------------------------------------------------- 1 | end. 2 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/expected.output: -------------------------------------------------------------------------------- 1 | program.alw:2:48: Syntax error 2 | -------------------------------------------------------------------------------- /Tests/Multifile-Error/program.alw: -------------------------------------------------------------------------------- 1 | for i := 0 until argc - 1 do 2 | write(i_w := 2, i, argv_length(i), argv(i))syntax error 3 | 4 | -------------------------------------------------------------------------------- /Tests/OldParse/Makefile: -------------------------------------------------------------------------------- 1 | # OldParse test one of Hendrik Boom's 1970's source files. 2 | 3 | PROGRAM = parse 4 | ALGOLW_SOURCES = parse.alw 5 | OTHER_FILES = original-parse.alw expected.output 6 | 7 | test: clean parse 8 | ./parse < GRAMMAR > actual.output 9 | diff --strip-trailing-cr expected.output actual.output 10 | echo "testprograms: run of PARSE passed!" 11 | 12 | parse.alw: original-parse.alw 13 | # The timing is different every run, so to compare the actual output 14 | # with our expected one, we cheap a little and remove the timing 15 | # statements from the program 16 | sed -e 's/WRITE("Time:.*;//g' < original-parse.alw > parse.alw 17 | 18 | clean :: 19 | rm -f parse.alw actual.output 20 | 21 | include awe.mk 22 | -------------------------------------------------------------------------------- /Tests/Separate/Makefile: -------------------------------------------------------------------------------- 1 | AWE = ../../awe 2 | 3 | CFLAGS = -z execstack -I../.. -L../.. 4 | LDLIBS = -lawe -lm -lgc 5 | LDFLAGS += -z execstack 6 | 7 | .PHONY: test clean 8 | 9 | test : clean program 10 | ./program > actual.output 11 | diff --strip-trailing-cr expected.output actual.output 12 | echo "testprograms: separate compilation test passed!" 13 | 14 | program : separate.c program.c 15 | 16 | program.c: program.alw 17 | $(AWE) program.alw -c program.c 18 | 19 | separate.c: separate.alw 20 | $(AWE) separate.alw -p separate.c 21 | 22 | clean:: 23 | rm -f program program.o program.c separate.o separate.c actual.output 24 | -------------------------------------------------------------------------------- /Tests/Separate/expected.output: -------------------------------------------------------------------------------- 1 | Here we go: 2 | separate says: 3 | Hi there! 4 | Done. 5 | -------------------------------------------------------------------------------- /Tests/Separate/program.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure separate(string(10) value message); 3 | algol "separate"; 4 | 5 | write("Here we go:"); 6 | separate("Hi there!"); 7 | write("Done."); 8 | end. 9 | -------------------------------------------------------------------------------- /Tests/Separate/separate.alw: -------------------------------------------------------------------------------- 1 | procedure separate (string(10) value message); 2 | begin 3 | write("separate says:"); 4 | write(message); 5 | end. 6 | -------------------------------------------------------------------------------- /Tests/SeparateC/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | C_SOURCES = cprocedure.c 4 | OTHER_FILES = expected.output 5 | 6 | test : clean program 7 | ./program > actual.output 8 | diff --strip-trailing-cr expected.output actual.output 9 | 10 | clean:: 11 | rm -f actual.output 12 | 13 | include awe.mk 14 | -------------------------------------------------------------------------------- /Tests/SeparateC/cprocedure.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "program.awe.h" 5 | 6 | void Test (int v, int *r, int *vr, int *(*n)(void), _awe_array_t *a) 7 | { 8 | #define N *n() /* Name parameter */ 9 | #define A(j) *_awe_array_SUB(_awe_HERE, int, a, (j)) /* array parameter */ 10 | 11 | int j; 12 | 13 | printf("v = %d\n", v); 14 | printf("vr = %d\n", *vr); 15 | printf("n = %d\n", N); 16 | for (j = 1; j <= 3; ++j) printf("a(%d) = %d\n", j, A(j)); 17 | 18 | v++; 19 | ++(*vr); 20 | ++N; /* increment Name parameter */ 21 | *r = 41; 22 | for (j = 1; j <= 3; ++j) ++A(j); 23 | 24 | printf("v = %d\n", v); 25 | printf("vr = %d\n", *vr); 26 | printf("n = %d\n", N); /* fetch Name parameter again */ 27 | for (j = 1; j <= 3; ++j) printf("a(%d) = %d\n", j, A(j)); 28 | 29 | #undef A 30 | #undef N 31 | } 32 | -------------------------------------------------------------------------------- /Tests/SeparateC/expected.output: -------------------------------------------------------------------------------- 1 | v = 1 2 | vr = 50 3 | n = 60 4 | a(1) = 10 5 | a(2) = 20 6 | a(3) = 30 7 | v = 2 8 | vr = 51 9 | n = 61 10 | a(1) = 11 11 | a(2) = 21 12 | a(3) = 31 13 | -------------------------------------------------------------------------------- /Tests/SeparateC/program.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array A(1::3); 3 | integer r, n, vr; 4 | 5 | procedure test_c_parameters ( integer value v; 6 | integer result r; 7 | integer value result vr; 8 | integer n; 9 | integer array a(*) ); algol "Test"; 10 | 11 | A(1) := 10; 12 | A(2) := 20; 13 | A(3) := 30; 14 | r := 40; 15 | vr := 50; 16 | n := 60; 17 | 18 | test_c_parameters(1, r, vr, n, A); 19 | 20 | assert A(1) = 11; 21 | assert A(2) = 21; 22 | assert A(3) = 31; 23 | assert r = 41; 24 | assert vr = 51; 25 | assert n = 61; 26 | end. 27 | -------------------------------------------------------------------------------- /Tests/Stderr-redirection/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | OTHER_FILES = expected-stdout.output expected-stderr.output 4 | 5 | test : clean program 6 | ./program > actual-stdout.output 2> actual-stderr.output 7 | diff --strip-trailing-cr expected-stderr.output actual-stderr.output 8 | diff --strip-trailing-cr expected-stdout.output actual-stdout.output 9 | 10 | # an additional cleaning rule: 11 | clean :: 12 | rm -f actual-stdout.output actual-stderr.output 13 | 14 | include awe.mk 15 | 16 | -------------------------------------------------------------------------------- /Tests/Stderr-redirection/expected-stderr.output: -------------------------------------------------------------------------------- 1 | Whoops, didn't expect this! ;-) 2 | -------------------------------------------------------------------------------- /Tests/Stderr-redirection/expected-stdout.output: -------------------------------------------------------------------------------- 1 | Some text, and some more text. 2 | -------------------------------------------------------------------------------- /Tests/Stderr-redirection/program.alw: -------------------------------------------------------------------------------- 1 | % Test stderr/stdout redirection. % 2 | begin 3 | write("Some text, "); 4 | 5 | iocontrol(50001); 6 | write("Whoops, didn't expect this! ;-)"); 7 | iocontrol(50000); 8 | 9 | writeon("and some more text."); 10 | end. 11 | -------------------------------------------------------------------------------- /Tests/Strings-as-bytes/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | C_SOURCES = byte-access.c 4 | 5 | # just run it, it's full of ASSERT statements 6 | test : clean build 7 | ./program 8 | 9 | include awe.mk 10 | -------------------------------------------------------------------------------- /Tests/Strings-as-bytes/byte-access.c: -------------------------------------------------------------------------------- 1 | int byte (unsigned char s) { return (int)s; } 2 | unsigned char debyte (int x) { return (unsigned char)( x % 256); } 3 | -------------------------------------------------------------------------------- /Tests/Strings-as-bytes/program.alw: -------------------------------------------------------------------------------- 1 | BEGIN 2 | INTEGER PROCEDURE CODE (STRING(1) VALUE S); ALGOL "byte"; 3 | 4 | STRING(1) PROCEDURE DECODE (INTEGER VALUE X); ALGOL "debyte"; 5 | 6 | STRING(13) S; 7 | 8 | S(0|1) := DECODE(123); comment ASCII codes ; 9 | S(1|1) := DECODE(72); 10 | S(2|1) := DECODE(111); 11 | S(3|1) := DECODE(119); 12 | S(4|1) := DECODE(39); 13 | S(5|1) := DECODE(115); 14 | S(6|1) := DECODE(32); 15 | S(7|1) := DECODE(116); 16 | S(8|1) := DECODE(104); 17 | S(9|1) := DECODE(105); 18 | S(10|1) := DECODE(115); 19 | S(11|1) := DECODE(63); 20 | S(12|1) := DECODE(125); 21 | ASSERT(S = "{How's this?}"); 22 | 23 | S := "{And this?}"; 24 | ASSERT(CODE(S(0|1)) = 123); 25 | ASSERT(CODE(S(1|1)) = 65); 26 | ASSERT(CODE(S(2|1)) = 110); 27 | ASSERT(CODE(S(3|1)) = 100); 28 | ASSERT(CODE(S(4|1)) = 32); 29 | ASSERT(CODE(S(5|1)) = 116); 30 | ASSERT(CODE(S(6|1)) = 104); 31 | ASSERT(CODE(S(7|1)) = 105); 32 | ASSERT(CODE(S(8|1)) = 115); 33 | ASSERT(CODE(S(9|1)) = 63); 34 | ASSERT(CODE(S(10|1)) = 125) 35 | END. 36 | -------------------------------------------------------------------------------- /Tests/Tracing/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = program 2 | ALGOLW_SOURCES = program.alw 3 | C_SOURCES = tracing.c 4 | OTHER_FILES = expected.output 5 | AWE_FLAGS = -t 6 | 7 | test : clean program 8 | ./program 2> actual.output 9 | diff --strip-trailing-cr expected.output actual.output 10 | 11 | clean :: 12 | rm -f actual.output 13 | 14 | include awe.mk 15 | -------------------------------------------------------------------------------- /Tests/Tracing/expected.output: -------------------------------------------------------------------------------- 1 | program.alw:15:5: --> a 2 | program.alw:2:5: a 3 | program.alw:15:5: <-- a 4 | program.alw:16:5: --> b 5 | program.alw:6:5: b 6 | program.alw:8:30: --> c 7 | program.alw:11:5: c 8 | program.alw:8:30: <-- c 9 | program.alw:8:30: --> c 10 | program.alw:11:5: c 11 | program.alw:8:30: <-- c 12 | program.alw:8:30: --> c 13 | program.alw:11:5: c 14 | program.alw:8:30: <-- c 15 | program.alw:16:5: <-- b 16 | -------------------------------------------------------------------------------- /Tests/Tracing/program.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure a; 3 | begin 4 | end; 5 | 6 | procedure b; 7 | begin 8 | for i := 1 until 3 do c 9 | end; 10 | 11 | procedure c; 12 | begin 13 | end; 14 | 15 | a; 16 | b 17 | end. 18 | -------------------------------------------------------------------------------- /Tests/Tracing/tracing.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int nesting = 0; 4 | 5 | void _awe_trace_procedure_called (_awe_loc call_loc, const char *procedure_name) 6 | { 7 | _awe_warning(call_loc, "%*s--> %s", nesting, "", procedure_name); 8 | nesting += 4; 9 | } 10 | 11 | void _awe_trace_procedure_entered (_awe_loc procedure_loc, const char *procedure_name) 12 | { 13 | _awe_warning(procedure_loc, "%*s%s", nesting, "", procedure_name); 14 | } 15 | 16 | void _awe_trace_procedure_exited (_awe_loc call_loc, const char *procedure_name) 17 | { 18 | nesting -= 4; 19 | _awe_warning(call_loc, "%*s<-- %s", nesting, "", procedure_name); 20 | } 21 | -------------------------------------------------------------------------------- /Tests/array-bounds-empty-arrays-2.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a (1::2, 2::1); 3 | a(1,0) := 1; 4 | end. 5 | ----stderr 6 | Tests/array-bounds-empty-arrays-2.alw:3:4: array subscript error: subscript 2 = 0, outside the range (2::1) 7 | ----exitcode 8 | 1 9 | ----end 10 | -------------------------------------------------------------------------------- /Tests/array-bounds-empty-arrays.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a (0::-1); 3 | integer array b (-1::-2); 4 | integer array c (1::0); 5 | a(0) := 1; 6 | end. 7 | ----stderr 8 | Tests/array-bounds-empty-arrays.alw:5:4: array subscript error: subscript 1 = 0, outside the range (0::-1) 9 | ----exitcode 10 | 1 11 | ----end 12 | -------------------------------------------------------------------------------- /Tests/array-bounds-subscript-count.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a (1::2, 1::2); 3 | a(0) := 1; 4 | end. 5 | ----compile 6 | Tests/array-bounds-subscript-count.alw:3:4: Array 'a' requires 2 parameters 7 | ----end 8 | -------------------------------------------------------------------------------- /Tests/array-bounds.alw: -------------------------------------------------------------------------------- 1 | % Note that an array with bounds (1::0) is allowed here, 2 | it is an array with no elements that must not be accessed. 3 | This is an AWE extension to Algol W. 4 | % 5 | begin 6 | integer i; 7 | i := 5; 8 | while i >= -1 do comment Uh oh!; 9 | begin 10 | integer array a(1 :: i); comment Uh oh!; 11 | if i > 0 then 12 | begin 13 | a(1) := i; 14 | write(a(1)); 15 | end; 16 | i := i - 1 17 | end; 18 | end. 19 | ----stdout 20 | 5 21 | 4 22 | 3 23 | 2 24 | 1 25 | ----stderr 26 | Tests/array-bounds.alw:10:13: array dimension error: dimension 1 is (1::-1) 27 | ----exitcode 28 | 1 29 | ----end 30 | -------------------------------------------------------------------------------- /Tests/array-designator-as-parameter.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p(integer array A(*)); 3 | ; 4 | integer i; 5 | integer array B(1::3); 6 | i := 0; 7 | p(B(i+2)) 8 | end. 9 | ----compiler 10 | Tests/array-designator-as-parameter.alw:7:7: expected a 1 dimensional INTEGER ARRAY parameter here 11 | ----end 12 | -------------------------------------------------------------------------------- /Tests/array-parameters-type-cast.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p(real array A(*); integer value n); 3 | for i := 1 until n do 4 | writeon(A(i)); 5 | 6 | real array I(1::2); 7 | 8 | I(1) := 1; 9 | I(2) := 3; 10 | 11 | p(I, 2); 12 | end. 13 | ----stdout 14 | 1 3 15 | ----end 16 | -------------------------------------------------------------------------------- /Tests/array-parameters-type-error.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p(integer array A(*); integer value n); 3 | for i := 1 until n do 4 | writeon(A(i)); 5 | 6 | logical array L(1::2); 7 | 8 | L(1) := true; 9 | L(2) := false; 10 | 11 | p(L, 2) 12 | end. 13 | ----compile 14 | Tests/array-parameters-type-error.alw:11:6: expected a 1 dimensional INTEGER ARRAY parameter here, this is a 1 dimensional LOGICAL ARRAY 15 | ----end 16 | -------------------------------------------------------------------------------- /Tests/array-parameters.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p(integer array A(*,*); integer value m, n); 3 | begin 4 | i_w := 2; 5 | for i := 1 until m do 6 | begin 7 | for j := 1 until n do 8 | writeon(A(i,j)); 9 | iocontrol(2) 10 | end 11 | end p; 12 | 13 | procedure q(integer array A(*); integer value n); 14 | begin 15 | i_w := 2; 16 | for i := 1 until n do 17 | writeon(A(i)); 18 | end; 19 | 20 | procedure r(integer array A(*,*); integer value m, n); 21 | begin 22 | i_w := 2; 23 | for i := 1 until m do 24 | begin 25 | q(A(i,*), n); 26 | iocontrol(2) 27 | end 28 | end; 29 | 30 | 31 | procedure break; begin write("*"); iocontrol(2) end; 32 | 33 | begin 34 | integer array A(1::3, 1::4); 35 | integer array B(1::4, 1::3); 36 | integer n; 37 | n := 1; 38 | for i := 1 until 3 do 39 | for j := 1 until 4 do 40 | begin 41 | A(i,j) := n; 42 | B(j,i) := n; 43 | n := n + 1 44 | end; 45 | 46 | p(A, 3, 4); break; 47 | p(A(*,*), 3, 4); break; 48 | p(B, 4, 3); break; 49 | q(A(1,*), 4); break; 50 | q(A(*,1), 3); break; 51 | r(B, 4, 3) 52 | end 53 | end. 54 | ----stdout 55 | 1 2 3 4 56 | 5 6 7 8 57 | 9 10 11 12 58 | * 59 | 1 2 3 4 60 | 5 6 7 8 61 | 9 10 11 12 62 | * 63 | 1 5 9 64 | 2 6 10 65 | 3 7 11 66 | 4 8 12 67 | * 68 | 1 2 3 4 69 | * 70 | 1 5 9 71 | * 72 | 1 5 9 73 | 2 6 10 74 | 3 7 11 75 | 4 8 12 76 | ----end 77 | -------------------------------------------------------------------------------- /Tests/array-range.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::5); 3 | 4 | for i := 1 until 5 do 5 | a(i) := i * 2; 6 | 7 | for i := 1 until 6 do comment Uh oh!; 8 | write(a(i)) 9 | end. 10 | ----stdout 11 | 2 12 | 4 13 | 6 14 | 8 15 | 10 16 | ----stderr 17 | Tests/array-range.alw:8:15: array subscript error: subscript 1 = 6, outside the range (1::5) 18 | ----exitcode 19 | 1 20 | ----end 21 | -------------------------------------------------------------------------------- /Tests/array-references-init.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record r (integer f); 3 | reference(r) array a (1 :: 5); 4 | write(a(1)) %not initialised% 5 | end. 6 | ----stdout 7 | UNINITIALIZED 8 | ----end 9 | -------------------------------------------------------------------------------- /Tests/array-strings.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) array a (1::6, 1::6); 3 | 4 | a(3,4) := "abcbe"; 5 | a(3,5) := "ABCBE"; 6 | 7 | assert a(3,4) = "abcbe"; 8 | assert a(3,5) = "ABCBE"; 9 | end. 10 | -------------------------------------------------------------------------------- /Tests/array.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::9, 3::4); 3 | comment do nothing; 4 | end. 5 | -------------------------------------------------------------------------------- /Tests/arrays-multidimensional-range.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::10, 1::10); 3 | 4 | for i := 1 until 10 do 5 | for j := 1 until 10 do 6 | a(i,j) := i * 10 + j; 7 | assert(a(1,1) = 11); 8 | assert(a(5,4) = 54); 9 | assert(a(6,3) = 63); 10 | assert(a(3,11) = 0); comment Uh oh; 11 | end. 12 | ----stderr 13 | Tests/arrays-multidimensional-range.alw:10:12: array subscript error: subscript 2 = 11, outside the range (1::10) 14 | ----exitcode 15 | 1 16 | ----end 17 | -------------------------------------------------------------------------------- /Tests/arrays-multidimensional.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::10, 1::10); 3 | integer array b(1::10, 1::10, 1::10); 4 | 5 | for i := 1 until 10 do 6 | for j := 1 until 10 do 7 | a(i,j) := i * 10 + j; 8 | assert(a(1,1) = 11); 9 | assert(a(5,4) = 54); 10 | assert(a(6,3) = 63); 11 | 12 | for i := 1 until 10 do 13 | for j := 1 until 10 do 14 | for k := 1 until 10 do 15 | b(i,j,k) := i * 100 + j * 10 + k; 16 | assert(b(1,1,1) = 111); 17 | assert(b(5,4,6) = 546); 18 | assert(b(6,3,9) = 639); 19 | end. 20 | -------------------------------------------------------------------------------- /Tests/begin: -------------------------------------------------------------------------------- 1 | begin 2 | -------------------------------------------------------------------------------- /Tests/constants-range-bits-too-big.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(#fffffffff); 3 | end. 4 | ----compiler 5 | Tests/constants-range-bits-too-big.alw:2:9: BITS constant #FFFFFFFFF will not fit in a 32 bit word 6 | ----end 7 | -------------------------------------------------------------------------------- /Tests/constants-range-integer-too-big.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(2147483648); 3 | end. 4 | ----compiler 5 | Tests/constants-range-integer-too-big.alw:2:9: integer 2147483648 will not fit in a 32 bit word 6 | ----end 7 | -------------------------------------------------------------------------------- /Tests/constants-range.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(0); 3 | write(-0); 4 | write(1); 5 | write(-1); 6 | write(2147483647); 7 | write(-2147483647); 8 | write(-2147483647 - 1); 9 | write(#0); 10 | write(#ffffffff); 11 | end. 12 | ----stdout 13 | 0 14 | 0 15 | 1 16 | -1 17 | 2147483647 18 | -2147483647 19 | -2147483648 20 | 0 21 | FFFFFFFF 22 | ----end 23 | -------------------------------------------------------------------------------- /Tests/directives-lexical-error.alw: -------------------------------------------------------------------------------- 1 | comment This compiler directive does not start in column 1; 2 | begin 3 | @I'm a bad directive 4 | end. 5 | ----compiler 6 | Tests/directives-lexical-error.alw:3:3: Misplaced directive "@I'm a bad directive" 7 | ----end -------------------------------------------------------------------------------- /Tests/directives-source-position.alw: -------------------------------------------------------------------------------- 1 | comment Awe will output a compiler note for each Name paramter, 2 | the linemarker directives should ensure that they are 3 | reported as coming from different files; 4 | begin 5 | procedure p (integer i); % Tests/directives-source-position.alw:5:18 % 6 | begin 7 | end; 8 | 9 | # 1 "here.alw" 10 | procedure q (integer i); % here.alw:1:18 % 11 | begin 12 | end; 13 | 14 | procedure r (integer i); % here.alw:5:18 % 15 | begin 16 | end; 17 | 18 | # 4 "there.alw" 19 | procedure s (integer i); % there.alw:4:18 % 20 | begin 21 | end; 22 | 23 | # 10 "here.alw" 1 24 | procedure t (integer i); % here.alw:10:18 % 25 | begin 26 | end; 27 | end. 28 | ----compiler 29 | Tests/directives-source-position.alw:5:18: Note, this is a call-by-name formal parameter. 30 | here.alw:1:18: Note, this is a call-by-name formal parameter. 31 | here.alw:5:18: Note, this is a call-by-name formal parameter. 32 | there.alw:4:18: Note, this is a call-by-name formal parameter. 33 | here.alw:10:18: Note, this is a call-by-name formal parameter. 34 | ----end 35 | -------------------------------------------------------------------------------- /Tests/directives.alw: -------------------------------------------------------------------------------- 1 | comment The compiler should ignore the "@" directive lines; 2 | begin 3 | @I'm not here 4 | string(1) c; 5 | @I'm not here 6 | c := "@"; 7 | comment @; c := "!"; 8 | assert c = "!" 9 | @I'm not here 10 | end. 11 | -------------------------------------------------------------------------------- /Tests/end: -------------------------------------------------------------------------------- 1 | end. 2 | -------------------------------------------------------------------------------- /Tests/exceptions-divzero-complex.alw: -------------------------------------------------------------------------------- 1 | begin 2 | complex x; 3 | 4 | assert ~xcpnoted(divzero); 5 | assert xcplimit(divzero) = 0; 6 | assert xcpaction(divzero) = 0; 7 | assert xcpmark(divzero); 8 | 9 | xcplimit(divzero) := 3; 10 | 11 | xcpaction(divzero) := 0; 12 | x := 10 / 0; 13 | assert(x = 10); 14 | 15 | xcpaction(divzero) := 1; 16 | x := 10 / 0; 17 | assert(x = maxreal); 18 | 19 | xcpaction(divzero) := 2; 20 | x := 10 / 0; 21 | assert(x = 0); 22 | 23 | divzero := null; comment Returns the divdend and ignores the error; 24 | x := 10 / 0; 25 | assert(x = 10); 26 | end. 27 | ----stderr 28 | Tests/exceptions-divzero-complex.alw:12:11: Floating-point division by zero. 29 | Tests/exceptions-divzero-complex.alw:16:11: Floating-point division by zero. 30 | Tests/exceptions-divzero-complex.alw:20:11: Floating-point division by zero. 31 | ----exitcode 32 | 0 33 | ----end 34 | -------------------------------------------------------------------------------- /Tests/exceptions-divzero.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real r; 3 | 4 | assert ~xcpnoted(divzero); 5 | assert xcplimit(divzero) = 0; 6 | assert xcpaction(divzero) = 0; 7 | assert xcpmark(divzero); 8 | 9 | xcplimit(divzero) := 3; 10 | 11 | xcpaction(divzero) := 0; 12 | r := 10 / 0; 13 | assert(r = 10); 14 | 15 | xcpaction(divzero) := 1; 16 | r := 10 / 0; 17 | assert(r = maxreal); 18 | 19 | xcpaction(divzero) := 2; 20 | r := 10 / 0; 21 | assert(r = 0); 22 | 23 | divzero := null; comment Returns the divdend and ignores the error; 24 | r := 10 / 0; 25 | assert(r = 10); 26 | end. 27 | ----stderr 28 | Tests/exceptions-divzero.alw:12:11: Floating-point division by zero. 29 | Tests/exceptions-divzero.alw:16:11: Floating-point division by zero. 30 | Tests/exceptions-divzero.alw:20:11: Floating-point division by zero. 31 | ----exitcode 32 | 0 33 | ----end 34 | -------------------------------------------------------------------------------- /Tests/exceptions-establishment.alw: -------------------------------------------------------------------------------- 1 | comment Can an Exceptional Condition record be set and read?; 2 | begin 3 | DIVZERO := EXCEPTION(false, 10, 1, true, "DIVISION BY ZERO"); 4 | 5 | assert DIVZERO is EXCEPTION; 6 | assert ~XCPNOTED(DIVZERO); 7 | assert XCPLIMIT(DIVZERO) = 10; 8 | assert XCPACTION(DIVZERO) = 1; 9 | assert XCPMARK(DIVZERO); 10 | assert XCPMSG(DIVZERO) = "DIVISION BY ZERO" 11 | end. 12 | -------------------------------------------------------------------------------- /Tests/exceptions-intdivzero.alw: -------------------------------------------------------------------------------- 1 | begin 2 | assert ~xcpnoted(intdivzero); 3 | assert xcplimit(intdivzero) = 0; 4 | assert xcpaction(intdivzero) = 0; 5 | assert xcpmark(intdivzero); 6 | assert xcpmsg(intdivzero) = "Integer division by zero."; 7 | 8 | intdivzero := exception(false, 4, 1, true, "Divide by zero."); 9 | 10 | assert ~xcpnoted(intdivzero); comment No exceptions seen yet; 11 | assert xcplimit(intdivzero) = 4; comment Only 5 exceptions are allowed to occur; 12 | assert xcpaction(intdivzero) = 1; comment Action to take (all are the same for intdivzero); 13 | assert xcpmark(intdivzero); comment Give warning messages on exceptions; 14 | assert xcpmsg(intdivzero) = "Divide by zero."; 15 | 16 | ASSERT 42 DIV 0 = 42; comment <--- line 12; 17 | 18 | assert xcpnoted(intdivzero); comment We've seen one!; 19 | assert xcplimit(intdivzero) = 3; comment 4 to go...; 20 | 21 | xcpnoted(intdivzero) := false; comment Will this become true again?; 22 | xcpmark(intdivzero) := false; comment No warning for the next one; 23 | ASSERT 42 DIV 0 = 42; 24 | 25 | assert xcpnoted(intdivzero); comment It did become true!; 26 | assert xcplimit(intdivzero) = 2; 27 | 28 | xcpmsg(intdivzero) := "DIVIDE BY ZERO!"; comment A new warning message this time; 29 | xcpmark(intdivzero) := true; 30 | ASSERT 42 DIV 0 = 42; comment <--- line 26; 31 | 32 | assert xcplimit(intdivzero) = 1; comment Same message again; 33 | 34 | ASSERT 42 DIV 0 = 42; comment <--- line 30; 35 | 36 | assert xcplimit(intdivzero) = 0; comment That's our lot, the next exception will be the last; 37 | 38 | xcpmsg(intdivzero) := "DIVIDE BY ZERO!!!"; 39 | ASSERT 42 DIV 0 = 42; comment <--- line 35; 40 | 41 | write("I shouldn't happen.") 42 | end. 43 | ----stderr 44 | Tests/exceptions-intdivzero.alw:16:13: Divide by zero. 45 | Tests/exceptions-intdivzero.alw:30:13: DIVIDE BY ZERO! 46 | Tests/exceptions-intdivzero.alw:34:13: DIVIDE BY ZERO! 47 | Tests/exceptions-intdivzero.alw:39:13: DIVIDE BY ZERO!!! 48 | ----exitcode 49 | 1 50 | ----end 51 | -------------------------------------------------------------------------------- /Tests/expressions-case-incompatible.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 0, 4 do 3 | write(case i of (1,2,true,4,5,6)) 4 | end. 5 | ----compile 6 | Tests/expressions-case-incompatible.alw:3:13: This CASE expression's branch expressions have incompatible types. 7 | ----end 8 | -------------------------------------------------------------------------------- /Tests/expressions-case-too-high.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 7 do 3 | write(case i of (1,2,3,4,5,6)) 4 | end. 5 | ----stdout 6 | 1 7 | 6 8 | ----stderr 9 | Tests/expressions-case-too-high.alw:3:13: CASE range error: selector is 7 10 | ----exitcode 11 | 1 12 | ----end 13 | -------------------------------------------------------------------------------- /Tests/expressions-case-too-low.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 0, 4 do 3 | write(case i of (1,2,3,4,5,6)) 4 | end. 5 | ----stdout 6 | 1 7 | 6 8 | ----stderr 9 | Tests/expressions-case-too-low.alw:3:13: CASE range error: selector is 0 10 | ----exitcode 11 | 1 12 | ----end 13 | -------------------------------------------------------------------------------- /Tests/expressions-case.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 5, 4 do 3 | write (case i of (1, 2, 3, 4, 5, 6)) 4 | end. 5 | ----stdout 6 | 1 7 | 6 8 | 5 9 | 4 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/expressions-if-then-incompatible.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | logical b; 4 | i := if b then #1FFC else 3; 5 | end. 6 | ----compile 7 | Tests/expressions-if-then-incompatible.alw:4:8: incompatible types: the THEN clause is BITS and the ELSE clause is an INTEGER 8 | ----end -------------------------------------------------------------------------------- /Tests/expressions-if-then-needs-else.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | logical b; 4 | i := if b then 1; 5 | end. 6 | ----compile 7 | Tests/expressions-if-then-needs-else.alw:4:18: expected a statement here, got an INTEGER 8 | ----end -------------------------------------------------------------------------------- /Tests/expressions-if-then-string-expressions.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s5; 3 | string(2) s2; 4 | string(1) s1, c; 5 | logical b; 6 | 7 | s2 := "ab"; 8 | c := "x"; 9 | 10 | s5 := if true then s2 else " "; assert s5 = "ab "; 11 | s5 := if false then s2 else "cd"; assert s5 = "cd "; 12 | s5 := if true then s2 else " "; assert s5 = "ab "; 13 | s5 := if false then s2 else "c"; assert s5 = "c "; 14 | s5 := if false then s2 else c; assert s5 = "x "; 15 | 16 | s1 := if true then "t" else s2(0|1); assert s1 = "t"; 17 | s1 := if false then "c" else s2(0|1); assert s1 = "a"; 18 | s1 := if true then c else s2(0|1); assert s1 = "x"; 19 | end. 20 | -------------------------------------------------------------------------------- /Tests/expressions-if-then.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(if false then 1.0 else 3); 3 | write(if false then 4 else 3.2); 4 | write(if false then 4 else 3); 5 | write(if false then false else true); 6 | write(if false then #0FF else #f67e); 7 | end. 8 | ----stdout 9 | 3 10 | 3.2 11 | 3 12 | TRUE 13 | F67E 14 | ----end -------------------------------------------------------------------------------- /Tests/lexing-unclosed-comment.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 0; 4 | comment 5 | now we are in trouble -->: 6 | end. 7 | ----compiler 8 | Tests/lexing-unclosed-comment.alw:4:5: This comment is not closed with a semicolon 9 | ----end 10 | -------------------------------------------------------------------------------- /Tests/lexing-unclosed-string.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 0; 4 | write("now we are in trouble -->'); 5 | end. 6 | ----compiler 7 | Tests/lexing-unclosed-string.alw:4:11: This string is not closed with a double quote 8 | ----end 9 | -------------------------------------------------------------------------------- /Tests/long-comment-error-1.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("1"); 3 | @awe_text 4 | write("2"); 5 | end. 6 | ----compiler 7 | Tests/long-comment-error-1.alw:3:1: This @AWE_TEXT directive is not closed with an @AWE_CODE directive 8 | ----end -------------------------------------------------------------------------------- /Tests/long-comment-error-2.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("1"); 3 | @awe_text 4 | write("2"); 5 | @awe_text 6 | write("3"); 7 | @awe_code 8 | write("4"); 9 | end. 10 | ----compile 11 | Tests/long-comment-error-2.alw:3:1: This @AWE_TEXT directive is not closed with an @AWE_CODE directive 12 | ----end 13 | -------------------------------------------------------------------------------- /Tests/long-comment-error-3.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("1"); 3 | @awe_text 4 | write(x); %we shouldn't see this error% 5 | @awe_code 6 | write(x); %error message should point to the right place% 7 | end. 8 | ----compiler 9 | Tests/long-comment-error-3.alw:6:10: 'x' is undefined here 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/long-comment.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("1"); 3 | @awe_text 4 | write("2"); woot! we do what we like in here! 5 | write("3"); 6 | @awe_code 7 | write("4"); 8 | end. 9 | ----stdout 10 | 1 11 | 4 12 | ----end -------------------------------------------------------------------------------- /Tests/operators-bits.alw: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | comment Equality; 4 | assert(#1 = #1); 5 | assert(#2 = #2); 6 | assert(#1 ~= #0); 7 | 8 | comment Bit operators; 9 | assert((#88888888 shl 1) = #11111110); 10 | assert((#11111111 shl 0) = #11111111); 11 | assert((#88888888 shl 7) = #44444400); 12 | assert((#88888888 shr 0) = #88888888); 13 | assert((#11111111 shr 1) = #08888888); 14 | assert((#11111111 shr 7) = #00222222); 15 | 16 | assert((#88888888 shl -1) = #11111110); 17 | assert((#88888888 shl -7) = #44444400); 18 | assert((#11111111 shr -1) = #08888888); 19 | assert((#11111111 shr -7) = #00222222); 20 | 21 | assert((#11 or #11) = #11); 22 | assert((#11 or #22) = #33); 23 | assert((#ee and #77) = #66); 24 | 25 | assert((~ #1001)= #ffffeffe); 26 | 27 | end. 28 | -------------------------------------------------------------------------------- /Tests/operators-integer-divide-by-0.alw: -------------------------------------------------------------------------------- 1 | write(1 div 0). 2 | ----stderr 3 | Tests/operators-integer-divide-by-0.alw:1:9: Integer division by zero. 4 | ----exitcode 5 | 1 6 | ----end 7 | -------------------------------------------------------------------------------- /Tests/operators-integer-division.alw: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | comment Section 6.3.2.3; 4 | 5 | integer procedure SGN(integer value A); 6 | if A < 0 then -1 else 1; 7 | 8 | integer procedure D(integer value A, B); 9 | if A < B then 0 else D(A-B, B) + 1; 10 | 11 | for a := 91, 10, 0, -13, -10 do 12 | for b := 43, 5, -5, -10 do 13 | assert A div B = SGN(A * B) * D(abs A, abs B); 14 | 15 | 16 | comment Section 6.3.2.4; 17 | 18 | for a := 91, 10, 0, -13, -10 do 19 | for b := 43, 5, -5, -10 do 20 | assert a rem b = a - (a div b) * b; 21 | 22 | 23 | comment Section 6.3.2.1; 24 | 25 | assert 5 / 2 = 2.5; 26 | 27 | end. 28 | -------------------------------------------------------------------------------- /Tests/operators-integer.alw: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | assert +1 = 1; 4 | assert -1 = -1; 5 | 6 | assert 2 + 2 = 4; 7 | assert 2 - 3 = -1; 8 | assert 2 * 3 = 6; 9 | assert 8 div 2 = 4; 10 | assert 9 div 2 = 4; 11 | assert 9 rem 2 = 1; 12 | assert 8 rem 2 = 0; 13 | 14 | assert (if true then 2 else 3) + 2 = 4; 15 | assert case 2 of (1,2,3,4,5) + 2 = 4; 16 | 17 | assert entier(32.4) = 32; 18 | assert entier(32.7) = 32; 19 | 20 | assert abs -42 = 42; 21 | assert abs 42 = 42; 22 | assert long 3 = 3.0L; 23 | 24 | end. 25 | -------------------------------------------------------------------------------- /Tests/operators-logical-comparison.alw: -------------------------------------------------------------------------------- 1 | begin 2 | 3 | comment Comparision of LOGICAL values was an ALGOLW extension to Algol W (inherited from MTS Algol); 4 | 5 | assert(true = true); 6 | assert(false = false); 7 | 8 | assert(true ~= false); 9 | assert(false ~= true); 10 | 11 | assert(true > false); 12 | assert(true >= false); 13 | assert(true >= true); 14 | 15 | assert(false < true); 16 | assert(false <= true); 17 | assert(false <= false); 18 | 19 | end. 20 | -------------------------------------------------------------------------------- /Tests/operators-logical.alw: -------------------------------------------------------------------------------- 1 | begin 2 | assert (true and true); 3 | assert ~(true and false); 4 | assert ~(false and true); 5 | assert ~(false and false); 6 | 7 | assert (true or true); 8 | assert (true or false); 9 | assert (false or true); 10 | assert ~(false or false); 11 | 12 | assert ~~true; 13 | assert ~false; 14 | 15 | assert ~(if true then false else true); 16 | assert (if false then false else true); 17 | 18 | begin comment The "shortcut" property; 19 | integer i; 20 | i := 0; 21 | write(i > 0 and 1 div i = 1); comment the divisions won't happen; 22 | write(i = 0 or 1 div i = 1); 23 | end; 24 | end. 25 | ----stdout 26 | FALSE 27 | TRUE 28 | ----end -------------------------------------------------------------------------------- /Tests/operators-pwr.alw: -------------------------------------------------------------------------------- 1 | begin 2 | complex x; 3 | 4 | write(0 ** 0); 5 | write(1 ** 0, 1 ** 1, 1 ** 2); 6 | write(1 ** 0, 1 ** 1, 1 ** 2); 7 | write(" "); 8 | 9 | write(0.0 ** 0); 10 | write(10.0 ** 0, 10.0 ** 1, 10.0 ** 2, 10.0 ** 20); 11 | write(10.0 ** 0, 10.0 ** -1, 10.0 ** -2, 10.0 ** -20); 12 | write(" "); 13 | 14 | x := 7 - 4i; 15 | write(x ** 0); 16 | write(x ** 1); 17 | write(x ** 2); 18 | write(x ** 20); 19 | end. 20 | ----stdout 21 | 1 22 | 1 1 1 23 | 1 1 1 24 | 25 | 1 26 | 1 10 100 1'+20 27 | 1 0.1 0.01 1'-20 28 | 29 | 1 0I 30 | 7 -4I 31 | 33 -56I 32 | -7.741605'+17 1.101422'+18I 33 | ----end 34 | -------------------------------------------------------------------------------- /Tests/operators-real-divide-by-0.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real x, y; 3 | x := 0.0; 4 | y := 1.0 / x; 5 | write(y); 6 | end. 7 | ----stderr 8 | Tests/operators-real-divide-by-0.alw:4:14: Floating-point division by zero. 9 | ----exitcode 10 | 1 11 | ----end 12 | -------------------------------------------------------------------------------- /Tests/operators-string-substring-negative-index.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(6) s6; 3 | 4 | s6 := "012345"; 5 | for i := 4 step -1 until -1 do 6 | write(s6(i|2)) 7 | end. 8 | ----stdout 9 | 45 10 | 34 11 | 23 12 | 12 13 | 01 14 | ----stderr 15 | Tests/operators-string-substring-negative-index.alw:6:14: Invalid substring (-1|2). 16 | ----exitcode 17 | 1 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/operators-string-substring-too-long.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(3) s3; 3 | 4 | s3 := "012"; 5 | s3 := s3(0|4); 6 | end. 7 | ----compile 8 | Tests/operators-string-substring-too-long.alw:5:11: a STRING(3) can never contain 4 character substrings 9 | ----end 10 | -------------------------------------------------------------------------------- /Tests/operators-string-substring.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(6) s; 3 | string(6) array A (1::2); 4 | 5 | A(1) := "abcdef"; 6 | assert A(1)(0|3) = "abc"; 7 | s := "012345"; 8 | s(2|3) := A(1)(0|3); 9 | assert s = "01abc5"; 10 | 11 | A(1)(0|2) := s(4|2); 12 | assert A(1) = "c5cdef" 13 | end. 14 | -------------------------------------------------------------------------------- /Tests/operators-string.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(3) s3; 3 | string(6) s6, s6_2; 4 | 5 | assert "aaa" < "zzz"; 6 | assert "zzz" > "aaa"; 7 | assert "aaa" <= "zzz"; 8 | assert "zzz" >= "aaa"; 9 | assert "zzz" ~= "aaa"; 10 | assert "aaa" = "aaa"; 11 | assert "aaa" >= "aaa"; 12 | assert "aaa" <= "aaa"; 13 | assert "aaa" < "aaaa"; 14 | assert "aaaa" > "aaa"; 15 | assert "aaaa" ~= "aaa"; 16 | 17 | 18 | s6 := "012345"; 19 | s3 := s6(0|3); assert s3 = "012"; 20 | s3 := s6(1|3); assert s3 = "123"; 21 | s3 := s6(2|3); assert s3 = "234"; 22 | s3 := s6(3|3); assert s3 = "345"; 23 | 24 | s6 := s6(4|2); assert s6 = "45 "; 25 | 26 | s6 := "12"; 27 | s6_2 := "12 "; 28 | assert s6 = s6_2; 29 | assert s6_2 = s6; 30 | end. -------------------------------------------------------------------------------- /Tests/operators-triplet-rule.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(3 / 7); comment INTEGER / INTEGER -> LONG REAL (special case); 3 | write(3 / 7.0); comment INTEGER / REAL -> REAL; 4 | write(3.0 / 7); comment REAL / INTEGER -> REAL; 5 | write(3I / 7); comment COMPLEX / INTEGER -> COMPLEX; 6 | write(3I / 7.0); comment COMPLEX / REAL -> COMPLEX; 7 | end. 8 | ----stdout 9 | 0.4285714 10 | 0.4285714 11 | 0.4285714 12 | 0 0.4285714I 13 | 0 0.4285714I 14 | ----end -------------------------------------------------------------------------------- /Tests/parser-expressions.dat: -------------------------------------------------------------------------------- 1 | a 2 | a 3 | 4 | a(b) 5 | a(b) 6 | 7 | a(b,c) 8 | a(b, c) 9 | 10 | a(b,c)(d|1) 11 | a(b, c)(d | 1) 12 | 13 | a(b,c)(d|e) 14 | ^Syntax Error 15 | 16 | $ // is a synonym for | 17 | 18 | a(b,c)(d//1) 19 | a(b, c)(d | 1) 20 | 21 | a(b / c // 1) 22 | a((b / c) | 1) 23 | 24 | $ Empty statements may be actual parameters 25 | 26 | a() 27 | a((*empty*)) 28 | 29 | a(, b) 30 | a((*empty*), b) 31 | 32 | a(b,) 33 | a(b, (*empty*)) 34 | 35 | a(b,,c) 36 | a(b, (*empty*), c) 37 | 38 | a + b 39 | (a + b) 40 | 41 | a * b 42 | (a * b) 43 | 44 | a + b + c 45 | ((a + b) + c) 46 | 47 | a / b / c 48 | ((a / b) / c) 49 | 50 | $ looks wrong, but is correct: 51 | a ** b ** c 52 | ((a ** b) ** c) 53 | 54 | a + b * c 55 | (a + (b * c)) 56 | 57 | a * b + c 58 | ((a * b) + c) 59 | 60 | (a + b) * c 61 | ((a + b) * c) 62 | 63 | a * (b + c) 64 | (a * (b + c)) 65 | 66 | a = b OR c 67 | ((a = b) OR c) 68 | 69 | ~ a = b OR c 70 | ((~ (a = b)) OR c) 71 | 72 | $This is the proper symbol for "not": 73 | ¬ a 74 | (~ a) 75 | 76 | a AND b OR c 77 | ((a AND b) OR c) 78 | 79 | IF a THEN b ELSE c 80 | (IF a THEN b ELSE c) 81 | 82 | a + IF b THEN c ELSE d 83 | (a + (IF b THEN c ELSE d)) 84 | 85 | IF a THEN b ELSE c + d 86 | (IF a THEN b ELSE (c + d)) 87 | 88 | IF IF a THEN b ELSE c THEN d ELSE e 89 | (IF (IF a THEN b ELSE c) THEN d ELSE e) 90 | 91 | IF a THEN IF b THEN c ELSE d ELSE e 92 | (IF a THEN (IF b THEN c ELSE d) ELSE e) 93 | 94 | IF a THEN b ELSE IF c THEN d ELSE e 95 | (IF a THEN b ELSE (IF c THEN d ELSE e)) 96 | 97 | $ The precedence of unary minus is up with binary minus, which is a little odd: 98 | 99 | -a 100 | (- a) 101 | 102 | -a - b 103 | ((- a) - b) 104 | 105 | $ This looks odd, but is correct: 106 | - a * b 107 | (- (a * b)) 108 | 109 | $ This looks odd, but is correct: 110 | - a ** b 111 | (- (a ** b)) 112 | 113 | - IF a THEN b ELSE c 114 | (- (IF a THEN b ELSE c)) 115 | 116 | $ Other unary operators are where you'd expect them to be: 117 | 118 | ~ a AND b 119 | ((~ a) AND b) 120 | 121 | $ I though this would be a syntax error, 122 | $ because negation is non-associative, 123 | $ but it is accepted: 124 | - - a 125 | (- (- a)) 126 | 127 | x := a + b 128 | (x := (a + b)) 129 | 130 | $ This is not really allowed. Maybe it can be a type error (:= returns VOID). 131 | x := y := a + b 132 | (x := (y := (a + b))) 133 | 134 | ASSERT a > b 135 | (ASSERT (a > b)) 136 | 137 | -------------------------------------------------------------------------------- /Tests/parser-lexing-operators.dat: -------------------------------------------------------------------------------- 1 | $ parser-lexing-operators.dat -- some operator lexing peculiarities 2 | 3 | $ "NOT" was introduced as an operator after 1972 4 | 5 | a NOT= b 6 | (a ~= b) 7 | 8 | a NOT = b 9 | (a ~= b) 10 | 11 | a Not= b 12 | (a ~= b) 13 | 14 | a not = b 15 | (a ~= b) 16 | 17 | (not a) 18 | (~ a) 19 | 20 | $ Spaces are allowed between the two characters of an operator 21 | $ (Any whitespace is, but I haven't allowed newlines) 22 | 23 | a >= b 24 | (a >= b) 25 | 26 | a > = b 27 | (a >= b) 28 | 29 | a > = b 30 | (a >= b) 31 | 32 | -------------------------------------------------------------------------------- /Tests/parser-lexing.dat: -------------------------------------------------------------------------------- 1 | algolw 2 | algolw 3 | 4 | ALGOLW 5 | algolw 6 | 7 | AlgolW 8 | algolw 9 | 10 | Algol_W 11 | algol_w 12 | 13 | _Algol_W 14 | ^Unexpected character '_' 15 | 16 | $ This gets lexed as an integer followed by a constant, but that isn't allowed anyway. 17 | 5algolW 18 | ^Syntax Error 19 | 20 | algol68 21 | algol68 22 | 23 | COMMENT blah blah; AlgolW 24 | algolw 25 | 26 | Comment blah blah; AlgolW 27 | algolw 28 | 29 | comment blah blah; AlgolW 30 | algolw 31 | 32 | comment blah blah AlgolW 33 | ^This comment is not closed with a semicolon 34 | 35 | % blah blah; AlgolW 36 | algolw 37 | 38 | % blah blah % AlgolW 39 | algolw 40 | 41 | % blah blah AlgolW 42 | ^This comment is not closed with a semicolon 43 | 44 | 1200 45 | 1200 46 | 47 | 0 48 | 0 49 | 50 | $too big, but lexically correct: 51 | 100000000000000000 52 | 100000000000000000 53 | 54 | "String" 55 | "String" 56 | 57 | #00000000 58 | #00000000 59 | 60 | #0000BEEF 61 | #0000BEEF 62 | 63 | #FFFFFFFF 64 | #FFFFFFFF 65 | 66 | $too big, but lexically correct: 67 | #FFFFFFFFF 68 | #FFFFFFFFF 69 | 70 | # 71 | ^Unexpected character '#' 72 | 73 | ' 74 | ^Unexpected character '\'' 75 | 76 | 0.1 77 | 0.1 78 | 79 | 1. 80 | 1.0 81 | 82 | 1.0'3 83 | 1.0'3 84 | 85 | 0.1 86 | 0.1 87 | 88 | .1 89 | 0.1 90 | 91 | 1.'3 92 | 1.0'3 93 | 94 | 1'3 95 | 1.0'3 96 | 97 | 1.'3 98 | 1.0'3 99 | 100 | '3 101 | 1.0'3 102 | 103 | 0.1I 104 | 0.1I 105 | 106 | 1.I 107 | 1.0I 108 | 109 | 1.0'3I 110 | 1.0'3I 111 | 112 | 0.1I 113 | 0.1I 114 | 115 | 1I 116 | 1.0I 117 | 118 | 1.'3I 119 | 1.0'3I 120 | 121 | 1.'3I 122 | 1.0'3I 123 | 124 | '3I 125 | 1.0'3I 126 | 127 | 0.1L 128 | 0.1L 129 | 130 | 1.L 131 | 1.0L 132 | 133 | 1.0'3L 134 | 1.0'3L 135 | 136 | 0.1L 137 | 0.1L 138 | 139 | 1L 140 | 1.0L 141 | 142 | 1.'3L 143 | 1.0'3L 144 | 145 | 1.'3L 146 | 1.0'3L 147 | 148 | '3L 149 | 1.0'3L 150 | 151 | 0.1IL 152 | 0.1IL 153 | 154 | 1IL 155 | 1.0IL 156 | 157 | 1.0'3IL 158 | 1.0'3IL 159 | 160 | 0.1IL 161 | 0.1IL 162 | 163 | 1.IL 164 | 1.0IL 165 | 166 | 1.'3IL 167 | 1.0'3IL 168 | 169 | 1.'3IL 170 | 1.0'3IL 171 | 172 | '3IL 173 | 1.0'3IL 174 | 175 | "String" 176 | "String" 177 | 178 | "String 179 | ^This string is not closed with a double quote 180 | 181 | "String\" 182 | "String\" 183 | 184 | "String"" 185 | ^This string is not closed with a double quote 186 | 187 | -------------------------------------------------------------------------------- /Tests/procedure-external-invalid.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p1 (integer value result i); 3 | algol "{bluh}"; 4 | assert(true) 5 | end. 6 | ----compiler 7 | Tests/procedure-external-invalid.alw:3:6: the external reference "{bluh}" is not a valid C identifier 8 | ----end 9 | -------------------------------------------------------------------------------- /Tests/procedure-external.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p1 (integer value result i); 3 | algol "p1"; 4 | 5 | integer procedure p2 (real value r); 6 | fortran "P2"; 7 | 8 | comment We just want to look at the C code of the above; 9 | assert(true) 10 | end. 11 | ----messages 12 | /* PROCEDURE p1 (INTEGER VALUE RESULT i); ALGOL "p1"; */ 13 | void p1 (int *i); 14 | 15 | /* INTEGER PROCEDURE p2 (REAL VALUE r); ALGOL "P2"; */ 16 | int P2 (double r); 17 | 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/procedure-misnamed-block.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p; 3 | begin 4 | end p; 5 | 6 | procedure q; 7 | begin 8 | end r; 9 | 10 | procedure r; 11 | begin 12 | end; 13 | 14 | ; 15 | end 16 | ----compiler 17 | Tests/procedure-misnamed-block.alw:6:4: Note, this procedure is named q, but its block ends with r. 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-equality-2.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record c1 (integer i1); 3 | record c2 (integer i2); 4 | record c3 (integer i3); 5 | 6 | reference(c1) r1; 7 | reference(c1,c2) r2; 8 | reference(c3) r3; 9 | 10 | reference(c1) procedure a (reference(c1) result b); 11 | null; 12 | 13 | procedure b ( reference(c1,c2) value a; 14 | reference(c1,c2) b; 15 | integer value c; 16 | reference(c1,c2) procedure d (reference(c1,c2) value a) ); 17 | begin end; 18 | 19 | r1 := a(r2); 20 | b(r2, r3, 1, a); comment should fail; 21 | end. 22 | ----compile 23 | Tests/procedure-parameters-equality-2.alw:14:19: Note, this is a call-by-name formal parameter. 24 | Tests/procedure-parameters-equality-2.alw:20:11: a REFERENCE(c3) variable is not compatible with a REFERENCE(c1, c2) name parameter 25 | ----end 26 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-equality.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record c1 (integer i1); 3 | record c2 (integer i2); 4 | record c3 (integer i3); 5 | 6 | reference(c1) r1; 7 | reference(c1,c2) r2; 8 | reference(c3) r3; 9 | 10 | reference(c1) procedure a (reference(c1) value b); 11 | null; 12 | 13 | procedure b ( reference(c1,c2) value a; 14 | reference(c1,c2) b; 15 | integer value c; 16 | reference(c1,c2) procedure d (reference(c1,c2) value a) ); 17 | begin end; 18 | 19 | b(r1, r2, 1, a); 20 | b(null, null, 1, a); 21 | b(r2, r1, 1, a); 22 | b(r2, r3, 1, a); comment should fail; 23 | end. 24 | ----compile 25 | Tests/procedure-parameters-equality.alw:14:19: Note, this is a call-by-name formal parameter. 26 | Tests/procedure-parameters-equality.alw:20:13: Note, this call-by-name parameter is an expression. 27 | Tests/procedure-parameters-equality.alw:22:11: a REFERENCE(c3) variable is not compatible with a REFERENCE(c1, c2) name parameter 28 | ----end 29 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-general.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer procedure p ( integer value v; 3 | integer result r; 4 | integer value result vr; 5 | integer n ); 6 | begin 7 | v := v + 1; 8 | r := v + vr; 9 | vr := r + v; 10 | n := n + v; 11 | v 12 | end; 13 | 14 | integer i, r0, vr0, n0; 15 | 16 | vr0 := 2; 17 | n0 := 6; 18 | i := p(1, r0, vr0, n0); 19 | write(i, r0, vr0, n0); 20 | end. 21 | ----compiler 22 | Tests/procedure-parameters-general.alw:5:26: Note, this is a call-by-name formal parameter. 23 | ----stdout 24 | 2 4 6 8 25 | ----end 26 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-hendrik.alw: -------------------------------------------------------------------------------- 1 | COMMENT 2 | Q: "Trivia question: What's the defined semantics for a VALUE 3 | RESULT parameter when the actual parameter is an array element 4 | A(i) and i changes during execution of the procedure?" 5 | 6 | A: The designator expression 'A(i)' is evaluated once at the 7 | beginning of the call, to copy a value into the VALUE RESULT 8 | parameter, and once again at the end of the call, to copy the 9 | VALUE RESULT parameter back out. ; 10 | begin 11 | integer array A(1::2); 12 | integer i; 13 | 14 | procedure p(integer value result ai); 15 | 16 | begin comment ai = A(i) = A(1) here; 17 | ai := ai + 1; 18 | 19 | i := 2; comment <--- Oh no! What have you done?; 20 | 21 | end p; comment ai = A(i) = A(2) here; 22 | 23 | A(1) := 2; 24 | A(2) := 4; 25 | 26 | i := 1; 27 | 28 | p(A(i)); 29 | 30 | assert A(1) = 2; 31 | assert A(2) = 3 32 | end. 33 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-incompatable.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer procedure a; 3 | 1; 4 | 5 | procedure p (logical procedure x); 6 | write(x); 7 | 8 | p(a) 9 | end. 10 | ----compile 11 | Tests/procedure-parameters-incompatable.alw:8:6: expected a LOGICAL PROCEDURE parameter, this is an INTEGER 12 | ----end -------------------------------------------------------------------------------- /Tests/procedure-parameters-manorboy.alw: -------------------------------------------------------------------------------- 1 | comment Knuth's "Man or boy?" test; 2 | begin 3 | integer procedure A (integer value k; integer procedure x1, x2, x3, x4, x5); 4 | begin 5 | integer procedure B; 6 | begin 7 | k := k - 1; 8 | A(k, B, x1, x2, x3, x4) 9 | end B; 10 | 11 | if k <= 0 then 12 | x4 + x5 13 | else 14 | B 15 | end A; 16 | 17 | assert A(10, 1, -1, -1 , 1 , 0) = -67 18 | end. 19 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-name-manorboy.alw: -------------------------------------------------------------------------------- 1 | comment Knuth's "Man or boy?" test; 2 | comment (Uses expressions in Name parameters, and gets away with it); 3 | begin 4 | integer procedure A (integer value k; integer x1, x2, x3, x4, x5); 5 | begin 6 | integer procedure B; 7 | begin 8 | k := k - 1; 9 | A(k, B, x1, x2, x3, x4) 10 | end B; 11 | 12 | if k <= 0 then 13 | x4 + x5 14 | else 15 | B 16 | end A; 17 | 18 | assert A(10, 1, -1, -1 , 1 , 0) = -67 19 | end. 20 | ----compiler 21 | Tests/procedure-parameters-name-manorboy.alw:4:42: Note, this is a call-by-name formal parameter. 22 | Tests/procedure-parameters-name-manorboy.alw:9:15: Note, this call-by-name parameter is an expression. 23 | Tests/procedure-parameters-name-manorboy.alw:18:17: Note, this call-by-name parameter is an expression. 24 | Tests/procedure-parameters-name-manorboy.alw:18:20: Note, this call-by-name parameter is an expression. 25 | Tests/procedure-parameters-name-manorboy.alw:18:24: Note, this call-by-name parameter is an expression. 26 | Tests/procedure-parameters-name-manorboy.alw:18:29: Note, this call-by-name parameter is an expression. 27 | Tests/procedure-parameters-name-manorboy.alw:18:33: Note, this call-by-name parameter is an expression. 28 | ----end 29 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-name-name.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::2); 3 | 4 | integer i; 5 | 6 | procedure p (integer ai); 7 | begin 8 | assert ai = 1; 9 | ai := ai * 2; 10 | q(ai) 11 | end; 12 | 13 | procedure q (integer ai); 14 | begin 15 | i := i + 1; 16 | assert ai = 2; 17 | ai := ai * 2; 18 | assert ai = 4; 19 | end; 20 | 21 | a(1) := 1; 22 | a(2) := 2; 23 | i := 1; 24 | 25 | p(a(i)); 26 | 27 | assert a(1) = 2; 28 | assert a(2) = 4 29 | end. 30 | ----compile 31 | Tests/procedure-parameters-name-name.alw:6:17: Note, this is a call-by-name formal parameter. 32 | Tests/procedure-parameters-name-name.alw:13:17: Note, this is a call-by-name formal parameter. 33 | ----end 34 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-name.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer array a(1::2); 3 | 4 | integer i; 5 | 6 | procedure p (integer ai); 7 | begin 8 | assert ai = 1; 9 | ai := ai * 2; 10 | i := i + 1; 11 | assert ai = 2; 12 | ai := ai * 2; 13 | assert ai = 4; 14 | end; 15 | 16 | a(1) := 1; 17 | a(2) := 2; 18 | i := 1; 19 | 20 | p(a(i)); 21 | 22 | assert a(1) = 2; 23 | assert a(2) = 4 24 | end. 25 | ----compile 26 | Tests/procedure-parameters-name.alw:6:17: Note, this is a call-by-name formal parameter. 27 | ----end 28 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-procedure-incompatible.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure p (procedure q (integer i)); 3 | q(0); 4 | 5 | procedure q0 (integer result i); 6 | i := 1; 7 | 8 | p(q0) 9 | end. 10 | ----compile 11 | Tests/procedure-parameters-procedure-incompatible.alw:2:31: Note, this is a call-by-name formal parameter. 12 | Tests/procedure-parameters-procedure-incompatible.alw:3:10: Note, this call-by-name parameter is an expression. 13 | Tests/procedure-parameters-procedure-incompatible.alw:8:7: expected PROCEDURE (INTEGER) here, this is PROCEDURE (INTEGER RESULT) 14 | ----end 15 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-procedure.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real procedure f (real value i); 3 | i + i / 3; 4 | 5 | real procedure g (real value i); 6 | i + i / 2; 7 | 8 | real procedure sum (integer value first, last; real procedure f (real value x)); 9 | begin 10 | real total; 11 | total := 0; 12 | for i := first until last do 13 | total := total + f(i); 14 | total 15 | end sum; 16 | 17 | real procedure sum2 (integer value first, last; real procedure f, g (real value x)); 18 | begin 19 | real total; 20 | total := 0; 21 | for i := first until last do 22 | total := total + f(g(i)); 23 | total 24 | end sum2; 25 | 26 | real procedure c (real procedure a, b (real value x); real value x); 27 | a(b(x)); 28 | 29 | real procedure sum3 ( integer value first, last; 30 | real procedure c (real procedure a, b (real value x); real value x); 31 | real procedure f, g (real value x) ); 32 | begin 33 | real total; 34 | total := 0; 35 | for i := first until last do 36 | total := total + c(f, g, i); 37 | total 38 | end sum3; 39 | 40 | write(sum(1, 10, f)); 41 | write(sum(1, 10, g)); 42 | write(sum2(1, 10, f, g)); 43 | write(sum3(1, 10, c, f, g)); 44 | end. 45 | ----stdout 46 | 73.33333 47 | 82.5 48 | 110 49 | 110 50 | ----end 51 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-result-incompatible-2.alw: -------------------------------------------------------------------------------- 1 | begin 2 | logical x; 3 | procedure p(integer result i); begin end; 4 | p(x) 5 | end. 6 | ----compile 7 | Tests/procedure-parameters-result-incompatible-2.alw:4:6: an INTEGER cannot be assigned to a LOGICAL variable 8 | ----end 9 | -------------------------------------------------------------------------------- /Tests/procedure-parameters-result-incompatible.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | procedure p(real value okay; real result not_okay); begin end; 4 | p(i, i) 5 | end. 6 | ----compile 7 | Tests/procedure-parameters-result-incompatible.alw:4:9: a REAL cannot be assigned to an INTEGER variable 8 | ----end 9 | -------------------------------------------------------------------------------- /Tests/procedure-parameters.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure a; 3 | begin 4 | write("BING!"); 5 | end a; 6 | 7 | procedure p (procedure w); 8 | begin 9 | for i := 1 until 3 do 10 | w; 11 | end p; 12 | 13 | integer i; 14 | 15 | p(a); 16 | p(write("BONG!")); 17 | 18 | p( ); 19 | 20 | i := 0; 21 | p(i := i + 1); 22 | assert i = 3 23 | end. 24 | ----stdout 25 | BING! 26 | BING! 27 | BING! 28 | BONG! 29 | BONG! 30 | BONG! 31 | ----end -------------------------------------------------------------------------------- /Tests/procedure-result.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i0; 3 | procedure p(integer result i1); 4 | begin 5 | i1 := 2; 6 | assert i0 = 1; 7 | i0 := 3; 8 | assert i0 = 3; 9 | assert i1 = 2; 10 | end; 11 | i0 := 1; 12 | p(i0); 13 | assert i0 = 2 14 | end. 15 | -------------------------------------------------------------------------------- /Tests/procedure-value-result.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i0; 3 | procedure p(integer value result i1); 4 | begin 5 | assert i1 = 1; 6 | i1 := 2; 7 | assert i0 = 1; 8 | i0 := 3; 9 | assert i0 = 3; 10 | assert i1 = 2; 11 | end; 12 | i0 := 1; 13 | p(i0); 14 | assert i0 = 2 15 | end. 16 | -------------------------------------------------------------------------------- /Tests/procedure-value.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i0; 3 | procedure p(integer value i1); 4 | begin 5 | assert i1 = 1; 6 | i1 := 2; 7 | assert i0 = 1; 8 | i0 := 3; 9 | assert i0 = 3; 10 | assert i1 = 2; 11 | end; 12 | i0 := 1; 13 | p(i0); 14 | assert i0 = 3 15 | end. 16 | -------------------------------------------------------------------------------- /Tests/procedure-visibility.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure P1; begin P2 end; 3 | procedure P2; begin I := 42 end; 4 | bits B; 5 | integer I; 6 | 7 | P1; 8 | assert I = 42 9 | end. 10 | -------------------------------------------------------------------------------- /Tests/program-exit-code-int.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure exit(integer value code); algol "exit"; %use C's exit function% 3 | write(2 + 2); 4 | exit(3); 5 | end. 6 | ----messages 7 | /* PROCEDURE exit (INTEGER VALUE code); ALGOL "exit"; */ 8 | void exit (int code); 9 | 10 | ----stdout 11 | 4 12 | ----exitcode 13 | 3 14 | ----end 15 | -------------------------------------------------------------------------------- /Tests/program-exit-code-none.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(2 + 2) 3 | end. 4 | ----stdout 5 | 4 6 | ----exitcode 7 | 0 8 | ----end -------------------------------------------------------------------------------- /Tests/program-exit-code-statement.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(2 + 2) 3 | end. 4 | ----stdout 5 | 4 6 | ----exitcode 7 | 0 8 | ----end -------------------------------------------------------------------------------- /Tests/program-exit-code-wrong-type.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(2 + 2); 3 | TRUE 4 | end. 5 | ----compile 6 | Tests/program-exit-code-wrong-type.alw:3:4: a program should be a statement, this returns a LOGICAL 7 | ----end 8 | -------------------------------------------------------------------------------- /Tests/records-0.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record R1 (integer f1); 3 | record R2 (integer f2); 4 | record R3 (integer f3); 5 | 6 | reference (R1,R2,R3) x1; 7 | reference ( R2,R3) x2; 8 | reference (R1,R2 ) x3; 9 | 10 | x1 := R1(1); 11 | x2 := R2(3); 12 | x3 := x2; 13 | 14 | end. -------------------------------------------------------------------------------- /Tests/records-allocation-expressions.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record C ( 3 | reference(C) r; 4 | string(5) s; 5 | string(8) t; 6 | integer i 7 | ); 8 | reference(C) a, b; 9 | 10 | a := C(null, "AAA", "BBB", 1); 11 | assert(r(a)=null and s(a)="AAA" and t(a)="BBB" and i(a)=1); 12 | 13 | b := C(a, , "XXX", 2); 14 | assert(r(b)=a and t(b)="XXX" and i(b)=2); 15 | 16 | a := b; 17 | b := C(b, "XXX", , 3); 18 | assert(r(b)=a and r(b)~=b); %i.e. the 'b' from before the assignment% 19 | assert(s(b)="XXX"); 20 | assert(i(b)=3); 21 | 22 | b := C( , , , ); 23 | 24 | b := C; 25 | end. 26 | -------------------------------------------------------------------------------- /Tests/records-class-set-compatibility-error.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec2(integer f2); 3 | record rec3(integer f3); 4 | record rec4(integer f4); 5 | record rec5(integer f5); 6 | 7 | reference(rec2, rec3, rec4) r234; 8 | reference(rec4, rec5) r45; 9 | 10 | r45 := rec5; 11 | r234 := r45 12 | end. 13 | ----stderr 14 | Tests/records-class-set-compatibility-error.alw:11:4: reference error: a REFERENCE(rec4, rec3, rec2) cannot be made to refer to a 'rec5' record. 15 | ----exitcode 16 | 1 17 | ----end 18 | -------------------------------------------------------------------------------- /Tests/records-class-set-compatibility.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec2(integer f2); 3 | record rec3(integer f3); 4 | record rec4(integer f4); 5 | 6 | reference(rec2 ) r2; 7 | reference( rec3 ) r3; 8 | reference( rec4) r4; 9 | reference(rec2, rec3 ) r23; 10 | reference(rec2, rec4) r24; 11 | reference(rec2, rec3, rec4) r234; 12 | 13 | r2 := rec2; 14 | r2 := r2; assert r2 is rec2; 15 | r23 := r2; assert r23 is rec2; 16 | r24 := r2; assert r24 is rec2; 17 | r234 := r2; assert r234 is rec2; 18 | 19 | r23 := rec2; 20 | r2 := r23; assert r2 is rec2; 21 | r23 := r23; assert r23 is rec2; 22 | r24 := r23; assert r24 is rec2; 23 | r234 := r23; assert r234 is rec2; 24 | 25 | r234 := rec2; 26 | r2 := r234; assert r2 is rec2; 27 | r23 := r234; assert r23 is rec2; 28 | r24 := r234; assert r24 is rec2; 29 | r234 := r234; assert r234 is rec2; 30 | end. 31 | -------------------------------------------------------------------------------- /Tests/records-field-of-null-run-time.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec1 (integer f1); 3 | reference(rec1) r; 4 | r := null; 5 | f1(r) := 1; 6 | end. 7 | ----stderr 8 | Tests/records-field-of-null-run-time.alw:5:4: reference error: tried to find field f1 of a NULL reference 9 | ----exitcode 10 | 1 11 | ----end -------------------------------------------------------------------------------- /Tests/records-fields-do-not-work-on-null.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec(integer f); 3 | reference(rec) r; 4 | 5 | r := rec(42); 6 | assert(f(r) = 42); 7 | 8 | r := null; 9 | assert(f(r) = 42) 10 | end. 11 | ----stderr 12 | Tests/records-fields-do-not-work-on-null.alw:9:11: reference error: tried to find field f of a NULL reference 13 | ----exitcode 14 | 1 15 | ----end 16 | -------------------------------------------------------------------------------- /Tests/records-fields-wrong-class-compile-time.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec1 (integer f1); 3 | record rec2 (integer f2); 4 | reference(rec1) r1; 5 | r1 := rec1; 6 | f2(r1) := 1; 7 | end. 8 | ----compiler 9 | Tests/records-fields-wrong-class-compile-time.alw:6:7: a REFERENCE(rec1) can never have the field f2 10 | ----end -------------------------------------------------------------------------------- /Tests/records-fields-wrong-class-run-time.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec1 (integer f1); 3 | record rec2 (integer f2); 4 | reference(rec1,rec2) r; 5 | r := rec1; 6 | f2(r) := 1; 7 | end. 8 | ----stderr 9 | Tests/records-fields-wrong-class-run-time.alw:6:4: reference error: tried to find field f2 of a REFERENCE(rec1) 10 | ----exitcode 11 | 1 12 | ----end -------------------------------------------------------------------------------- /Tests/records-is-never-of-class.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record a (integer i); 3 | record b (integer j); 4 | record c (integer k); 5 | reference(a, b) x; 6 | assert(x is c) 7 | end. 8 | ----compiler 9 | Tests/records-is-never-of-class.alw:6:18: a REFERENCE(a, b) will never refer to a RECORD c 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/records-is-null.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record node (integer label; reference(node) next); 3 | reference(node) node1, node2, node3, ptr; 4 | node3 := node(3, null); 5 | node2 := node(2, node3); 6 | node1 := node(1, node2); 7 | ptr := node1; 8 | while ptr is node do begin 9 | write(label(ptr)); 10 | ptr := next(ptr) 11 | end; 12 | write("done"); 13 | end. 14 | ----stdout 15 | 1 16 | 2 17 | 3 18 | done 19 | ----end 20 | -------------------------------------------------------------------------------- /Tests/records-is.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec1(integer f1); 3 | record rec2(integer f2); 4 | record rec3(integer f3); 5 | 6 | reference(rec1, rec2, rec3) r; 7 | 8 | r := null; 9 | assert(r = null); 10 | assert(~ r is rec1); 11 | assert(~ r is rec2); 12 | assert(~ r is rec3); 13 | 14 | r := rec1; 15 | assert(r ~= null); 16 | assert( r is rec1); 17 | assert(~ r is rec2); 18 | assert(~ r is rec3); 19 | 20 | r := rec2; 21 | assert(r ~= null); 22 | assert(~ r is rec1); 23 | assert( r is rec2); 24 | assert(~ r is rec3); 25 | 26 | r := rec3; 27 | assert(r ~= null); 28 | assert(~ r is rec1); 29 | assert(~ r is rec2); 30 | assert( r is rec3); 31 | end. 32 | 33 | -------------------------------------------------------------------------------- /Tests/records-parameters.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec1(integer f1); 3 | record rec2(integer f2); 4 | record rec3(integer f3); 5 | 6 | 7 | procedure p(reference(rec1, rec2) v); 8 | begin 9 | if v ~= null then v := rec2; 10 | end; 11 | 12 | reference(rec1, rec2) r; 13 | reference(rec2) r2; 14 | 15 | r := rec1; 16 | p(r); 17 | assert(r is rec2); 18 | end. 19 | ----compile 20 | Tests/records-parameters.alw:7:16: Note, this is a call-by-name formal parameter. 21 | ----end 22 | -------------------------------------------------------------------------------- /Tests/records-record-designator-class.alw: -------------------------------------------------------------------------------- 1 | comment Record designators: return a reference of the correct class; 2 | begin 3 | record rec1(integer f1); 4 | record rec2(integer f2); 5 | reference(rec1, rec2) r0; 6 | reference(rec1) r1; 7 | reference(rec2) r2; 8 | 9 | r0 := rec1; 10 | r0 := rec2; 11 | 12 | r1 := rec1; 13 | r2 := rec2; 14 | 15 | r1 := rec2 comment It won't like that; 16 | end. 17 | ----compiler 18 | Tests/records-record-designator-class.alw:15:4: a REFERENCE(rec2) cannot be assigned to a REFERENCE(rec1) variable 19 | ----end 20 | -------------------------------------------------------------------------------- /Tests/records-record-designators.alw: -------------------------------------------------------------------------------- 1 | comment Record designators take no parameters or as many parameters as fields; 2 | comment Uninitialized record fields are assigned zero-like default values by default (not required); 3 | comment EXCEPT for ninitialized references, which the algolw runtime will give an error for; 4 | begin 5 | record rec ( 6 | integer i; 7 | real x; 8 | complex c; 9 | logical l; 10 | bits b; 11 | reference(rec) r; 12 | string(3) s 13 | ); 14 | 15 | reference(rec) ref; 16 | 17 | ref := rec; 18 | 19 | assert(ref ~= null); 20 | 21 | i(ref) := 1; comment Just to be sure that we really do get a new record next; 22 | x(ref) := 2.0; 23 | c(ref) := 3.0; 24 | 25 | ref := rec(,,,,,,); 26 | 27 | ref := rec(1, , 2+3i, true, , , "Yay"); 28 | 29 | assert(i(ref) = 1); 30 | assert(c(ref) = 2+3i); 31 | assert(l(ref)); 32 | assert(s(ref) = "Yay"); 33 | end. 34 | -------------------------------------------------------------------------------- /Tests/records-string-fields.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec(string(5) s); 3 | string(5) t, u; 4 | reference(rec) r; 5 | 6 | r := rec("012"); 7 | u := "012"; 8 | 9 | t := u; 10 | assert t = "012 "; 11 | assert t = "012"; 12 | 13 | t := s(r); 14 | assert t = "012 "; 15 | assert t = "012"; 16 | assert s(r) = "012"; 17 | assert s(r) = "012 "; 18 | end. -------------------------------------------------------------------------------- /Tests/records-uninitialized-element.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec(reference(rec) f); 3 | reference(rec) array a (1::2); 4 | f(a(1)) := null 5 | end. 6 | ----stderr 7 | Tests/records-uninitialized-element.alw:4:5: reference error: tried to find field f of an uninitialized reference 8 | ----exitcode 9 | 1 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/records-uninitialized-field.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec(reference(rec) f); 3 | reference(rec) r; 4 | f(r) := null 5 | end. 6 | ----stderr 7 | Tests/records-uninitialized-field.alw:4:5: reference error: tried to find field f of an uninitialized reference 8 | ----exitcode 9 | 1 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/records-uninitialized-variable.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record rec(integer f); 3 | reference(rec) r; 4 | r := null; 5 | write(f(r)) 6 | end. 7 | ----stderr 8 | Tests/records-uninitialized-variable.alw:5:11: reference error: tried to find field f of a NULL reference 9 | ----exitcode 10 | 1 11 | ----end 12 | -------------------------------------------------------------------------------- /Tests/records-visibility.alw: -------------------------------------------------------------------------------- 1 | comment A reference type for a record can be made anywhere it is in scope, including in its own definition; 2 | comment nested field designators work; 3 | begin 4 | record rec1(reference(rec1,rec2) f1); 5 | record rec2(reference(rec1,rec2) f2); 6 | begin 7 | record rec3(reference(rec1,rec2,rec3) f3); 8 | 9 | reference(rec1,rec2,rec3) r; 10 | 11 | r := rec3(rec2(rec1(null))); 12 | 13 | assert r is rec3; 14 | assert f3(r) is rec2; 15 | assert f2(f3(r)) is rec1; 16 | assert f1(f2(f3(r))) = null; 17 | end 18 | end. 19 | -------------------------------------------------------------------------------- /Tests/records.alw: -------------------------------------------------------------------------------- 1 | begin 2 | record r (integer i; real n); 3 | reference(r) x; 4 | 5 | x := r(1, 1.0); 6 | assert i(x) = 1; 7 | assert n(x) = 1.0; 8 | 9 | i(x) := 2; 10 | n(x) := 2.0; 11 | assert i(x) = 2; 12 | assert n(x) = 2.0 13 | end. 14 | -------------------------------------------------------------------------------- /Tests/roman4.alw: -------------------------------------------------------------------------------- 1 | BEGIN 2 | 3 | PROCEDURE ROMAN (INTEGER VALUE NUMBER; STRING(15) RESULT CHARACTERS; INTEGER RESULT LENGTH); 4 | COMMENT 5 | Returns the Roman number of an integer between 1 and 3999. 6 | "MMMDCCCLXXXVIII" (15 characters long) is the longest Roman number under 4000; 7 | BEGIN 8 | INTEGER PLACE, POWER; 9 | 10 | PROCEDURE APPEND (STRING(1) VALUE C); 11 | BEGIN CHARACTERS(LENGTH|1) := C; LENGTH := LENGTH + 1 END; 12 | 13 | PROCEDURE I; APPEND(CASE PLACE OF ("I","X","C","M")); 14 | PROCEDURE V; APPEND(CASE PLACE OF ("V","L","D")); 15 | PROCEDURE X; APPEND(CASE PLACE OF ("X","C","M")); 16 | 17 | ASSERT (NUMBER >= 1) AND (NUMBER < 4000); 18 | 19 | CHARACTERS := " "; 20 | LENGTH := 0; 21 | POWER := 1000; 22 | PLACE := 4; 23 | WHILE PLACE > 0 DO 24 | BEGIN 25 | CASE NUMBER DIV POWER + 1 OF BEGIN 26 | BEGIN END; 27 | BEGIN I END; 28 | BEGIN I; I END; 29 | BEGIN I; I; I END; 30 | BEGIN I; V END; 31 | BEGIN V END; 32 | BEGIN V; I END; 33 | BEGIN V; I; I END; 34 | BEGIN V; I; I; I END; 35 | BEGIN I; X END 36 | END; 37 | NUMBER := NUMBER REM POWER; 38 | POWER := POWER DIV 10; 39 | PLACE := PLACE - 1 40 | END 41 | END ROMAN; 42 | 43 | INTEGER I; 44 | STRING(15) S; 45 | 46 | ROMAN(1, S, I); WRITE(S, I); 47 | ROMAN(3999, S, I); WRITE(S, I); 48 | ROMAN(3888, S, I); WRITE(S, I); 49 | ROMAN(2009, S, I); WRITE(S, I); 50 | ROMAN(405, S, I); WRITE(S, I); 51 | END. 52 | ----stdout 53 | I 1 54 | MMMCMXCIX 9 55 | MMMDCCCLXXXVIII 15 56 | MMIX 4 57 | CDV 3 58 | ----end 59 | -------------------------------------------------------------------------------- /Tests/standard-analysis-exp.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 700 until 710 do 3 | write(i, exp(i)) 4 | end. 5 | ----stdout 6 | 700 1.014232'+304 7 | 701 2.756969'+304 8 | 702 7.494218'+304 9 | 703 2.03714'+305 10 | 704 5.537519'+305 11 | 705 1.505254'+306 12 | 706 4.091704'+306 13 | 707 1.112241'+307 14 | 708 3.023383'+307 15 | 709 8.218407'+307 16 | 710 17 | ----stderr 18 | Tests/standard-analysis-exp.alw:3:16: Argument of EXP or LONGEXP out of domain. 19 | ----exitcode 20 | 1 21 | ----end 22 | -------------------------------------------------------------------------------- /Tests/standard-analysis.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("sqrt(0.5) ", sqrt(0.5)); 3 | write("exp(0.5) ", exp(0.5)); 4 | write("ln(0.5) ", ln(0.5)); 5 | write("log(0.5) ", log(0.5)); 6 | write("sin(0.5) ", sin(0.5)); 7 | write("cos(0.5) ", cos(0.5)); 8 | write("arctan(0.5) ", arctan(0.5)); 9 | write(" "); 10 | write("longsqrt(0.5) ", longsqrt(0.5)); 11 | write("longexp(0.5) ", longexp(0.5)); 12 | write("longln(0.5) ", longln(0.5)); 13 | write("longlog(0.5) ", longlog(0.5)); 14 | write("longsin(0.5) ", longsin(0.5)); 15 | write("longcos(0.5) ", longcos(0.5)); 16 | write("longarctan(0.5) ", longarctan(0.5)); 17 | end. 18 | ----stdout 19 | sqrt(0.5) 0.7071068 20 | exp(0.5) 1.648721 21 | ln(0.5) -0.6931472 22 | log(0.5) -0.30103 23 | sin(0.5) 0.4794255 24 | cos(0.5) 0.8775826 25 | arctan(0.5) 0.4636476 26 | 27 | longsqrt(0.5) 0.7071068 28 | longexp(0.5) 1.648721 29 | longln(0.5) -0.6931472 30 | longlog(0.5) -0.30103 31 | longsin(0.5) 0.4794255 32 | longcos(0.5) 0.8775826 33 | longarctan(0.5) 0.4636476 34 | ----end -------------------------------------------------------------------------------- /Tests/standard-predefined-variables.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(maxinteger); 3 | write(pi); 4 | write(maxreal); 5 | write(epsilon); 6 | write(longepsilon); 7 | end. 8 | ----stdout 9 | 2147483647 10 | 3.141593 11 | 1.797693'+308 12 | 2.220446'-16 13 | 2.220446'-16 14 | ----end 15 | -------------------------------------------------------------------------------- /Tests/standard-read-exception-null.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | integer i; 4 | real r; 5 | complex c; 6 | logical l; 7 | bits b; 8 | 9 | endfile := null; 10 | for counter := 1 until 6 do 11 | begin 12 | read(s, i, r, c, l, b); 13 | write(s, i, r, c, l, b) 14 | end; 15 | write("(end)") 16 | end. 17 | ----stdin 18 | "aaaaa" 1 1.0 1.0+1.0i true #1 19 | "bbbbb" 2 2.0 2.0+2.0i true #2 20 | "ccccc" 3 3.0 3.0+3.0i true #3 21 | ----stdout 22 | aaaaa 1 1 1 1I TRUE 1 23 | bbbbb 2 2 2 2I TRUE 2 24 | ccccc 3 3 3 3I TRUE 3 25 | 0 0 0 0I FALSE 0 26 | 0 0 0 0I FALSE 0 27 | 0 0 0 0I FALSE 0 28 | (end) 29 | ----end -------------------------------------------------------------------------------- /Tests/standard-read-exception.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | integer i; 4 | real r; 5 | complex c; 6 | logical l; 7 | bits b; 8 | 9 | xcplimit(endfile) := 6; 10 | xcpmark(endfile) := false; 11 | xcpmsg(endfile) := "That's your lot."; 12 | 13 | while true do 14 | begin 15 | read(s, i, r, c, l, b); 16 | write(s, i, r, c, l, b) 17 | end; 18 | write("You shouldn't see this.") 19 | end. 20 | ----stdin 21 | "aaaaa" 1 1.0 1.0+1.0i true #1 22 | "bbbbb" 2 2.0 2.0+2.0i true #2 23 | "ccccc" 3 3.0 3.0+3.0i true #3 24 | ----stdout 25 | aaaaa 1 1 1 1I TRUE 1 26 | bbbbb 2 2 2 2I TRUE 2 27 | ccccc 3 3 3 3I TRUE 3 28 | 0 0 0 0I FALSE 0 29 | ----stderr 30 | Tests/standard-read-exception.alw:15:10: That's your lot. 31 | ----exitcode 32 | 1 33 | ----end -------------------------------------------------------------------------------- /Tests/standard-read-integer.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i, j, k; 3 | read(i, j, k); 4 | write(i, j, k); 5 | read(i, j); 6 | write(i, j); 7 | readon(i); 8 | write(i) 9 | end. 10 | ----stdin 11 | 1 123 -42 -9999 12 | 2 3 -9999 13 | ----stdout 14 | 1 123 -42 15 | 2 3 16 | -9999 17 | ----end 18 | -------------------------------------------------------------------------------- /Tests/standard-read-iocontrol.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | readon(i); write(i); 4 | readon(i); write(i); 5 | 6 | iocontrol(1); 7 | 8 | readon(i); write(i); 9 | readon(i); write(i); 10 | 11 | read(i); write(i); 12 | readon(i); write(i); 13 | end. 14 | ----stdin 15 | 1 2 3 16 | 4 5 6 17 | 7 8 18 | ----stdout 19 | 1 20 | 2 21 | 4 22 | 5 23 | 7 24 | 8 25 | ----end -------------------------------------------------------------------------------- /Tests/standard-read-real.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real r; 3 | while true do 4 | begin 5 | readon(r); 6 | write(r); 7 | end 8 | end. 9 | ----stdin 10 | 12 +12 12l 11 | 12. +12. 12.l 12 | .34 +.34 .34l 13 | 12.34 +12.34 12.34l 14 | 12'5 +12'5 12'5l 15 | 12.'5 +12.'5 12.'5l 16 | .34'5 +.34'5 .34'5l 17 | 12.34'5 +12.34'5 12.34'5l 18 | 12'+5 +12'+5 12'+5l 19 | 12.'+5 +12.'+5 12.'+5l 20 | .34'+5 +.34'+5 .34'+5l 21 | 12.34'+5 +12.34'+5 12.34'+5l 22 | '+5 +'+5 '+5l 23 | ----stdout 24 | 12 25 | 12 26 | 12 27 | 12 28 | 12 29 | 12 30 | 0.34 31 | 0.34 32 | 0.34 33 | 12.34 34 | 12.34 35 | 12.34 36 | 1200000 37 | 1200000 38 | 1200000 39 | 1200000 40 | 1200000 41 | 1200000 42 | 34000 43 | 34000 44 | 34000 45 | 1234000 46 | 1234000 47 | 1234000 48 | 1200000 49 | 1200000 50 | 1200000 51 | 1200000 52 | 1200000 53 | 1200000 54 | 34000 55 | 34000 56 | 34000 57 | 1234000 58 | 1234000 59 | 1234000 60 | 100000 61 | 100000 62 | 100000 63 | ----stderr 64 | Tests/standard-read-real.alw:5:10: Unexpected end of input. 65 | ----exitcode 66 | 1 67 | ----end 68 | -------------------------------------------------------------------------------- /Tests/standard-read-strings.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(3) s; 3 | while true do 4 | begin 5 | readon(s); 6 | write("'", s, "' ") 7 | end 8 | end. 9 | ----stdin 10 | "abc" "a" "" """" """a" "a""" "abcd" 11 | ----stdout 12 | 'abc' 13 | 'a ' 14 | ' ' 15 | '"" ' 16 | '""a' 17 | 'a""' 18 | ----stderr 19 | Tests/standard-read-strings.alw:5:11: String too long on line 1 of the standard input. 20 | ----exitcode 21 | 1 22 | ----end 23 | -------------------------------------------------------------------------------- /Tests/standard-read.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(3) s; 3 | logical a,b; 4 | bits x; 5 | integer n; 6 | real r; 7 | complex c; 8 | 9 | for i := 1 until 6 do 10 | begin 11 | readon(s); 12 | write("'", s, "' ") 13 | end; 14 | read(a,b); 15 | write(a,b); 16 | for i := 1 until 4 do 17 | begin 18 | readon(x); 19 | write(x) 20 | end; 21 | for i := 1 until 5 do 22 | begin 23 | readon(n); 24 | write(n) 25 | end; 26 | for i := 1 until 8 do 27 | begin 28 | readon(r); 29 | write(r) 30 | end; 31 | for i := 1 until 2 do 32 | for i := 1 until 8 do 33 | begin 34 | readon(c); 35 | write(c) 36 | end; 37 | end. 38 | ----stdin 39 | "abc" "a" "" """" """a" "a""" 40 | TRUE FALSE 41 | #0 #1 #ffffffff #FFFFFFFF 42 | +10 -10 10 00010 -000010 43 | 10. .1 0.1 1'-1 10'0 +10'2 +10'+2 10 44 | 10.i 45 | .1i 46 | 0.1i 47 | 1'-1i 48 | 10'0i 49 | +10'2i 50 | +10'+2i 51 | 10i 52 | 10.+2i 53 | .1+2i 54 | 0.1+0.2i 55 | 1'-1+2'-2i 56 | 10'0-2.0i 57 | +10'2-.2i 58 | +10'+2 59 | 10+2i 60 | 61 | ----stdout 62 | 'abc' 63 | 'a ' 64 | ' ' 65 | '"" ' 66 | '""a' 67 | 'a""' 68 | TRUE FALSE 69 | 0 70 | 1 71 | FFFFFFFF 72 | FFFFFFFF 73 | 10 74 | -10 75 | 10 76 | 10 77 | -10 78 | 10 79 | 0.1 80 | 0.1 81 | 0.1 82 | 10 83 | 1000 84 | 1000 85 | 10 86 | 0 10I 87 | 0 0.1I 88 | 0 0.1I 89 | 0 0.1I 90 | 0 10I 91 | 0 1000I 92 | 0 1000I 93 | 0 10I 94 | 10 2I 95 | 0.1 2I 96 | 0.1 0.2I 97 | 0.1 0.02I 98 | 10 -2I 99 | 1000 -0.2I 100 | 1000 0I 101 | 10 2I 102 | ----end 103 | -------------------------------------------------------------------------------- /Tests/standard-readcard-eof.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(80) card; 3 | for i := 1 until 4 do 4 | begin 5 | readcard(card); 6 | write(card); 7 | end 8 | end. 9 | ----stdin 10 | line 1 11 | line 2 12 | line 3 13 | ----stdout 14 | line 1 15 | line 2 16 | line 3 17 | ----stderr 18 | Tests/standard-readcard-eof.alw:5:10: Unexpected end of input. 19 | ----exitcode 20 | 1 21 | ----end 22 | -------------------------------------------------------------------------------- /Tests/standard-readcard-exception-eof.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | 4 | xcplimit(endfile) := 1; 5 | xcpmark(endfile) := false; 6 | while 7 | begin 8 | readcard(s); 9 | ~xcpnoted(endfile) 10 | end 11 | do 12 | write("""", s, """"); 13 | 14 | write("(eof)") 15 | end. 16 | ----stdin 17 | one 18 | two 19 | three 20 | four 21 | five 22 | ----stdout 23 | "one " 24 | "two " 25 | "three" 26 | "four " 27 | "five " 28 | (eof) 29 | ----end -------------------------------------------------------------------------------- /Tests/standard-readcard-exception-null.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | endfile := null; 4 | for i := 1 until 10 do 5 | begin 6 | readcard(s); 7 | write("""", s, """") 8 | end 9 | end. 10 | ----stdin 11 | one 12 | two 13 | three 14 | four 15 | five 16 | ----stdout 17 | "one " 18 | "two " 19 | "three" 20 | "four " 21 | "five " 22 | " " 23 | " " 24 | " " 25 | " " 26 | " " 27 | ----end -------------------------------------------------------------------------------- /Tests/standard-readcard-exception.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | xcplimit(endfile) := 3; 4 | xcpmark(endfile) := false; 5 | xcpmsg(endfile) := "Expected more lines on the input."; 6 | for i := 1 until 10 do 7 | begin 8 | readcard(s); 9 | write("""", s, """") 10 | end; 11 | write("You shouldn't see this.") 12 | end. 13 | ----stdin 14 | one 15 | two 16 | three 17 | four 18 | five 19 | ----stdout 20 | "one " 21 | "two " 22 | "three" 23 | "four " 24 | "five " 25 | " " 26 | " " 27 | " " 28 | ----stderr 29 | Tests/standard-readcard-exception.alw:8:10: Expected more lines on the input. 30 | ----exitcode 31 | 1 32 | ----end -------------------------------------------------------------------------------- /Tests/standard-readcard.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(80) card; 3 | for i := 1 until 9 do 4 | begin 5 | readcard(card); 6 | write(i_w := 2, i, card); 7 | end 8 | end. 9 | ----stdin 10 | 1 2 3 4 5 6 7 8 11 | ....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....| 12 | 13 | The hardware representation is case-insensitive. Algol comments are allowed 14 | anywhere white space is allowed. Comments begin with the keyword 15 | "comment" and end after the next semicolon. The optional identifier at 16 | the end of a block is a comment. UTF-8 symbols may be used in comments 17 | and as alternatives to the standard ASCII/EDCBIC operators. 18 | ***************************************************************************************** 19 | ----stdout 20 | 1 1 2 3 4 5 6 7 8 21 | 2 ....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....| 22 | 3 23 | 4 The hardware representation is case-insensitive. Algol comments are allowed 24 | 5 anywhere white space is allowed. Comments begin with the keyword 25 | 6 "comment" and end after the next semicolon. The optional identifier at 26 | 7 the end of a block is a comment. UTF-8 symbols may be used in comments 27 | 8 and as alternatives to the standard ASCII/EDCBIC operators. 28 | 9 ******************************************************************************** 29 | ----end 30 | -------------------------------------------------------------------------------- /Tests/standard-transfer-base.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real r; 3 | 4 | procedure w (real value x); 5 | begin 6 | write( base10(x), " ", longbase10(x)); 7 | end; 8 | 9 | w(0); 10 | w(1); 11 | w(10); 12 | w(16); 13 | w(32); 14 | w(-91'101); 15 | w(91'-101); 16 | write(" "); 17 | 18 | r := 1.23456789012345; 19 | for i := 0 until 10 do 20 | begin 21 | w(r * 10**i); 22 | w(r * 10**-i); 23 | w(-r * 10**i); 24 | w(-r * 10**-i) 25 | end 26 | end. 27 | ----stdout 28 | +00+0000000 +00+000000000000000 29 | +00+1000000 +00+100000000000000 30 | +01+1000000 +01+100000000000000 31 | +01+1600000 +01+160000000000000 32 | +01+3200000 +01+320000000000000 33 | +102-9100000 +102-910000000000000 34 | -100+9100000 -100+910000000000000 35 | 36 | +00+1234568 +00+123456789012345 37 | +00+1234568 +00+123456789012345 38 | +00-1234568 +00-123456789012345 39 | +00-1234568 +00-123456789012345 40 | +01+1234568 +01+123456789012345 41 | -01+1234568 -01+123456789012345 42 | +01-1234568 +01-123456789012345 43 | -01-1234568 -01-123456789012345 44 | +02+1234568 +02+123456789012345 45 | -02+1234568 -02+123456789012345 46 | +02-1234568 +02-123456789012345 47 | -02-1234568 -02-123456789012345 48 | +03+1234568 +03+123456789012345 49 | -03+1234568 -03+123456789012345 50 | +03-1234568 +03-123456789012345 51 | -03-1234568 -03-123456789012345 52 | +04+1234568 +04+123456789012345 53 | -04+1234568 -04+123456789012345 54 | +04-1234568 +04-123456789012345 55 | -04-1234568 -04-123456789012345 56 | +05+1234568 +05+123456789012345 57 | -05+1234568 -05+123456789012345 58 | +05-1234568 +05-123456789012345 59 | -05-1234568 -05-123456789012345 60 | +06+1234568 +06+123456789012345 61 | -06+1234568 -06+123456789012345 62 | +06-1234568 +06-123456789012345 63 | -06-1234568 -06-123456789012345 64 | +07+1234568 +07+123456789012345 65 | -07+1234568 -07+123456789012345 66 | +07-1234568 +07-123456789012345 67 | -07-1234568 -07-123456789012345 68 | +08+1234568 +08+123456789012345 69 | -08+1234568 -08+123456789012345 70 | +08-1234568 +08-123456789012345 71 | -08-1234568 -08-123456789012345 72 | +09+1234568 +09+123456789012345 73 | -09+1234568 -09+123456789012345 74 | +09-1234568 +09-123456789012345 75 | -09-1234568 -09-123456789012345 76 | +10+1234568 +10+123456789012345 77 | -10+1234568 -10+123456789012345 78 | +10-1234568 +10-123456789012345 79 | -10-1234568 -10-123456789012345 80 | ----end. 81 | -------------------------------------------------------------------------------- /Tests/standard-transfer-roundtoreal.alw: -------------------------------------------------------------------------------- 1 | begin 2 | real array x (1::5); 3 | x(1) := -0.05459357; 4 | x(2) := 0.11644; 5 | x(3) := -0.01825297; 6 | x(4) := 0.5555555555555; 7 | x(5) := 0.3333333333333; 8 | for i := 1 until 5 do 9 | writeon(roundtoreal(x(i))); 10 | iocontrol(2); 11 | write("roundtoreal(0.5555555555555) ", roundtoreal(0.5555555555555)); 12 | write("roundtoreal(0.3333333333333) ", roundtoreal(0.3333333333333)); 13 | end. 14 | ----stdout 15 | -0.05459357 0.11644 -0.01825297 0.5555556 0.3333333 16 | roundtoreal(0.5555555555555) 0.5555556 17 | roundtoreal(0.3333333333333) 0.3333333 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/standard-transfer.alw: -------------------------------------------------------------------------------- 1 | begin 2 | assert truncate(+2.3) = +2; 3 | assert truncate(+2.5) = +2; 4 | assert truncate(+2.7) = +2; 5 | assert truncate(-2.3) = -2; 6 | assert truncate(-2.5) = -2; 7 | assert truncate(-2.7) = -2; 8 | 9 | assert entier(+2.3) = +2; 10 | assert entier(+2.5) = +2; 11 | assert entier(+2.7) = +2; 12 | assert entier(-2.3) = -3; 13 | assert entier(-2.5) = -3; 14 | assert entier(-2.7) = -3; 15 | 16 | assert round(+2.3) = +2; 17 | assert round(+2.5) = +3; 18 | assert round(+2.7) = +3; 19 | assert round(-2.3) = -2; 20 | assert round(-2.5) = -3; 21 | assert round(-2.7) = -3; 22 | 23 | assert odd(3); 24 | assert ~odd(2); 25 | assert odd(1); 26 | assert ~odd(0); 27 | assert odd(-1); 28 | 29 | assert number(#0) = 0; 30 | assert number(#1) = 1; 31 | assert number(#7FFFFFFF) = 2147483647; 32 | assert number(#7FFFFFFF) = maxinteger; 33 | assert number(#FFFFFFFF) = -1; 34 | 35 | assert bitstring(0) = #0; 36 | assert bitstring(1) = #1; 37 | assert bitstring(-1) = #FFFFFFFF; 38 | assert bitstring(2147483647) = #7FFFFFFF; 39 | assert bitstring(maxinteger) = #7FFFFFFF; 40 | 41 | assert decode(" ") = 64; COMMENT these are EBCDIC codes; 42 | assert decode("""") = 127; 43 | assert decode("~") = 161; 44 | assert code(64) = " "; 45 | assert code(127) = """"; 46 | assert code(161) = "~"; 47 | 48 | assert intbase10(0) = " +0000000000"; 49 | assert intbase10(1) = " +0000000001"; 50 | assert intbase10(-1) = " -0000000001"; 51 | assert intbase10(2147483647) = " +2147483647"; 52 | assert intbase10(-2147483647) = " -2147483647"; 53 | 54 | comment C itself doesn't like to see -2147483648; 55 | 56 | assert intbase16(0) = " 00000000"; 57 | assert intbase16(1) = " 00000001"; 58 | assert intbase16(-1) = " FFFFFFFF"; 59 | assert intbase16(2147483647) = " 7FFFFFFF"; 60 | assert intbase16(-2147483647) = " 80000001"; 61 | end. -------------------------------------------------------------------------------- /Tests/standard-write-eject-last-page.alw: -------------------------------------------------------------------------------- 1 | begin 2 | iocontrol(10014); % 14 character lines % 3 | iocontrol(20005); % 5 line pages % 4 | iocontrol(40005); % pretty_page_breaks % 5 | iocontrol(40011); % eject last page % 6 | for i := 1 until 6 do 7 | write(i) 8 | end. 9 | ----stdout 10 | 1 11 | 2 12 | 3 13 | 4 14 | 5 15 | ~~~~~~~~~~~~~~ 16 | 6 17 | 18 | 19 | 20 | 21 | ~~~~~~~~~~~~~~ 22 | ----end 23 | -------------------------------------------------------------------------------- /Tests/standard-write-example.alw: -------------------------------------------------------------------------------- 1 | begin 2 | procedure SCALED (integer value N); 3 | begin R_FORMAT := "S"; R_W := N+7 4 | end; 5 | procedure ALIGNED (integer value N,D); 6 | begin R_FORMAT := "A"; R_W := N+D+1; R_D := D 7 | end; 8 | procedure FREE_POINT (integer value N); 9 | begin R_FORMAT := "F"; R_W := N+7 10 | end; 11 | procedure NEW_LINE; IOCONTROL(2); 12 | 13 | FREE_POINT(5); I_W := 2; S_W := 1; 14 | 15 | for I := -1, 0, 32 do 16 | begin WRITE(S_W := 0, I, ":", NEW_LINE, I/3); 17 | WRITEON("I ", ALIGNED(3,2), I/3, "*", SCALED(12), I/3, "*") 18 | end 19 | end. 20 | ----stdout 21 | -1: 22 | -0.33333I -0.33 * -3.33333333333'-01 * 23 | 0: 24 | 0I 0.00 * 0 * 25 | 32: 26 | 10.667I 10.67 * 1.06666666667'+01 * 27 | ----end 28 | -------------------------------------------------------------------------------- /Tests/standard-write-i_w.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write(i_w := 0, 1); 3 | write(i_w := 1, 2); 4 | write(i_w := 2, 3); 5 | write(i_w := 3, 4); 6 | write(5); 7 | i_w := 3; 8 | write(6); 9 | i_w := 1; 10 | write(7, 8, 9); 11 | s_w := 0; 12 | i_w := 3; 13 | write(10, 11, 12); 14 | write(i_w := -5, 13, 14, 15); comment C allows this, maybe Algol W shouldn't; 15 | write(16, 17, 18); 16 | writeon(19); 17 | end. 18 | ----stdout 19 | 1 20 | 2 21 | 3 22 | 4 23 | 5 24 | 6 25 | 7 8 9 26 | 10 11 12 27 | 13 14 15 28 | 16 17 18 19 29 | ----end -------------------------------------------------------------------------------- /Tests/standard-write-line-wrap.alw: -------------------------------------------------------------------------------- 1 | comment this tests the lower extreme of line/page breaking; 2 | begin 3 | iocontrol(5); comment Hard page breaks are not on by default (Awe behaviour); 4 | iocontrol(40005); comment Pretty page breaks = on; 5 | 6 | s_w := 0; comment Write one digit at a time; 7 | i_w := 1; 8 | 9 | iocontrol(10001); comment Page width = 1; 10 | iocontrol(20001); comment Page height = 1; 11 | 12 | for i := 1 until 4 do 13 | writeon(i); 14 | 15 | iocontrol(2); comment Line break; 16 | 17 | iocontrol(10002); 18 | iocontrol(20002); 19 | 20 | for i := 1 until 8 do 21 | writeon(i); 22 | 23 | iocontrol(2); 24 | iocontrol(20003); 25 | writeon("ab"); 26 | writeon("cd"); 27 | end. 28 | ----stdout 29 | 1 30 | ~ 31 | 2 32 | ~ 33 | 3 34 | ~ 35 | 4 36 | ~ 37 | 12 38 | 34 39 | ~~ 40 | 56 41 | 78 42 | ~~ 43 | ab 44 | cd 45 | ----end 46 | -------------------------------------------------------------------------------- /Tests/standard-write-page-breaks-off.alw: -------------------------------------------------------------------------------- 1 | begin 2 | iocontrol(4); 3 | for i := 1 until 61 do 4 | write(i) 5 | end. 6 | ----stdout 7 | 1 8 | 2 9 | 3 10 | 4 11 | 5 12 | 6 13 | 7 14 | 8 15 | 9 16 | 10 17 | 11 18 | 12 19 | 13 20 | 14 21 | 15 22 | 16 23 | 17 24 | 18 25 | 19 26 | 20 27 | 21 28 | 22 29 | 23 30 | 24 31 | 25 32 | 26 33 | 27 34 | 28 35 | 29 36 | 30 37 | 31 38 | 32 39 | 33 40 | 34 41 | 35 42 | 36 43 | 37 44 | 38 45 | 39 46 | 40 47 | 41 48 | 42 49 | 43 50 | 44 51 | 45 52 | 46 53 | 47 54 | 48 55 | 49 56 | 50 57 | 51 58 | 52 59 | 53 60 | 54 61 | 55 62 | 56 63 | 57 64 | 58 65 | 59 66 | 60 67 | 61 68 | ----end -------------------------------------------------------------------------------- /Tests/standard-write-page-breaks.alw: -------------------------------------------------------------------------------- 1 | begin 2 | iocontrol(5); 3 | for i := 1 until 61 do 4 | write(i) 5 | end. 6 | ----stdout 7 | 1 8 | 2 9 | 3 10 | 4 11 | 5 12 | 6 13 | 7 14 | 8 15 | 9 16 | 10 17 | 11 18 | 12 19 | 13 20 | 14 21 | 15 22 | 16 23 | 17 24 | 18 25 | 19 26 | 20 27 | 21 28 | 22 29 | 23 30 | 24 31 | 25 32 | 26 33 | 27 34 | 28 35 | 29 36 | 30 37 | 31 38 | 32 39 | 33 40 | 34 41 | 35 42 | 36 43 | 37 44 | 38 45 | 39 46 | 40 47 | 41 48 | 42 49 | 43 50 | 44 51 | 45 52 | 46 53 | 47 54 | 48 55 | 49 56 | 50 57 | 51 58 | 52 59 | 53 60 | 54 61 | 55 62 | 56 63 | 57 64 | 58 65 | 59 66 | 60 61 67 | ----end -------------------------------------------------------------------------------- /Tests/standard-write-reference.alw: -------------------------------------------------------------------------------- 1 | comment Writing references; 2 | begin 3 | record x (integer i); 4 | record y (integer j); 5 | reference(x) a; 6 | reference(y) b; 7 | reference(x,y) c; 8 | reference(x,y) d, e; 9 | reference(x,y) f; 10 | a := x; 11 | b := y; 12 | c := y; 13 | d := c; 14 | e := null; 15 | write("These should be different: ", a, b); 16 | write("These should be the same: ", c, d); 17 | write("This should be ""null"": ", e); 18 | write("This should be ""UNINITIALIZED"":", f); 19 | end. 20 | ----stdout 21 | These should be different: x.1 y.2 22 | These should be the same: y.3 y.3 23 | This should be "null": null 24 | This should be "UNINITIALIZED": UNINITIALIZED 25 | ----end 26 | -------------------------------------------------------------------------------- /Tests/standard-writecard-error.alw: -------------------------------------------------------------------------------- 1 | begin 2 | writecard(1) 3 | end. 4 | ----compiler 5 | Tests/standard-writecard-error.alw:2:13: Expected a statement or string expression, this is an INTEGER expression 6 | ----end -------------------------------------------------------------------------------- /Tests/standard-writecard.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | string(8) four; 4 | four := "44444444"; 5 | write("*"); 6 | writecard("1", "2", i := 1, "33333", four); 7 | write("*"); 8 | 9 | comment "*" Should not be on the same line as "5", writecard writes entire lines; 10 | writecard("5"); 11 | writeon("*"); 12 | 13 | assert i = 1 14 | end. 15 | ----stdout 16 | * 17 | 1 18 | 2 19 | 33333 20 | 44444444 21 | * 22 | 5 23 | * 24 | ----end -------------------------------------------------------------------------------- /Tests/statements-assignment.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i, j; 3 | real r; 4 | 5 | i := j := 42; 6 | assert i = 42 and j = 42; 7 | 8 | r := j := 42; 9 | assert r = 42.0 and j = 42 10 | end. -------------------------------------------------------------------------------- /Tests/statements-block-empty.alw: -------------------------------------------------------------------------------- 1 | begin 2 | end. -------------------------------------------------------------------------------- /Tests/statements-block-out-of-scope.alw: -------------------------------------------------------------------------------- 1 | begin 2 | begin 3 | integer i; 4 | i := 1; 5 | end; 6 | assert i = 1; 7 | end. 8 | ----compile 9 | Tests/statements-block-out-of-scope.alw:6:12: 'i' is undefined here 10 | ----end -------------------------------------------------------------------------------- /Tests/statements-block-overshadowed-2.alw: -------------------------------------------------------------------------------- 1 | begin 2 | logical x; 3 | begin 4 | integer x; 5 | write(x and true); 6 | end; 7 | end. 8 | ----compile 9 | Tests/statements-block-overshadowed-2.alw:5:16: Incorrect operand types: INTEGER AND LOGICAL 10 | ----end -------------------------------------------------------------------------------- /Tests/statements-block-overshadowed-3.alw: -------------------------------------------------------------------------------- 1 | comment Labels and declarations share scope, 2 | declarations are added to the scope first 3 | to make the error messages more sensible; 4 | begin 5 | integer x; 6 | x: ; 7 | end. 8 | ----compile 9 | Tests/statements-block-overshadowed-3.alw:6:4: 'x' is already defined here, as an INTEGER variable 10 | ----end -------------------------------------------------------------------------------- /Tests/statements-block-overshadowed.alw: -------------------------------------------------------------------------------- 1 | begin 2 | x: begin 3 | integer x; 4 | goto x; 5 | end; 6 | end. 7 | ----compile 8 | Tests/statements-block-overshadowed.alw:4:8: 'x' should be a label here, it is an INTEGER variable 9 | ----end -------------------------------------------------------------------------------- /Tests/statements-block.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i, j; 3 | i := 1; 4 | j := 1; 5 | begin 6 | integer i; 7 | assert j = 1; 8 | i := 2; 9 | j := 2; 10 | assert i = 2; 11 | assert j = 2; 12 | end; 13 | assert i = 1; 14 | assert j = 2; 15 | end. -------------------------------------------------------------------------------- /Tests/statements-case-too-high.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 7 do 3 | case i of 4 | begin 5 | write(1); 6 | write(2); 7 | write(3); 8 | write(4); 9 | write(5); 10 | write(6) 11 | end 12 | end. 13 | ----stdout 14 | 1 15 | 6 16 | ----stderr 17 | Tests/statements-case-too-high.alw:3:7: CASE range error: selector is 7 18 | ----exitcode 19 | 1 20 | ----end 21 | -------------------------------------------------------------------------------- /Tests/statements-case-too-low.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 0 do 3 | case i of 4 | begin 5 | write(1); 6 | write(2); 7 | write(3); 8 | write(4); 9 | write(5); 10 | write(6); 11 | end 12 | end. 13 | ----stdout 14 | 1 15 | 6 16 | ----stderr 17 | Tests/statements-case-too-low.alw:3:7: CASE range error: selector is 0 18 | ----exitcode 19 | 1 20 | ----end 21 | -------------------------------------------------------------------------------- /Tests/statements-case.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1, 6, 5, 4 do 3 | case i of 4 | begin 5 | write(1); 6 | write(2); 7 | write(3); 8 | write(4); 9 | write(5); 10 | write(6); 11 | end 12 | end. 13 | ----stdout 14 | 1 15 | 6 16 | 5 17 | 4 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/statements-for-control-variable-scope.alw: -------------------------------------------------------------------------------- 1 | % The control variable should not clash with variables % 2 | % outside the FOR loop's scope, so it should be declared last. % 3 | % (Examine Awe C output to be sure that this is really happening.) % 4 | begin 5 | integer i; 6 | integer kk; 7 | i := 10; 8 | kk := 1; 9 | for i := i step 2 until 20 do 10 | write(i); 11 | assert i = 10; 12 | for i := i until 12 do 13 | write(i); 14 | i := 2; 15 | for i := 1 step i until i * 4 do 16 | write(i); 17 | end. 18 | ----stdout 19 | 10 20 | 12 21 | 14 22 | 16 23 | 18 24 | 20 25 | 10 26 | 11 27 | 12 28 | 1 29 | 3 30 | 5 31 | 7 32 | ----end 33 | -------------------------------------------------------------------------------- /Tests/statements-for-list.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 42; 4 | for i := 5 do 5 | write(i); 6 | for i := 1, 2, 4, 8 do 7 | write(i); 8 | assert(i = 42) 9 | end. 10 | ----stdout 11 | 5 12 | 1 13 | 2 14 | 4 15 | 8 16 | ----end -------------------------------------------------------------------------------- /Tests/statements-for-step-0.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1 step 0 until 8 do 3 | write(i); 4 | end. 5 | ----stderr 6 | Tests/statements-for-step-0.alw:2:5: FOR step of 0 7 | ----exitcode 8 | 1 9 | ----end -------------------------------------------------------------------------------- /Tests/statements-for-step.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 42; 4 | for i := 1 step 2 until 8 do 5 | write(i); 6 | for i := 8 step -2 until 1 do 7 | write(i); 8 | for i := 1 step -2 until 8 do comment shouldn't do anything; 9 | write(i); 10 | assert(i = 42) 11 | end. 12 | ----stdout 13 | 1 14 | 3 15 | 5 16 | 7 17 | 8 18 | 6 19 | 4 20 | 2 21 | ----end -------------------------------------------------------------------------------- /Tests/statements-for.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 42; 4 | for i := 1 until 4 do 5 | write(i); 6 | for i := 4 until 1 do 7 | write(i); 8 | assert(i = 42) 9 | end. 10 | ----stdout 11 | 1 12 | 2 13 | 3 14 | 4 15 | ----end -------------------------------------------------------------------------------- /Tests/statements-goto-scope.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 1; 4 | top: 5 | 6 | begin 7 | integer j, k; 8 | j := 1; 9 | top: 10 | k := 10 * i + j; 11 | write(k); 12 | j := j + 1; 13 | if j = 4 then goto bottom; 14 | if k = 32 then goto exit; 15 | go to top; 16 | bottom: 17 | end; 18 | 19 | i := i + 1; 20 | if i = 4 then goto bottom; 21 | go to top; 22 | bottom: 23 | exit: 24 | end. 25 | ----stdout 26 | 11 27 | 12 28 | 13 29 | 21 30 | 22 31 | 23 32 | 31 33 | 32 34 | ----end 35 | -------------------------------------------------------------------------------- /Tests/statements-goto-wrong-direction.alw: -------------------------------------------------------------------------------- 1 | begin 2 | for i := 1 until 4 do 3 | begin 4 | uh_oh: write(i); 5 | end; 6 | goto uh_oh 7 | end. 8 | ----compile 9 | Tests/statements-goto-wrong-direction.alw:6:5: 'uh_oh' is undefined here 10 | ----end -------------------------------------------------------------------------------- /Tests/statements-goto.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 8; 4 | top: 5 | write(i); 6 | i := i + 1; 7 | if i = 12 then goto bottom; 8 | go to top; 9 | bottom: 10 | end. 11 | ----stdout 12 | 8 13 | 9 14 | 10 15 | 11 16 | ----end 17 | -------------------------------------------------------------------------------- /Tests/statements-if.alw: -------------------------------------------------------------------------------- 1 | begin 2 | % this is okay % 3 | if true then 4 | if true then 5 | assert true; 6 | 7 | % this is okay % 8 | if true then 9 | if true then 10 | assert true 11 | else 12 | assert true; 13 | 14 | % this SHOULD not be okay (THEN followed by non , c.f. 7.5.1) % 15 | % but we are allowing it % 16 | if true then 17 | if true then 18 | assert true 19 | else 20 | assert true 21 | else 22 | assert true; 23 | end. 24 | -------------------------------------------------------------------------------- /Tests/statements-while-body-is-statement.alw: -------------------------------------------------------------------------------- 1 | begin 2 | while true do 3 | 1 4 | end. 5 | ----compile 6 | Tests/statements-while-body-is-statement.alw:3:9: expected a statement here, got an INTEGER 7 | ----end 8 | -------------------------------------------------------------------------------- /Tests/statements-while-is-statement.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := while true do 1 4 | end. 5 | ----compile 6 | Tests/statements-while-is-statement.alw:3:24: expected a statement here, got an INTEGER 7 | ----end 8 | -------------------------------------------------------------------------------- /Tests/statements-while.alw: -------------------------------------------------------------------------------- 1 | begin 2 | integer i; 3 | i := 1; 4 | while i <= 5 do 5 | begin 6 | write(i); 7 | i := i + 1 8 | end 9 | end. 10 | ----stdout 11 | 1 12 | 2 13 | 3 14 | 4 15 | 5 16 | ----end 17 | -------------------------------------------------------------------------------- /Tests/string-case.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(6) a1, a2, a3, s; 3 | 4 | procedure p (string(6) value x); 5 | begin 6 | x(0|1) := code(decode(x(0|1)) + 64); 7 | write(x); 8 | end; 9 | 10 | a1 := "a"; 11 | a2 := "b123"; 12 | a3 := "c12345"; 13 | for i := 1 until 3 do p(case i of (a1, a2, a3)); 14 | 15 | assert a1 = "a"; 16 | assert a2 = "b123"; 17 | assert a3 = "c12345"; 18 | 19 | for i := 1 until 3 do p(case i of ("a", "b123", "c12345")); 20 | end. 21 | ----stdout 22 | A 23 | B123 24 | C12345 25 | A 26 | B123 27 | C12345 28 | ----end 29 | -------------------------------------------------------------------------------- /Tests/string-character-order.alw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glynawe/awe/659346c6042ae10e5b544cd907ca9c7dcc38eec4/Tests/string-character-order.alw -------------------------------------------------------------------------------- /Tests/string-comparisions.alw: -------------------------------------------------------------------------------- 1 | begin 2 | assert("abc" = "abc"); 3 | assert("bce" > "abc"); 4 | assert("abc" < "bce"); 5 | 6 | assert("abc" ~= "abcd"); 7 | assert("abcd" > "abc"); 8 | assert("abc" < "abcd"); 9 | 10 | 11 | comment Spaces at the ends of strings do not count in comparisions; 12 | 13 | assert("abc" = "abc "); 14 | assert("bce " > "abc"); 15 | assert("abc " < "bce"); 16 | assert("bce" > "abc "); 17 | assert("abc" < "bce "); 18 | 19 | assert("abc " = "abc "); 20 | assert("bce " > "abc "); 21 | assert("abc " < "bce "); 22 | assert("bce " > "abc "); 23 | assert("abc " < "bce "); 24 | end. -------------------------------------------------------------------------------- /Tests/string-constants-non-printing.alw: -------------------------------------------------------------------------------- 1 | begin 2 | write("This non-printing character should not be accepted: "); 3 | end. 4 | ----compiler 5 | Tests/string-constants-non-printing.alw:2:10: This string contains a non-printing or non ISO 8859-1 character code 6 | ----end 7 | 8 | -------------------------------------------------------------------------------- /Tests/string-constants.alw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glynawe/awe/659346c6042ae10e5b544cd907ca9c7dcc38eec4/Tests/string-constants.alw -------------------------------------------------------------------------------- /Tests/string-result-parameters.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(4) procedure p ( string(4) value v; 3 | string(4) result r; 4 | string(4) value result vr; 5 | string(4) n ); 6 | begin 7 | r(0|2) := v(0|2); 8 | r(2|2) := vr(0|2); 9 | n(0|2) := v(0|2); 10 | vr := n; 11 | vr 12 | end; 13 | 14 | string(4) s, r0, vr0, n0; 15 | vr0 := "VVVV"; 16 | n0 := "nnnn"; 17 | s := p("vvvv", r0, vr0, n0); 18 | write(s, r0, vr0, n0) 19 | end. 20 | ----compile 21 | Tests/string-result-parameters.alw:5:28: Note, this is a call-by-name formal parameter. 22 | ----stdout 23 | vvnnvvVVvvnnvvnn 24 | ----end 25 | -------------------------------------------------------------------------------- /Tests/string-substring-1.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(5) s; 3 | string(1) c; 4 | procedure p(string(3) value x); 5 | x := "xxx"; 6 | 7 | string(5) procedure z; 8 | " "; 9 | 10 | string(1) procedure q(string(5) value x); 11 | begin x := "x"; x(0|1) end; 12 | 13 | string(1) procedure r(string(1) value x); 14 | begin x := "x"; x(0|1) end; 15 | 16 | 17 | s := "01234"; 18 | p(s(0|3)); 19 | assert(s = "01234"); 20 | 21 | c := "a"; 22 | s := c; 23 | s := q(c); 24 | s := q(s); 25 | s := q(s(0|1)); 26 | s := q(c(0|1)); 27 | s := q(" "); 28 | s := q(" "); 29 | 30 | c := r(c(0|1)); 31 | c := r(c); 32 | c := r(" "); 33 | s := r(c(0|1)); 34 | s := r(c); 35 | s := r(" "); 36 | 37 | c := " "; 38 | s := " "; 39 | s := c; 40 | s := z; 41 | s := begin s := z; " " end 42 | end. -------------------------------------------------------------------------------- /Tests/string-substring-all-of-length-1.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(10) s; 3 | s := "0123456789"; 4 | for i := 0 until 9 do 5 | write(s(i|1)) 6 | end. 7 | ----stdout 8 | 0 9 | 1 10 | 2 11 | 3 12 | 4 13 | 5 14 | 6 15 | 7 16 | 8 17 | 9 18 | ----end 19 | -------------------------------------------------------------------------------- /Tests/string-substring-assignment-off-end.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(10) s; 3 | s := "0123456789"; 4 | s(8|3) := "abc"; 5 | end. 6 | ----stderr 7 | Tests/string-substring-assignment-off-end.alw:4:4: Substring (8|3) of a string of length 10. 8 | ----exitcode 9 | 1 10 | ----end 11 | -------------------------------------------------------------------------------- /Tests/string-substring-assignment-too-long.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(10) s; 3 | s := "0123456789"; 4 | s(4|3) := "abcd"; 5 | write(s); 6 | end. 7 | ----compile 8 | Tests/string-substring-assignment-too-long.alw:4:4: a STRING(4) cannot be assigned to a STRING(3) variable 9 | ----end 10 | -------------------------------------------------------------------------------- /Tests/string-substring-assignment.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(10) s; 3 | 4 | s := "0123456789"; 5 | s(4|3) := "abc"; 6 | assert s = "0123abc789"; 7 | s(0|3) := "___"; 8 | assert s = "___3abc789"; 9 | s(6|4) := "????"; 10 | assert s = "___3ab????"; 11 | 12 | s := "0123456789"; 13 | s(3|5) := "ab"; 14 | assert s = "012ab 89"; 15 | end. -------------------------------------------------------------------------------- /Tests/string-substring-io.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(8) s; 3 | s := "01234567"; 4 | readcard(s(2|4)); 5 | assert(s = "01abcd67"); 6 | write(s(1|6)); 7 | end. 8 | ----stdin 9 | abcd 10 | ----stdout 11 | 1abcd6 12 | ----end 13 | -------------------------------------------------------------------------------- /Tests/string-substring-multiple-assignment.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(2) a, b; 3 | string(1) c; 4 | 5 | a := b := "ab"; 6 | assert(a = "ab"); 7 | assert(b = "ab"); 8 | 9 | c := b(1|1) := "2"; 10 | assert(c = "2"); 11 | assert(b = "a2"); 12 | 13 | a(1|1) := c := "3"; 14 | assert(c = "3"); 15 | assert(a = "a3"); 16 | 17 | a(1|1) := b(1|1) := "4"; 18 | assert(a = "a4"); 19 | assert(b = "a4"); 20 | end. 21 | -------------------------------------------------------------------------------- /Tests/string-substring-name-parameter.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(8) s; 3 | integer i; 4 | 5 | procedure p (string(4) x); 6 | begin 7 | assert(x = "0123"); 8 | i := 1; 9 | assert(x = "1234"); 10 | i := 2; 11 | x := "abcd"; 12 | assert(x = "abcd"); 13 | assert(s = "01abcd67") comment Eerie isn't it; 14 | end; 15 | 16 | s := "01234567"; 17 | i := 0; 18 | p(s(i|4)) 19 | end. 20 | ----compiler 21 | Tests/string-substring-name-parameter.alw:5:17: Note, this is a call-by-name formal parameter. 22 | ----end 23 | -------------------------------------------------------------------------------- /Tests/string-substring-of-short-string.alw: -------------------------------------------------------------------------------- 1 | comment In A2WC generated code Algol strings can be represented by C 2 | strings shorter than the string length. This happens when 3 | string variables are assigned constants. Let's see if the 4 | substring operators can handle that; 5 | begin 6 | string(6) a; 7 | string(6) b; 8 | 9 | a := "01"; 10 | assert(a(2|2) = " "); 11 | 12 | b := "01"; 13 | b(3|2) := "xx"; 14 | assert(b = "01 xx ") 15 | end. -------------------------------------------------------------------------------- /Tests/string-too-long.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(3) s; 3 | s := " "; 4 | s := "1"; 5 | s := "12"; 6 | s := "123"; 7 | s := "1234" 8 | end. 9 | ----compiler 10 | Tests/string-too-long.alw:7:4: a STRING(4) cannot be assigned to a STRING(3) variable 11 | ----end 12 | -------------------------------------------------------------------------------- /Tests/string-value-parameters.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(12) s; 3 | string(40) d; 4 | 5 | procedure p(string(40) value u); 6 | write("""", u, """"); 7 | 8 | procedure q(string(20) value v); 9 | write("""", v, """"); 10 | 11 | s := "Hello world!"; 12 | write(s); 13 | 14 | d := s; 15 | write(d); 16 | p(s); 17 | p(d); 18 | q(s); 19 | end. 20 | ----stdout 21 | Hello world! 22 | Hello world! 23 | "Hello world! " 24 | "Hello world! " 25 | "Hello world! " 26 | ----end 27 | -------------------------------------------------------------------------------- /Tests/string.alw: -------------------------------------------------------------------------------- 1 | begin 2 | string(12) s; 3 | s := "Hello world!"; 4 | write(s) 5 | end. 6 | ----stdout 7 | Hello world! 8 | ----end 9 | -------------------------------------------------------------------------------- /Tools/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile -- build, test and install Awe tools 2 | 3 | # This file is part of Awe. Copyright 2012 Glyn Webster. 4 | # 5 | # Awe is free software: you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License as published 7 | # by the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Awe is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public 16 | # License along with Awe. If not, see . 17 | 18 | 19 | # Where the file will be installed. Edit these to suit your system: 20 | 21 | PREFIX = $(DESTDIR)/usr/local 22 | BINDIR = $(PREFIX)/bin 23 | TOOLDIR = $(PREFIX)/share/awe 24 | MANDIR = $(PREFIX)/share/man/man1 25 | 26 | .phony:: build test install clean 27 | 28 | default: test 29 | 30 | install: build 31 | install -m 755 -d $(BINDIR) $(TOOLDIR) $(MANDIR) 32 | install -m 755 -t $(BINDIR) awnest 33 | install -m 644 -t $(MANDIR) awnest.1 34 | install -m 644 -t $(TOOLDIR) algolw.ssh 35 | 36 | build: 37 | ocamllex awnest.mll && ocamlc awnest.ml -o awnest 38 | 39 | test : clean build 40 | ./awnest < awnest-test-file.alw > actual.output 41 | diff --strip-trailing-cr expected.output actual.output 42 | rm actual.output 43 | echo "Success!" 44 | 45 | clean: 46 | rm -f awnest awnest.cmi awnest.cmo awnest.ml actual.output 47 | -------------------------------------------------------------------------------- /Tools/algolw.ssh: -------------------------------------------------------------------------------- 1 | # algolw.ssh -- `a2ps' style sheet for Algol W 2 | 3 | # a2ps --line-numbers=1 --pretty-print=./algolw.ssh -o 4 | # a2ps --line-numbers=1 --highlight-level=heavy --pretty-print=./algolw.ssh -o 5 | 6 | style AlgolW is 7 | requires a2ps 4.13 8 | written by "Glyn Webster" 9 | version is 1.0 10 | documentation is 11 | "This style highlights Algol W. Keywords are always printed in" 12 | "lowercase. Heavy pretty-printing gives you the mathematical symbols" 13 | "used in 'A Contribution to the Development of Algol' (except for the" 14 | "subscript 10 symbol)." 15 | end documentation 16 | 17 | first alphabet is "abcdefghijklmnopqrstuvwxyz" 18 | second alphabet is "abcdefghijklmnopqrstuvwxyz0123456789_" 19 | case insensitive 20 | 21 | keywords in Keyword_strong are 22 | "algol" "algol", 23 | "and" "and", 24 | "array" "array", 25 | "assert" "assert", 26 | "begin" "begin", 27 | "bits" "bits", 28 | "case" "case", 29 | "complex" "complex", 30 | "div" "div", 31 | "do" "do", 32 | "else" "else", 33 | "end" "end", 34 | "false" "false", 35 | "for" "for", 36 | "fortran" "fortran", 37 | "goto" "goto", 38 | "if" "if", 39 | "integer" "integer", 40 | "is" "is", 41 | "logical" "logical", 42 | "long" "long", 43 | "null" "null", 44 | "of" "of", 45 | "or" "or", 46 | "procedure" "procedure", 47 | "real" "real", 48 | "record" "record", 49 | "reference" "reference", 50 | "rem" "rem", 51 | "result" "result", 52 | "shl" "shl", 53 | "short" "short", 54 | "shr" "shr", 55 | "step" "step", 56 | "string" "string", 57 | "then" "then", 58 | "true" "true", 59 | "until" "until", 60 | "value" "value", 61 | "while" "while", 62 | /(go[\\t ]*to)/ 63 | end keywords 64 | 65 | operators are 66 | (~= \not,"="), 67 | ~ \not 68 | end operators 69 | 70 | optional keywords are 71 | "and" \wedge, 72 | "or" \vee, 73 | "shl" \uparrow, 74 | "shr" \downarrow, 75 | "div" \div 76 | end keywords 77 | 78 | optional operators are 79 | # * \times, 80 | ** \uparrow, 81 | <= \leq, 82 | >= \geq, 83 | ~= \neq 84 | end operators 85 | 86 | sequences are 87 | "comment" Comment Comment ";" Plain, 88 | "%" Comment Comment ";" Plain, 89 | "%" Comment Comment "%" Plain, 90 | "@" Comment Comment /$/ Plain, 91 | 92 | # String and character constants (Quotes are escaped by doubling them): 93 | "\"" Plain 94 | Plain 95 | "\"" Plain 96 | exceptions are "\"\"" end exceptions 97 | end sequences 98 | 99 | end style 100 | -------------------------------------------------------------------------------- /Tools/awnest-test-file.alw: -------------------------------------------------------------------------------- 1 | BEGIN 2 | 3 | PROCEDURE ROMAN (INTEGER VALUE NUMBER; STRING(15) RESULT CHARACTERS; INTEGER RESULT LENGTH); 4 | COMMENT 5 | Returns the Roman number of an integer between 1 and 3999. 6 | "MMMDCCCLXXXVIII" (15 characters long) is the longest Roman number under 4000; 7 | BEGIN 8 | INTEGER PLACE, POWER; 9 | 10 | PROCEDURE APPEND (STRING(1) VALUE C); 11 | BEGIN CHARACTERS(LENGTH|1) := C; LENGTH := LENGTH + 1 END; 12 | 13 | PROCEDURE I; APPEND(CASE PLACE OF ("I","X","C","M")); 14 | PROCEDURE V; APPEND(CASE PLACE OF ("V","L","D")); 15 | PROCEDURE X; APPEND(CASE PLACE OF ("X","C","M")); 16 | 17 | ASSERT (NUMBER >= 1) AND (NUMBER < 4000); 18 | 19 | CHARACTERS := " "; 20 | LENGTH := 0; 21 | POWER := 1000; 22 | PLACE := 4; 23 | WHILE PLACE > 0 DO 24 | BEGIN 25 | CASE NUMBER DIV POWER + 1 OF BEGIN 26 | BEGIN END; 27 | BEGIN I END; 28 | BEGIN I; I END; 29 | BEGIN I; I; I END; 30 | BEGIN I; V END; 31 | BEGIN V END; 32 | BEGIN V; I END; 33 | BEGIN V; I; I END; 34 | BEGIN V; I; I; I END; 35 | BEGIN I; X END 36 | END; 37 | NUMBER := NUMBER REM POWER; 38 | POWER := POWER DIV 10; 39 | PLACE := PLACE - 1 40 | END 41 | END ROMAN; 42 | 43 | INTEGER I; 44 | STRING(15) S; 45 | 46 | ROMAN(1, S, I); WRITE(S, I); 47 | ROMAN(3999, S, I); WRITE(S, I); 48 | ROMAN(3888, S, I); WRITE(S, I); 49 | ROMAN(2009, S, I); WRITE(S, I); 50 | ROMAN(405, S, I); WRITE(S, I); 51 | 52 | @AWE_TEXT 53 | 54 | Ignore this rubbish, it is commented out. 55 | PROCEDURE ROMAN (INTEGER VALUE NUMBER; STRING(15) RESULT CHARACTERS; INTEGER RESULT LENGTH); 56 | COMMENT 57 | Returns the Roman number of an integer between 1 and 3999. 58 | "MMMDCCCLXXXVIII" (15 characters long) is the longest Roman number under 4000; 59 | BEGIN 60 | 61 | @AWE_CODE 62 | 63 | END. 64 | -------------------------------------------------------------------------------- /Tools/awnest.1: -------------------------------------------------------------------------------- 1 | .TH awnest 1 "2012-06-01" "awnest" "Algol W source code lister" 2 | .SH "NAME" 3 | awnest \- line number and block-level lister for the Algol W language 4 | .SH "SYNOPSIS" 5 | \fBawnest\fR < \fIsource.alw\fR > \fIlisting.text\fR 6 | .SH "DESCRIPTION" 7 | This produces a source code listing of an Algol W program with 8 | line numbers and block levels in columns on left. 9 | (The block level is the number of unclosed BEGINs that preceed the line.) 10 | .PP 11 | Legacy code source can be quite densely packed (perhaps to save punch cards) 12 | so this kind of listing can be very useful. 13 | .SH "VERSION" 14 | 1.0 15 | .SH "COPYRIGHTS" 16 | Copyright 2012 by Glyn Webster. 17 | .PP 18 | alnest is free software: you can redistribute it and/or modify it under 19 | the terms of the GNU General Public License and Lesser GNU General 20 | Public License as published by the Free Software Foundation, either 21 | version 3 of the License, or (at your option) any later version. 22 | .SH "SEE ALSO" 23 | .PP 24 | \fIawe\fR\|(1) 25 | \fIAlgol W Language Description, June 1972\fR 26 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2024-12 Version -------------------------------------------------------------------------------- /algolw.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glynawe/awe/659346c6042ae10e5b544cd907ca9c7dcc38eec4/algolw.pdf -------------------------------------------------------------------------------- /awe.mk: -------------------------------------------------------------------------------- 1 | # awe.mk -- General purpose Makefile for Algol W programs. 2 | 3 | # See man page awe.mk(7) 4 | 5 | #Cygwin's libgc library (cygwin 1.7.16-1, libgc-devel 7.1-1) does not 6 | #currently work with Awe, it issues warnings and corrupts memory, so 7 | #'libawe.a' is not linked to 'libgc' on Cygwin. 8 | # 9 | ifeq ($(shell uname -o),Cygwin) 10 | $(warning "This is Cygwin, so not linking your program to 'libgc'.") 11 | LDLIBS += -lawe -lm 12 | else 13 | LDLIBS += -lawe -lm -lgc 14 | endif 15 | 16 | # Awe programs require an executable stack for call-by-name 17 | # "-z execstack" suppresses a warning from the GCC linker 18 | # See: https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments 19 | # 20 | CFLAGS += -z execstack 21 | LDFLAGS += -z execstack 22 | 23 | ifdef COMPILER_PATH 24 | CFLAGS += -I$(COMPILER_PATH) -L$(COMPILER_PATH) 25 | AWE=$(COMPILER_PATH)/awe 26 | else 27 | AWE=awe 28 | endif 29 | 30 | ifndef DISTNAME 31 | DISTNAME = $(shell basename `pwd`) 32 | endif 33 | 34 | .PHONY: default build clean test dist 35 | 36 | # default rule: 37 | build: Makefile $(PROGRAM) 38 | 39 | $(PROGRAM) : $(PROGRAM).awe.c $(PROGRAM).awe.h $(C_SOURCES) $(C_INCLUDES) 40 | gcc $(CFLAGS) $(C_SOURCES) $(PROGRAM).awe.c $(LDLIBS) -o $(PROGRAM) 41 | 42 | $(PROGRAM).awe.c $(PROGRAM).awe.h : $(ALGOLW_SOURCES) 43 | $(AWE) $(AWE_FLAGS) $(ALGOLW_SOURCES) -c $(PROGRAM).awe.c > $(PROGRAM).awe.h 44 | 45 | clean:: 46 | rm -f $(PROGRAM) $(PROGRAM).awe.c $(PROGRAM).awe.h $(DISTNAME).tar.gz 47 | 48 | # Tar the files with the program's name as a directory prefix. 49 | # 50 | # /$(sort ...)' = sort and remove duplicate file names (the latter is important) 51 | # 52 | # '--transform=...' = edit the path names going into 'tar' using 'sed' 53 | # 54 | ALL_FILES = $(sort $(wildcard Makefile $(ALGOLW_SOURCES) $(C_SOURCES) $(C_INCLUDES) $(EXTRA_FILES))) 55 | dist: 56 | rm -f $(DISTNAME).tar.gz 57 | tar --create --gzip \ 58 | --no-recursion \ 59 | --transform "s|^|$(DISTNAME)/|" \ 60 | --file $(DISTNAME).tar.gz $(ALL_FILES) 61 | #end 62 | -------------------------------------------------------------------------------- /class.ml: -------------------------------------------------------------------------------- 1 | (* class.mli -- record class identifiers 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | (* Record classes are identified by their index in a global class 23 | array. Awe must give record classes unique C identifiers because C 24 | structure definitions are always global. *) 25 | 26 | type t = int 27 | 28 | let compare a b = a - b 29 | 30 | let exception_class = (Table.Id.create "_awe_class_0_exception", "exception") 31 | 32 | let global_class_array = DynArray.create (Table.Id.dummy, "") 33 | 34 | let create loc id = 35 | let name = Table.Id.to_string id in 36 | let number = DynArray.length global_class_array in 37 | let global_id = Table.Id.create (Printf.sprintf "_awe_class_%i_%s" number name) in 38 | DynArray.add global_class_array (global_id, name) ; 39 | number 40 | 41 | let to_id c = fst (DynArray.get global_class_array c) 42 | 43 | let to_string c = snd (DynArray.get global_class_array c) 44 | 45 | let contents () = DynArray.to_list global_class_array 46 | 47 | 48 | 49 | (* end *) 50 | -------------------------------------------------------------------------------- /class.mli: -------------------------------------------------------------------------------- 1 | (* class.mli -- record class identifiers 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | 23 | (* Record classes need unique global C identifiers. This module generates them. *) 24 | 25 | type t 26 | 27 | val compare : t -> t -> int 28 | 29 | val create : Location.t -> Table.Id.t -> t 30 | 31 | val to_id : t -> Table.Id.t 32 | 33 | val to_string : t -> string (* the C identifier for the class *) 34 | 35 | val contents : unit -> (Table.Id.t * string) list 36 | 37 | (* end *) 38 | -------------------------------------------------------------------------------- /code.mli: -------------------------------------------------------------------------------- 1 | (* code.ml 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | (* Rapidly concatenatable scraps of C code text. *) 23 | 24 | (* A scrap of C code. *) 25 | type t 26 | 27 | val empty : t 28 | 29 | (* 'string s' converts the string 's' to a scrap. *) 30 | val string : string -> t 31 | 32 | val id : Table.Id.t -> t 33 | 34 | val to_string : t -> string 35 | 36 | 37 | (* 'separate seperator scrap_list' concatenates a list of C code scraps, 38 | using the string 'separator' as a separator. *) 39 | val separate : string -> t list -> t 40 | 41 | 42 | val concat : t list -> t 43 | val add : t -> t -> t 44 | 45 | (* Adds two code scraps with a comma between them. 46 | But if either of the scraps is empty the separator is not used. *) 47 | 48 | val add_with_comma : t -> t -> t 49 | 50 | (* 'template template scrap_list' makes a C code scrap, replacing '$' 51 | signs in 'template' with C code scraps from 'scrap_list'. *) 52 | val template : string -> t list -> t 53 | 54 | (* 'output_code channel scrap' outputs 'scrap' to 'channel' as a string. *) 55 | val output_code : out_channel -> t -> unit 56 | 57 | (* 'is_empty scrap' returns true if 'scrap' represents an empty string. *) 58 | val is_empty : t -> bool 59 | 60 | (* end *) 61 | -------------------------------------------------------------------------------- /dynArray.ml: -------------------------------------------------------------------------------- 1 | (* dynArray.ml 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | type 'a t = { 23 | mutable length : int; 24 | mutable arr : 'a array; 25 | filler : 'a 26 | } 27 | 28 | let initial_size = 20 29 | 30 | let create filler = 31 | { length = 0; 32 | arr = Array.make initial_size filler; 33 | filler = filler } 34 | 35 | let get a i = Array.get a.arr i 36 | 37 | let add a element = 38 | let len = Array.length a.arr in 39 | if len = a.length then 40 | a.arr <- Array.append a.arr (Array.make len a.filler) ; (* double the array length *) 41 | Array.set a.arr a.length element ; 42 | a.length <- a.length + 1 43 | 44 | let length a = a.length 45 | 46 | let to_list (a : 'a t) : 'a list = 47 | let xs = ref [] in 48 | for i = a.length - 1 downto 0 do 49 | xs := a.arr.(i) :: !xs 50 | done ; 51 | !xs 52 | 53 | (* end *) 54 | 55 | -------------------------------------------------------------------------------- /dynArray.mli: -------------------------------------------------------------------------------- 1 | (* dynArray.mli -- An array that grows when elements are added to the end. 2 | 3 | A newly created DynArray.t has no elements. 4 | 5 | -- 6 | 7 | This file is part of Awe. Copyright 2012 Glyn Webster. 8 | 9 | Awe is free software: you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published 11 | by the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Awe is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public 20 | License along with Awe. If not, see . 21 | 22 | *) 23 | 24 | type 'a t 25 | 26 | val create : 'a -> 'a t (* the parameter is a dummy *) 27 | val get : 'a t -> int -> 'a 28 | val add : 'a t -> 'a -> unit 29 | val length : 'a t -> int 30 | val to_list : 'a t -> 'a list 31 | 32 | (* end *) 33 | 34 | -------------------------------------------------------------------------------- /email_address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glynawe/awe/659346c6042ae10e5b544cd907ca9c7dcc38eec4/email_address.png -------------------------------------------------------------------------------- /htmltext.py: -------------------------------------------------------------------------------- 1 | #!/usr/env python3 2 | 3 | template = ''' 4 | 5 | 6 | %s 7 | 8 | 9 |
%s
10 | 11 | 12 | ''' 13 | 14 | from sys import stdout, stdin, argv 15 | from html import escape 16 | 17 | stdout.write(template % (escape(argv[1]), escape(stdin.read()))) 18 | -------------------------------------------------------------------------------- /location.ml: -------------------------------------------------------------------------------- 1 | (* location.ml 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | type source_t = { file_name : string; 23 | file_number : int } 24 | 25 | type t = { source : source_t; 26 | line : int; 27 | column : int } 28 | 29 | let filename loc = loc.source.file_name 30 | let file_number loc = loc.source.file_number 31 | let line loc = loc.line 32 | let column loc = loc.column 33 | 34 | let to_string loc = 35 | Printf.sprintf "%s:%i:%i:" (filename loc) (line loc) (column loc + 1) 36 | 37 | 38 | let sources : (string, source_t) Hashtbl.t = Hashtbl.create 20 39 | 40 | let source_list : source_t list ref = ref [] 41 | 42 | 43 | let source_files () = List.map (function source -> source.file_name) !source_list 44 | 45 | 46 | let create_source file_name = 47 | try 48 | Hashtbl.find sources file_name 49 | with Not_found -> 50 | let file_number = List.length !source_list in 51 | let source = {file_name; file_number} in 52 | source_list := !source_list @ [source] ; 53 | Hashtbl.add sources file_name source ; 54 | source 55 | 56 | 57 | let current_source : source_t ref = 58 | let stdin_source = create_source "" in 59 | ref stdin_source 60 | 61 | 62 | let set_source filename = 63 | let source = create_source filename in 64 | current_source := source 65 | 66 | 67 | let create filename line column = 68 | let source = create_source filename in 69 | {source; line; column} 70 | 71 | 72 | let of_position (position : Lexing.position) : t = 73 | let source = !current_source in 74 | let line = position.Lexing.pos_lnum in 75 | let column = position.Lexing.pos_cnum - position.Lexing.pos_bol in 76 | {source; line; column} 77 | 78 | (* end *) 79 | -------------------------------------------------------------------------------- /location.mli: -------------------------------------------------------------------------------- 1 | (* location.mli -- Algol W source code locations, for runtime error messages 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | type t 23 | 24 | val filename : t -> string 25 | val file_number : t -> int 26 | val line : t -> int 27 | val column : t -> int 28 | 29 | val source_files : unit -> string list (* The names of all the source files, in file_number order. *) 30 | 31 | val set_source : string -> unit (* set a source file name as the one for error reports, 32 | appends a new source file to list of sources in needed *) 33 | 34 | val create : string -> int -> int -> t (* Create from source file, line number and column number. *) 35 | 36 | val of_position : Lexing.position -> t 37 | 38 | val to_string : t -> string (* Convert to an Emacs-compatible source code location string *) 39 | 40 | (* end *) 41 | -------------------------------------------------------------------------------- /man.py: -------------------------------------------------------------------------------- 1 | #!/usr/env python3 2 | # man.py -- very simple markup preprocessor for man pages 3 | 4 | import re, time, sys 5 | 6 | def usage(): 7 | print('''usage: python3 man.py manpage.1.md manpage.1 MACRO=value... 8 | 9 | This is a rough preprocessor to convert a subset of Markdown to man pages. 10 | 11 | A summary of the markup commands you can use in your src file: 12 | 13 | # TITLE 1 / program name / short program description 14 | 15 | ## heading 16 | *itatics* 17 | **bold** 18 | `monospace` 19 | {{MACRO}} 20 | 21 | ``` 22 | example code block 23 | ``` 24 | 25 | definition 26 | : description 27 | ''') 28 | sys.exit(1) 29 | 30 | if len(sys.argv) < 3: usage() 31 | 32 | macros = {'DATE': time.strftime("%Y-%m-%d"), 33 | 'YEAR': time.strftime("%Y")} 34 | for arg in sys.argv[3:]: 35 | m = re.match(r'([A-Z][A-Za-z0-9_]+)=(.*)', arg) 36 | if m: 37 | macros[m.group(1)] = m.group(2) 38 | else: 39 | usage() 40 | 41 | repls = [ 42 | (r'^###? +(.+?)$', r'.SH "\1"'), # ## heading 43 | (r'\*\*(.+?)\*\*', r'\\fB\1\\fR'), # **bold** 44 | (r'\*(.+?)\*', r'\\fI\1\\fR'), # *itatics* 45 | (r'`(.+?)`', r'\\fI\1\\fR'), # `monospace` 46 | ('^(.+?) *\n: +', '\n.TP\n.B \\1\n'), # definition 47 | (r'^# +(.+?) */ *(.+?) */ *(.+?) *$', 48 | r'.TH \1 "{{DATE}}" "\2" "\3"'), # man page heading 49 | (r'{{(.+?)}}', 50 | lambda m: macros[m.group(1)]) ] # {{macro}} substitution 51 | 52 | 53 | with open(sys.argv[1], "r") as f: 54 | page = f.read() 55 | 56 | # split into text and code example sections, 57 | # odd-numbered sections will be code: 58 | sections = re.split('```[A-Za-z]*', page) 59 | 60 | with open(sys.argv[2], "w") as f: 61 | for i, s in enumerate(sections): 62 | if i % 2 == 0: # text section 63 | for pattern, repl in repls: 64 | s = re.sub(pattern, repl, s, flags=re.MULTILINE) 65 | else: # code section 66 | s = s.replace('\n', '\n ') 67 | s = '\n.nf\n' + s + '\n.fi\n' 68 | f.write(s) 69 | -------------------------------------------------------------------------------- /markdown-to-html.py: -------------------------------------------------------------------------------- 1 | ''' markdown-to-html.py -- convert a Markdown file to an HTML page''' 2 | 3 | # The HTML page will require 'github-markdown.css' from 4 | # https://github.com/sindresorhus/github-markdown-css 5 | # 6 | # The Markdown file must contain a top-level heading 7 | 8 | from pathlib import Path 9 | from sys import argv 10 | from markdown import markdown 11 | from html import escape 12 | import re 13 | 14 | markdown_text = Path(argv[1]).read_text() 15 | html_file = Path(argv[2]) 16 | 17 | html = markdown(markdown_text, extensions=['extra', 'toc']) 18 | title = escape(re.search(r'^# +(.+) *$', markdown_text, re.MULTILINE).group(1)) 19 | 20 | html_file.write_text(''' 21 | 22 | 23 | 24 | 25 | 26 | %s 27 | 28 | 29 | 30 | 31 | 40 | 41 | 42 |
43 | %s 44 |
45 | 46 | ''' % (title, html)) 47 | -------------------------------------------------------------------------------- /options.ml: -------------------------------------------------------------------------------- 1 | (* options.ml --- Awe compiler options. *) 2 | 3 | let initialize_all = ref true 4 | let add_tracing_hooks = ref false 5 | -------------------------------------------------------------------------------- /scope.ml: -------------------------------------------------------------------------------- 1 | (* scope.ml 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | 23 | exception Undefined of Table.Id.t 24 | 25 | exception Redefined of Table.Id.t * Type.definition_t 26 | 27 | 28 | module Local = 29 | struct 30 | type t = Type.definition_t Table.IdMap.t 31 | 32 | let empty = Table.IdMap.empty 33 | 34 | let get block id = 35 | try 36 | Some (Table.IdMap.find id block) 37 | with 38 | Not_found -> None 39 | 40 | let set block id defn = 41 | try 42 | let existing_defn = Table.IdMap.find id block in 43 | raise (Redefined (id, existing_defn)) 44 | with Not_found -> 45 | Table.IdMap.add id defn block 46 | 47 | let redefine block id defn = 48 | Table.IdMap.add id defn (Table.IdMap.remove id block) 49 | 50 | let fold = Table.IdMap.fold 51 | end 52 | 53 | 54 | type t = Local.t list 55 | 56 | 57 | let empty = [Local.empty] 58 | 59 | 60 | let push scope = Local.empty :: scope 61 | 62 | 63 | let pop = 64 | function 65 | | [] -> failwith "Scope.pop: this popped the global scope." 66 | | _ :: outer_scope -> outer_scope 67 | 68 | 69 | let rec get scope id = 70 | match scope with 71 | | [] -> raise (Undefined id) 72 | | local_block :: global_scope -> 73 | match Local.get local_block id with 74 | | Some defn -> defn 75 | | None -> get global_scope id 76 | 77 | 78 | let set scope id defn = 79 | match scope with 80 | | [] -> failwith "This should never happen." 81 | | local_block :: global_scope -> 82 | Local.set local_block id defn :: global_scope 83 | 84 | let redefine scope id defn = 85 | match scope with 86 | | [] -> failwith "This should never happen." 87 | | local_block :: global_scope -> 88 | Local.redefine local_block id defn :: global_scope 89 | 90 | (* end*) 91 | -------------------------------------------------------------------------------- /table.mli: -------------------------------------------------------------------------------- 1 | (* table.mli 2 | 3 | -- 4 | 5 | This file is part of Awe. Copyright 2012 Glyn Webster. 6 | 7 | Awe is free software: you can redistribute it and/or modify it 8 | under the terms of the GNU General Public License as published 9 | by the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Awe is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public 18 | License along with Awe. If not, see . 19 | 20 | *) 21 | 22 | (* The global symbol table. *) 23 | 24 | (* Algol W identifiers. These are case insensitive, but they are always output in lowercase. 25 | This interface is compatible with 'Set.OrderedType' and 'Hashtbl.HashableType'. 26 | *) 27 | module Id : sig 28 | 29 | (* An identifier in an Algol W program. *) 30 | type t 31 | 32 | (* 'create string' creates a new identifier from an identifier string *) 33 | val create : string -> t 34 | 35 | (* 'to_string identifier' returns the string representation of an identifier. 36 | Returns the identifier as a lowercase string *) 37 | val to_string : t -> string 38 | 39 | (* Returns the string representation of an identifier, with a "_" appended 40 | if it would clash with GNU C's reserved words or global identifiers. *) 41 | val to_C_id_string : t -> string 42 | 43 | val hash : t -> int 44 | val compare : t -> t -> int 45 | val eq : t -> t -> bool 46 | 47 | val dummy : t (* an identifer that is never used *) 48 | end 49 | 50 | 51 | (* Maps of identifiers to any type. Used in Scope module. *) 52 | module IdMap : Map.S with type key = Id.t 53 | 54 | 55 | (* end *) 56 | --------------------------------------------------------------------------------