Rutgers ALGOL 68

From Rosetta Code
Rutgers ALGOL 68 is an implementation of ALGOL 68. Other implementations of ALGOL 68.
This page is a stub. It needs more information! You can help Rosetta Code by filling it in!

Rutgers University Algol 68 Interpreter - runs under WIndows, Linux and DOS





Not all the exotic features are implemented. In particular there are no semaphores, formats and parallel-clauses.

The manual included with the interpreter details the restrictons, some of those that would affect some of the RC samples are listed here and in the Transput section.

long and short modes are not implemented and will cause errors to be reported, if used.
The stadard prelude has a number of ommissions, particularly transput - see below.
There are no pragmats (using pr or pragma will cause an error message to be issued) and hence no file inclusion.

Lexical style

Rutgers ALGOL 68 is case-sensitive and uses quote-stropping. The standard bold-words are in lower case, e.g.:

'begin'
    print( ( "Hello, World!", newline ) )
'end'

Transput

The restrictions Rutgers Algol68 places on the language and prelude are described in the manual. The following highlights some of the differences that are likely to affect running the RC samples with Rutgers Algol 68.

Only the standard input and standard ouptut channels are supported. The transput event routines (on logical file end etc.) are not implemented. Formatted transput is not implemented.

There are a number of differences in the formatting of items output by print/write.

The read procedure handles char and string items differently to the standard.
read( ( c ) ), where c is a char item gets the next character from standard input - c is set to repr 10 at end of line.
read( ( s ) ), where s is a string item does not change the bounds of s, it reads as many characters as are currently contained in s, - so string s; read( ( s, newline ) ) won't read anything into s as its bounds will be 1:0 at that point.

Building and running under Windows


To build under Windows, download the Linux version from the above link and unpack to a suitable folder (e.g. \algol\RutgersAlgol68 is assumed here), this will be refered to as the installation folder in the following. Place the following batch file into the the folder and execute it. The batch file asumes TCC is being used as the C compiler, change as appropriate. The DEFINES and ALINC variables may also need to be changed.

rem build.bat: build the Linux version of RutgersAlgol68 under Windows

rem set CC and DEFINES as appropriate for your C compiler
rem if your compiler does not come with include/sys/times.h, set ALINC=-I..\.. to include the dummy times.h
rem if your compiler does have a include/sys/times/.h, set ALINC=
rem the following are for tcc ( tested with version 0.9.26 (i386 Win32) )

set CC=\tcc\tcc
set DEFINES=
set ALINC=-I..\..

if not exist bin mkdir bin
del          bin\*.exe
del          bin\_prelude_

cd src

%CC%         %DEFINES%    prelude.c       -o ..\bin\prelude.exe
..\bin\prelude.exe  ..\bin\_prelude_       > ..\prelude.out

%CC%         %DEFINES%    textual_error.c -o ..\bin\textual_error.exe
%CC%         %defines%    dump.c          -o ..\bin\dump.exe

cd al
%CC% %ALINC% %DEFINES%    algol.c clauses.c coercion.c declaration.c declarer.c error.c init.c primary.c repr.c routine_call.c standard.c transput.c unit.c -o ..\..\bin\al.exe
cd ..

cd la
%CC%         %DEFINES%    lalgol.c data.c hash.c io.c symbol.c -o ..\..\bin\la.exe
cd ..

cd ..

Note that the interpreter requires <sys/times.h>, the TCC compiler used in the batch file above did not have one, the following dummy times.h can be used. If needed it should be placed in a sub-folder of the installation folder, called sys.

// times.h for RutgersAlgol68 - not a real timss.h
#include <time.h>
#define times(x) (unsigned) time(x)
// end RutgersAlgol68 times.h

The following batch file can be used to execute the interpreter with an upper-stropping source (as used by most of the samples on RC):

@rem u68.bat: execute an upper-stropping Algol 68 source using Rutgers Algol 68
@
@set  p=%1
@set o2=%2
@
@rem %p%: program source, o2: -l to suppress listing
@
@if not exist %p% @if exist %p%.a68 @set p=%p%.a68
@if not exist %p% @echo %p% not found.
@if not exist %p% @exit /b 7
@
@set rDir=%RUTGERS_HOME%
@if %rDir%. == . @set rDir=\algol\RutgersAlgol68
@set rBin=%rDir%\bin
@set preludeR=%rBin%\_prelude_
@
@rem construct a temporary source with the additional prelude and postlude added
@rem the postlude ends with ^E^O^F which upperToQoute needs to recognise EOF
@rem as Rutgers Algol 68 does not support transput event routines
@
@type %rDir%\prelude.r68         > _.tmp
@type %p%                       >> _.tmp
@type %rDir%\postlude.r68       >> _.tmp
@
@rem convert the temporary upper-stropping source to Rutgers-style quote-stropping
@%rBin%\la.exe                                _.lst _.b68 %rDir%\upperToQuote.r68
@if errorlevel 1 @goto :preError
@%rBin%\al.exe                     %preludeR% _.lst _.b68 _.d68  < _.tmp -l > _.u68
@if errorlevel 1 @goto :preError
@
@if exist _.lst @del _.lst
@if exist _.b68 @del _.b68
@if exist _.d68 @del _.d68
@
@%rBin%\la.exe                                _.lst _.b68       _.u68
@if errorlevel 1 @exit /b 7
@
@%rBin%\al.exe                     %preludeR% _.lst _.b68 _.d68 %o2%
@if errorlevel 1 @goto :runError
@   del                                       _.lst _.b68 _.d68 _.u68
@   goto :endR68
@:preError
@   echo Error pre-processing %p%
@   %rBin%\textual_error.exe   _.d68
@   exit /b 7
@:runError
@   %rBin%\textual_error.exe                              _.d68
@   %rBin%\dump.exe                                       _.d68
@   exit /b 7
@:endR68

The prelude.r68, postlude.r68 and upperToQuote.r68 soureces used by the above batch-file should be placed in the installation folder (\algolRutgersAlgol8 is assumed here). They are in the following sections on Using upper-stropping and Additional prelude items.

Using upper stropping

As mentioned above, Rutgers Algol 68 uses quote-stropping. The following program will convert an upper-stropping source to Rutgers style quote-stropping. Additionally, it removes any pragmats (i.e. pragmatic comments delimited by pr or pragma) from the source.

This should be placed in the installation folder (\algol\RutgersAlgol68 is assumed here) and called upperToQuote.r68.

'begin' # convert an upper-stropped source to Rutgers quote stropping #
    'proc' control = ( 'char' letter )'char': 'repr' ( 1 + ( 'abs' letter - 'abs' "A" ) );
    'char'   ctrlE        = control( "E" );
    'char'   ctrlO        = control( "O" );
    'char'   ctrlF        = control( "F" );
    'char'   ctrlZ        = control( "Z" );
    'char'   quote        = """";
    'char'   briefComment = "#";
    'char'   nl           = 'repr' 10;
    'int'    lineNumber  := 1;
    'string' pushback    := "";
    'bool'   atEof       := 'false';
    'proc' readChar = 'char':
           'if' atEof
           'then'
                # reached EOF #
                ctrlZ
           'elif' 'upb' pushback >= 'lwb' pushback
           'then'
               'char' c  = pushback[ 'lwb' pushback ];
               pushback := pushback[ 'lwb' pushback + 1 : ];
               'if' c = nl 'then' lineNumber +:= 1 'fi';
               c
           'elif' 'char' c;
                  'proc' nextChar = 'char':
                         'begin'
                             'char' c;
                             read( ( c ) );
                             c
                         'end' # nextChar # ;
                  ( c := nextChar ) = ctrlE
           'then'
               # have ^E - possible EOF #
               'if' ( c := nextChar ) /= ctrlO
               'then'
                   # didn't get ^O after ^E #
                   c +=: pushback;
                   ctrlE
               'elif' # have ^E^O - could be EOF #
                      ( c := nextChar ) = ctrlF
               'then'
                   # have ^E^O^F - i.e. have an EOF marker #
                   atEof := 'true';
                   ctrlZ
               'else'
                   # didn't get ^F after ^E^O #
                   c     +=: pushback;
                   ctrlO +=: pushback;
                   ctrlE
               'fi'
           'else'
               # normal character #
               'if' c = nl 'then' lineNumber +:= 1 'fi';
               c
           'fi' # readChar # ;
    'proc' putChar = ( 'char' c )'void': print( ( c ) );
    'proc' putWordInLowerCase = ( 'string' word )'void':
           'begin'
                'for' cPos 'from' 'lwb' word 'to' 'upb' word
                'do'
                    putChar( 'repr' ( ( 'abs' word[ cPos ]
                                      - 'abs' "A"
                                      )
                                    + 'abs' "a"
                                    )
                           )
                'od'
           'end' # putWordInLowerCase # ;
    'proc' readBoldWord = 'string':
           'begin'
                'string' boldWord := c;
                'while' c := readChar;
                        ( c >= "A" 'and' c <= "Z" )
                'do'
                    boldWord +:= c
                'od';
                boldWord
           'end' # readBoldWord # ;

    'char'  c := readChar;
    'while' c /= ctrlZ
    'do'
        'if' c = quote 'or' c = briefComment
        'then'
            # char/string denotation or brief comment #
            'int'    startLine  = lineNumber;
            'char'   delimiter  = c;
            'string' symbolName = 'if' c = quote
                                  'then' "denotation"
                                  'else' "comment"
                                  'fi';
            putChar( c );
            'if' delimiter = briefComment
            'then'
                # brief comment - allow newlines #
                'while' c := readChar;
                        c /= delimiter
                  'and' c /= ctrlZ
                'do'
                    putChar( c )
                'od'
            'else'
                # string/char denotation - do not allow newlines #
                'while' c := readChar;
                        c /= delimiter
                  'and' c /= ctrlZ
                  'and' c /= nl
                'do'
                    putChar( c )
                'od'
            'fi';
            'if' c = delimiter
            'then'
                # have a closing delimiter #
                putChar( c );
                c := readChar
            'else'
                # closing delimiter missing #
                print( ( newline
                       , "**** "
                       , 'if' c = nl 'then' "Newline" 'else' "EOF" 'fi'
                       , " before closing ["
                       , delimiter
                       , "] for the "
                       , symbolName
                       , " starting on line "
                       , startLine
                       , newline
                       )
                     )
            'fi'
        'elif' c >= "A" 'and' c <= "Z"
        'then'
            # upper-stropping bold-word #
            'string' boldWord := readBoldWord;
            'if'  boldWord /= "CO" 'and' boldWord /= "COMMENT"
            'and' boldWord /= "PR" 'and' boldWord /= "PRAGMA"
            'then'
                # not a comment/pragmat - convert the bold-word to lower-case #
                # and enclose in single quotes #
                putChar( "'" );
                putWordInLowerCase( boldWord );
                putChar( "'" )
            'else'
                # pragmat or comment #
                # pragmats are ignored and converted to brief comments #
                'int'    startLine = lineNumber;
                'string' delimiter = 'if'   boldWord = "CO"
                                     'then' "'co' "
                                     'elif' boldWord = "COMMENT"
                                     'then' "'comment' "
                                     'else' briefComment
                                     'fi';
                print( ( delimiter ) );
                'while'
                    'while' c /= ctrlZ
                      'and' ( c <= "A" 'or' c >= "Z" )
                    'do'
                        putChar( c );
                        c := readChar
                    'od';
                    'bool' atEndOfPragment := 'false';
                    'if' c = ctrlZ
                    'then'
                        # got eof before the ending delimiter #
                        print( ( newline
                               , "**** EOF "
                               , "before the closing delimiter for the "
                               , boldWord
                               , " starting on line "
                               , startLine
                               , newline
                               )
                             );
                        atEndOfPragment := 'true'
                    'else'
                        # have a bold character, could be the delimiter #
                        'string' possibleDelimiter := readBoldWord;
                        'if' 'not' ( atEndOfPragment := possibleDelimiter = boldWord )
                        'then'
                            # not at the end of the comment #
                            print( ( possibleDelimiter ) )
                        'fi'
                    'fi';
                    'not' atEndOfPragment
                'do'
                    'skip'
                'od';
                print( ( delimiter ) )
            'fi'
        'else'
            # "normal" character #
            putChar( c );
            c := readChar
        'fi'
    'od'
'end'

Note that Rutgers Algol 68 does not implement transput event routines, so cannot detect EOF. The above program assumes EOF will be indicated by control-E followed by control-O followed by control-F.

The postlude file (used by the batch file above) in the following section should end with ^E^O^F.

Additional prelude items

The following source should be placed in the instalation folder (\algol\RutgersAlgol68 is assumed here) and named prelude.r68:

'begin' # additional prelude declarations for Rutgers Algol 68 #
    'int'  max abs char = 255;
    'mode' 'complex'    = 'compl';
    'prio' 'over'   = 7;
    'op'   'over'   = ( 'int' a, b )'int': a % b;
    'prio' 'overab' = 1;
    'op'   'overab' = ( 'ref''int' a, 'int' b )'ref''int': a := a 'over' b;
    'prio' 'modab'  = 1;
    'op'   'modab'  = ( 'ref''int' a, 'int' b )'ref''int': a := a 'mod'  b;
    'proc'  whole   = ( 'int' value, width )'string':
    'begin'
        [ 1 : 20 ]'char' result;
        'int'            rpos := 'upb' result + 1;
        'int'            v    := 'abs' value;
        'int'            w    := 'abs' width;
        'while' result[ rpos -:= 1 ] := 'repr' ( 'abs' "0" +  v 'mod' 10 );
                w -:= 1;
                ( v 'overab' 10 ) > 0
        'do''skip''od';
        'if'   value < 0 'then' result[ rpos -:= 1 ] := "-"; w -:= 1
        'elif' width > 0 'then' result[ rpos -:= 1 ] := "+"; w -:= 1
        'fi';
        'while' w > 0 'do' result[ rpos -:= 1 ] := " "; w -:= 1 'od';
        result[ rpos : 'upb' result ]
    'end'; # whole #
    'proc' char in string = ( 'char' c, 'ref''int' position, 'string' text )'bool':
    'begin'
        'bool' found := 'false';
        'for' pos 'from''lwb' text 'to''upb' text 'while''not' found
        'do'
            'if' found := text[ pos ] = c
            'then'
                # found the character - if we have a REF INT to return the   #
                # position in, set it                                        #
                'if''ref''int'( position ) 'isnt''ref''int'( 'nil' )
                'then'
                    # have a position                                        #
                    position := pos
                'fi'
            'fi'
        'od';
        found
    'end'; # char in string #
    'begin'

The following source should be placed in the installaton folder (\algol\RutgersAlgol68 is assumed here) and named postlude.r68.
Note that ^E^O^F should be replaced with the seuence of characters control-E, control-O and control-F.

    'end'
'end'
^E^O^F