Rutgers ALGOL 68: Difference between revisions
Content added Content deleted
Line 23: | Line 23: | ||
=== Building and running under Windows === |
=== Building and running under Windows === |
||
<br> |
<br> |
||
To build under Windows, download the Linux version and unpack to a suitable |
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 |
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. |
||
<lang dos>rem build.bat: build the Linux version of RutgersAlgol68 under Windows |
<lang dos>rem build.bat: build the Linux version of RutgersAlgol68 under Windows |
||
Line 58: | Line 58: | ||
cd ..</lang> |
cd ..</lang> |
||
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): |
|||
<lang dos>@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</lang> |
|||
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. This should be placed in the installation folder (\algol\RutgersAlgol68 is assumed here) and called '''upperToQuote.r68'''. |
|||
<lang algol68>'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'</lang> |
|||
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 wit ^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''': |
|||
<lang algol68>'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'</lang> |
|||
The following source should be placed in the installaton folder (\algol\RutgersAlgol68 is assumed here) and named '''postlude.r68'''. |
|||
<br> |
|||
'''Note''' that ^E^O^F should be replaced with the seuence of characters control-E, control-O and control-F. |
|||
<lang algol68> 'end' |
|||
'end' |
|||
^E^O^F</lang> |