|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 73728 (0x12000) Types: TextFile Names: »tptoa«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦this⟧ »tptoa«
begin procedure writetest(text); integer array text; begin integer i,j,k; j:=system(3,k,text); for i:=j,i+1 while i<=k and text(i-1) <> 0 do begin outchar(out,if text(i) = 0 then 38 else text(i)); end; if text(i-1) <> 0 then outchar(out,37); end writetest; procedure writetesti(text,j); value j; integer j; integer array text; begin integer i,k; system(3,k,text); for i:=j,i+1 while i<=k and text(i-1) <> 0 do begin outchar(out,if text(i) <> 0 then text(i) else 38); end; if text(i-1) <> 0 then outchar(out,37); end writetesti; procedure writetestnl(textstring); string textstring; begin write(out,<:<10>:>,textstring,<:<58>:>); end writetestnl; procedure writetestno(number); value number; integer number; begin write(out,number); end writetestno; procedure writetestchar(char); value char; integer char; begin if char > 32 and char < 127 then outchar(out,char) else write(out,false add 34,1,<<zdd>,char,false add 34,1); end writetestchar; integer searchtablelength, ntablength, stdlinelength, maxniveau; comment all texts is assumed to be of stdlinelength, unless otherwise conditions assure another length ; stdlinelength := 132; comment table length initialisation; searchtablelength := 253; ntablength := 6000; comment in sequential pascal their is only 2 niveaus program and procedure, note no local procedures; maxniveau := 1; begin integer array ntab(0:ntablength), searchtable(0:searchtablelength); integer entrynext, entrytype, entrylength, entrynamelength, entrytypeid, basicentrylength, entrytypedeckind, entryparameterlistlength, entrytypedecref; comment entry types; integer constantentry, typedecentry, recorddecentry, recordentry, reservedword, variabledecentry, structuredecentry, routineheading, enumerationconstantentry, recordfixedpartelemententry, recordelementfixedinwithblockentry, recordelementvariantentry recordelementvariantinwithblockentry; comment name types; integer notype, integertype, realtype, chartype, booleantype, stringtype, nextdeclaredtype; comment type declaration kinds; integer enumerationtype, previusdefinedtype, simpletype, subrangetype; procedure initofntabrecord; begin comment this procdure inits constants which conserning records and entrylength in the ntab; comment identifier symbol record describtion; entrynext := 0; entrylength := 1; basicentrylength := 6; entrynamelength := 3; entrytype := 4; constantentry := 1; typedecentry := 2; recorddecentry := 3; recordentry := 4; reservedword := 5; variabledecentry := 7; structuredecentry := 8; routineheading := 9; entrytypeid :=5; comment refference to a structured type, if type dec kind is previus definied type; entrytypedecref := 5; notype := 0; integertype:= 1; realtype := 2; chartype:= 3; booleantype := 4; stringtype := 5; nextdeclaredtype := 6; entryparameterlistlength := 6; entrytypedeckind := 6; enumerationtype := 1; previusdefinedtype := 2; subrangetype := 3; end initofntabrecord; comment table entry types; comment *************************************************** version 1.1 jan.1981. lilli andersen carsten gyrn. *************************************************** in this version all texts and charakters if considered as charakters is contained in a integer and texts is integer array with one charakter stored in every integer item. ***************************************************; comment *************************************************** implementation dependent input/output procedures *************************************************; comment procedure sourcechar schould read a charakter from the file where the pascal source program is stored.▶16◀▶16◀▶16◀ procedure objectchar schould write a charakter on the file where the algol object program is wanted. procedure listchar schould write a char on the file where the program listning, and error messages is wanted. all these procedure schold accept or return charater values, as integers in the iso alphabet ( close to asscii), the alphabet and conversion is given below. ( iso alphabet table ); procedure sourcechar(char); integer char; begin readchar(in,char); end sourcechar; procedure objectchar(char); value char; integer char; begin comment implementation dependent code, algol 8 version; outchar(objectfile,char); end objectchar; procedure listchar(char); value char; integer char; begin comment implementaion dependant code, algol 8 version; outchar(out,char); end listchar; comment decleration of file in the algol 8 version; zone objectfile(128,1,stderror); procedure openfiles; begin comment make all files ready to charakter input output. in the algol8 version the files for input source char and output of list char allready is openened and ready, becayse the standard input and output files is used. the file to the object file is declared just prior to this procedure. open(objectfile) as bs storage:(4) name:(<:objectfile:>) error mask :(0); end openfiles; procedure closefiles; begin comment terminates all ues of files. see comment to procedure obenfiles; close(objectfile,true); end closefiles; comment ****************************************************** implemantion dependant conversion procedures ******************************************************; boolean procedure convertstring(textarray,textstring); integer array textarray; string textstring; begin comment this procedure schould convert a string given as parameter to an integer array, where the charakters is packed left justified in a prober way ( see comment version ). the items in the textarray not used for the conversion is zero filled (null charakter). the procedure returns true if the conversion is ok, false otherwise; comment code for convertstring in algol 8, where move string converts a string to a real array where the charakters is packed as 6 charakters in every word, and a charakter occupie 8 bits; real array workarray(1:stdlinelength); integer i; movestring(workarray,1,textstring); for i:=1,i+1 while textarray(i-1) <> 0 do textarray(i) := workarray((i-1)//6+1) shift (-(48 -((i-1) mod 6+1)*8)) extract 8; end convertstring; comment ******************************************************* input output procedures *******************************************************; boolean procedure readsourceline; begin comment the procedure reads a string of a charakters using the procedure sourcechar, until either a new line, a form feed, a carrige return or a end medium charakter is met or the array line if filled up. the array line is assumed to be of standard line length; integer i; if -, endoffile then begin for i:=1,i+1 while class(sourceline(i-1)) < endoflineclass and i < stdlinelength do sourcechar(sourceline(i)); endofline := false; sourceline(i) := nullchar; sourcelinecounter := sourcelinecounter +1; gpointer := 1; if listsource then listsourceline; readsourceline := if class(sourceline(i-1)) < endoflineclass then true else false; if sourceline(i-1) = emchar then endoffile := true; end; end readsourceline; procedure writeobjectline(text); integer array text; begin comment write a std. text un the ogject file using the output procedure object char; integer index; for index := 1,index+1 while index <= stdlinelength and text(index-1) <> nullchar do begin objectchar(text(index)); end; end writeobjectline; procedure listline(line); integer array line; begin comment output a line given in the integer parameter line on the list file. the procedure stop output symbol from the line when a nlchareter , a formfeed, a carrige return or a end medium charakter is met or when the last charakter in the array line is met; integer i; for i:=1,i+1 while class(line(i-1)) < endoflineclass and line(i) <> nullchar and i <= stdlinelength do listchar(line(i)); end listline; procedure listsourceline; begin comment prints the source code with line numbers; integer index; integer array numbertext, formatnumber(1:12); converttextinteger(numbertext,sourcelinecounter); formatrigthtext(formatnumber,7,numbertext,1); concattext(printline,formatnumber,sourceline); insertnlchar(printline); listline(printline); end listsourceline; comment error and recovery procedures; procedure error(errorstring); string errorstring; begin comment errortext will be printed out on the list fie if list a pointer if source text is to be listed then a pointer is printed out before the error text line at positioning at current g pointer. line number is printed out before the error line text; integer array numbertext, formatnumber(1:12), errortext(1:stdlinelength); integer index; if listsource then begin for index := 1 step 1 until gpointer+7-1 do printline(index) := blankchar; printline(gpointer) := snabelachar; printline(gpointer+1) := nullchar; insertnlchar(printline); listline(printline); resettext(printline); end else begin converttextinteger(numbertext,sourcelinecounter); formatrigthtext(formatnumber,7,numbertext,1); movetext(printline,formatnumber); converttextinteger(numbertext,gpointer); formatrigthtext(formatnumber,7,numbertext,1); appendtext(printline,formatnumber); end; convertstring(errortext,errorstring); appendtext(printline,errortext); insertnlchar(printline); listline(printline); end error; comment recovery conditions; integer skipsemicolon, skipbegin, skipbeginsemicolon, skipreservedwordsemicolon, skipreservedword; procedure initofrecoverconditions; begin skipsemicolon := 1; comment skip until reserved word symbol begin or past semicolon; skipbeginsemicolon := 2; comment skip until begin; skipbegin := 3; comment skip until reserved word symbol or past semicolon; skipreservedwordsemicolon := 4; comment skip until next reserved word; skipreservedword := 5; end initofreceverconditions; procedure recover(condition); value condition; integer condition; begin comment this procedure tryes to firn the start of the next sentence, and set gpointer to start there; end recover; comment variables used in connection with input and output procedures; boolean endofline, endoffile, listsource; comment input and output buffers; integer array sourceline, objectline, printline(1:stdlinelength); integer sourcelinecounter, objectlinecounter; procedure initinputoutputvariables; begin endofline := true; endoffile := false; comment allways listning; listsource := true; sourcelinecounter := 0; objectlinecounter := 0; end initinputoutputvariables; comment objectcode printing procedures; procedure outcodenl; begin comment creates a newline char on the object line and write it out on the objectfile; objectlinecounter := objectlinecounter +1; insertnlchar(objectline); writeobjectline(objectline); end outcodenl; procedure outcodechar(char); value char; integer char; begin comment append the char to last of the objectline; if appendchar(objectline,char) then begin outcodenl; resettext(objectline); objectline(1) := char; end; end objectchar; procedure outcodetext(text); integer array text; begin comment add the text to the object line. if the result of the adding is greateher than std line then the object line i writen out and text is firt of new object line; if -, appendtext(objectline,text) then begin outcodenl; movetext(objectline,text); end; end outcodetext; procedure outcodestring(textstring); string textstring; begin comment adds the textstring to the objectline. if the result of the adding is greather than stdlinelength then objectline is written out on objectfile and textstring is made first of a new objectline; integer array text(1:stdlinelength); convertstring(text,textstring); if -, appendtext(objectline,text) then begin outcodenl; movetext(objectline,text); end; end outcodestring; comment variable used in connection with the procedure next,next0,next1,next2 which get next symbol from the source file; comment text,text0,text1,text2 contains the text of the identifier; integer array text,text0,text1,text2(1:stdlinelength); comment entry,entry0,entry1,entry2 contain an index of the identifier; integer entry,entry0,entry1,entry2; comment symbol,symbol0,symbol1,symbol2 contaion the symbol class of the the next symbol; integer symbol,symbol0,symbol1,symbol2; comment aux,aux0,aux1,aux2 contaions varius values; integer aux,aux0,aux1,aux2; comment the procedures next,next0,next1,next2 call getnextsymbol with different parameters; integer procedure next; begin next := symbol := getnextsymbol(text,entry,aux); end next; integer procedure next0; begin next0 := symbol0 := getnextsymbol(text0,entry0,aux0); end next0; integer procedure next1; begin next1 := symbol1 := getnextsymbol(text1,entry1,aux1); end next1; integer procedure next2; begin next2 := symbol2 := getnextsymbol(text2,entry2,aux2); end next2; comment table for class values associated to each char; integer array charclass(0:127); integer procedure class(char); value char; integer char; comment returns a class value associated to a given char. in this version the class values is taken from the table charclass; begin class := charclass(char); end class; integer procedure thisclass; begin comment delivers the class of the current spointer from the char in source line, only made to speed things up a bit; thisclass := charclass(sourceline(spointer)); end thisclass; comment variables used as symbol classes; integer illegalclass, letterclass, digetclass, exponentchar, rigthbraketchar, leftbraketchar, investchar, nextchar; comment charakter constants; integer nullchar, nlchar, emchar, ffchar, crchar, blankchar, minuschar, starchar, zerodigetchar, equalchar, greatherchar, lesschar, periodchar, colonchar, doublequotechar, snabelachar, firstsingleclass, lastsingleclass, firstdoubleclass, lastdoubleclass, firstseperatorclass, endoffileclass, endoflineclass; comment variables used as constant delivered as results from getnextsymbol, directive symbol and doublequotesymbol is not defined in the sequential pascal rapport page 5.; integer unknownsymbol, namesymbol, numbersymbol, greathersymbol, greatherequalsymbol, lesssymbol, lessequalsymbol, notequalsymbol, periodsymbol, rangeseperatorsymbol, rigtharraybraketsymbol, leftarraybraketsymbol, leftbraketsymbol, rigthbraketsymbol, assignmentsymbol, plussymbol, minussymbol, timessymbol, slashsymbol, pointersymbol, ambersandsymbol, equalsymbol, snabelasymbol, commasymbol, semicolonsymbol, colonsymbol, singlequotesymbol, doublequotesymbol, directivelsymbol; comment variables used inconnection with get next symbol. gpointer points to next char in sourceline, rpointer points to start of previus symbol used for error recovery, spointer used for scanning in sourceline is undefined after call of next; integer gpointer, spointer, rpointer, symbclass; integer procedure getnextsymbol(text,index,aux); integer array text; integer index,aux; begin if skipseperatorsymbol then begin comment init recovery pointer and scan pointer; rpointer := gpointer; spointer := gpointer; if symbclass = letterclass then getnextsymbol := getnextname(text,index,aux) else if symbclass = digetclass then getnextsymbol := getnextnumber(text,index,aux) else if symbclass >= firstsingleclass and symbclass <= lastsingleclass then getnextsymbol := getnextsinglecharsymbol(text,index,aux) else getnextsymbol := getnextdoublecharsymbol(text,index,aux); end else begin getnextsymbol := endoffileclass; end; end getnextsymbol; integer procedure getnextname(text,index,aux); integer array text; integer index,aux; begin comment letter found. collect text, and look up; integer spointer; for spointer := gpointer, spointer + 1 while symbclass = letterclass or symbclass = digetclass do begin text(spointer+1-gpointer) := sourceline(spointer); symbclass := class(sourceline(spointer+1)); end; comment set end text charakter in text; text(spointer+1-gpointer) := nullchar; gpointer := spointer; comment look up text in texttable; if lookuptext(text,index) then begin comment find name type in ntab and return result; if ntab(index+entrytype) = reservedword then begin comment because the reserved word is one of the most common symbols it is given a spcial symbol. also instead of returning the type in the var aux the nameid is returned, ( i.e. is it a begin or a while ect.). ; getnextname := reservedword; aux := ntab(index+entrytypeid); end else begin getnextname := namesymbol; aux := ntab(index+entrytype); end; end else getnextname := unknownnamesymbol; end getnextname; integer procedure getnextnumber(text,index,aux); integer array text; integer index,aux; begin comment number found. read number and store as text. aux gives as result integer or real; aux := integertype; for spointer:=gpointer, spointer+1 while thisclass = digetclass do begin text(spointer+1-gpointer) := sourceline(spointer); end; if class(spointer) = periodsymbol then begin aux := realtype; comment decimalpart found; text(spointer+1-gpointer) := sourceline(spointer); for spointer:=spointer+1 while thisclass=digetclass do begin text(spointer+1-gpointer) := sourceline(spointer); end; if sourceline(spointer) = exponentchar then begin comment exponent part found; text(spointer+1-gpointer) := sourceline(spointer); for spointer := spointer+1 while thisclass = digetclass do begin text(spointer+1-gpointer) := sourceline(spointer); end; end exponent part; end decimalpart; comment set end text charakter; text(spointer+1-gpointer) := 0; gpointer := spointer; getnextnumber := numbersymbol; end getnextnumber; integer procedure getnextsinglecharsymbol(text,index,aux); integer array text; integer index,aux; begin comment single charakter symbol is met, the class of the symbol is used as result, aux is set to the charakter value, text and index is unassigned; aux := sourceline(gpointer); getnextsinglecharsymbol := symbclass; gpointer := gpointer+1; end getnextsinglesymbol; integer procedure getnextdoublecharsymbol(text,index,aux); integer array text; integer index,aux; begin investchar := sourceline(gpointer); nextchar := sourceline(gpointer+1); if investchar = colonchar and nextchar = equalchar then begin getnextdoublecharsymbol:= assignmentsymbol; gpointer := gpointer + 2; end else if investchar = leftbraketchar and nextchar = periodchar then begin getnextdoublecharsymbol:= leftarraybraketsymbol; gpointer := gpointer + 2; end else if investchar = periodchar then begin if nextchar = rigthbraketchar then begin getnextdoublecharsymbol:= rigtharraybraketsymbol; gpointer := gpointer + 2; end else if nextchar = periodchar then begin getnextdoublecharsymbol:= rangeseperatorsymbol; gpointer := gpointer + 2; end else begin getnextdoublecharsymbol:= periodsymbol; gpointer := gpointer +1; end; end else if investchar = lesschar then begin if nextchar = greatherchar then begin getnextdoublecharsymbol:= notequalsymbol; gpointer := gpointer +2; end else if nextchar = equalchar then begin getnextdoublecharsymbol:= lessequalsymbol; gpointer := gpointer+2; end else begin getnextdoublecharsymbol:= lesssymbol; gpointer := gpointer +1; end; end else if investchar = greatherchar then begin if nextchar = equalchar then begin getnextdoublecharsymbol:= greatherequalsymbol; gpointer := gpointer +2; end else begin getnextdoublecharsymbol:= greathersymbol; gpointer := gpointer +1; end; end else begin getnextdoublecharsymbol := unknownsymbol; gpointer := gpointer +1; end; aux := investchar; index := nextchar; end getnextdoublesymbol; boolean procedure skipseperatorsymbol; begin comment this procedure skips all seperator symbols i.e blank, newline, carriege return and form feed charakters and comments. the skipping starts with the charakter pointerd out by gpointer, at return gpointer points to the first charakter not part of a seperator and symbclass contains the class of the first char not part of a seperator. the result of skipseperator is false if endoffile is met otherwise true; if -, endoffile then begin if endofline then readsourceline; for symbclass := class(sourceline(gpointer)) while symbclass >= firstseperatorclass and -, endoffile do begin if symbclass = endoflineclass then readsourceline else if symbclass = doublequotesymbol then skipcomment else gpointer := gpointer +1; end; end; skipseperatorsymbol := if endoffile then false else true; end skipblank; procedure skipcomment; begin comment skips from a begining of a comment until and past its end. gpointer points on the first duoblequote at entry. ; for gpointer := gpointer +1 while sourceline(gpointer) <> doublequotechar and -, endoffile do begin if class(sourceline(gpointer)) = endoflineclass then begin readsourceline; gpointer := 0; end; end; end skipcomment; procedure initofsearchtable; begin comment initialize every entry in the searchtable with the initial value nil; integer index; for index := 0 step 1 until searchtablelength do searchtable(index) := nil; end initofsearchtable; boolean procedure insertname(tabindex,name,recordtype,recordidno); value recordtype,recordidno; integer tabindex,recordtype,recordidno; integer array name; begin integer nameindex,recordindex; comment insert name in identifier table. if the name is allready in the idnametable then it is not inserted but the same name in the idnametable is used. if the same name exists in the idname table then it must be on same or a lower niveau; lookupname(name,nameindex); nameindex := allocate(length0(name)); movename4(ntab,nameindex,name); comment record information insert in ntable; recordindex := allocate(basicentrylength); ntab(recordindex+entrylength) := basicentrylength; ntab(recordindex+entrynext) := searchtable(tabindex); searchtable(tabindex) := recordindex; ntab(recordindex+entryrecordtype) := recordtype; ntab(recordindex+entryrecordtypeid) := recordidno; ntab(recordindex+entrynamelength) := length0(name); tabindex := recordindex; end insertname; boolean procedure lookuptext(text,textindex); integer array text; integer textindex; begin comment lookup a text in the ntab indexed through the search table. the result is true if the text is found othervise false. if the text is found then the textindex points to the symbol in the ntab. if the text is not found then textindex is the index in the search table; integer hashkey,searchkey,textlength; boolean textfound; textfound := false; textlength := length0(text); hashkey := calculatehashkey(text); searchkey := searchtable(hashkey); textindex := hashkey; for dummy := dummy while -, textfound and searchkey <> nil do begin if textlength = ntab(searchkey+entrynamelength) then begin if comparetext(text,1,ntab, ntab(searchkey-ntab(searchkey+entrynamelength))) then begin textindex := searchkey; textfound := true; end end; searchkey := ntab(searchkey+entrynext); end; lookuptext := textfound; end lookuptext; integer procedure calculatehashkey(text); integer array text; begin comment calculates a search key to be used for searching in the symbolable. the key is calculated using all charakters in the text. if no text is aplied to the procedure the hash key as result i zero.; integer hashkey,index; hashkey := 0; index := 0; for index := index+1 while text(index) <> 0 do hashkey := hashkey + index*text(index); calculatehashkey := hashkey mod searchtablelength + ( if hashkey <> 0 then 1 else 0); end calculatehashkey; procedure resettext(text); integer array text; begin comment insert a null char in the frirst position in the text, and by doing so making it a standard left justified empty text; text(1) := nullchar; end resettext; boolean procedure comparetext(text1,pointer1,text2,pointer2); integer array text1,text2; integer pointer1,pointer2; begin comment compares a text in array text1 with a text in array text2. the texts starts in the arrays at pointer1 or pointer2 respectively. result true if the texts are equal othervise false. it is asumed the the texts ends correct whit a zero charakter; integer index; boolean finiscompare; finiscompare := false; comparetext := true; for index := 0, index+1 while -,finiscompare do begin if text1(pointer1+index) <> text2(pointer2+index) then begin comparetext := false; finiscompare := true; end; if text1(pointer1+index) = 0 then finiscompare := true; end; end comparetext; boolean procedure concattext(resulttext,text1,text2); integer array resulttext,text1,text2; begin comment concatenate 2 left justified texts text1 and text2 to result text. ; integer indexfrom,indexto; indexto := 1; indexfrom:= 0; for indexfrom := indexfrom+1 while text1(indexfrom) <> 0 and indexto < stdlinelength do begin resulttext(indexto) := text1(indexfrom); indexto := indexto + 1; end; indexfrom := 0; for indexfrom := indexfrom + 1 while text2(indexfrom) <> 0 and indexto < stdlinelength do begin resulttext(indexto) := text2(indexfrom); indexto := indexto + 1; end; concattext := if indexto > 131 then false else true; resulttext(indexto) := 0; end concattext; boolean procedure appendtext(text1,text2); integer array text1,text2; begin comment adds text2 into text1 after the zero ending char in text1. if the result of the appending is longer than stdlinelength then text1 is left unchanged. the result of append is true if the appending is performed othervise false; integer text1length,index2; for text1length := 0, text1length+1 while text1(text1length) <> nullchar and text1length <= stdlinelength do; for index2:=0,index2+1 while text1length+index2 < stdlinelength and text2(index2) <> nullchar do text1(text1length+index2) := text2(index2+1); if index2+text1length <= stdlinelength then appendtext := true else begin appendtext := false; text1(text1length) := nullchar; end; end appendtext; boolean procedure appendchar(text,char); value char; integer char; integer array text; begin comment appends the char to the last of the text; integer index; for index:=1,index+1 while index<=stdlinelength and text(index-1) <> nullchar do; if index+1 < stdlinelength then begin appendchar := true; text(index-1) := char; text(index) := nullchar; end else appendchar := true; end appendchar; boolean procedure movetext(resulttext,sourcetext); integer array resulttext,sourcetext; begin comment moves the contents of sourcetext to result text. both text is left justified. the result schold obius allways be true, but if source text not end with a zero charakter then the result is false; integer index; for index := 1,index+1 while index < stdlinelength do resulttext(index) := sourcetext(index); movetext := if index < stdlinelength then true else false; end movetext; boolean procedure movetext1(resulttext,text1,indexlow,indexhigh); value indexlow,indexhigh; integer indexlow,indexhigh; integer array resulttext,text1; begin comment moves a text from array text1 indexed from indexlow to index high to the array resulttext left justified. if a zero charakter in text1 is met before index high then the procedure is terminated. the result of the procedure is false if more than stdlinelength charakters is tryed to be moved othervise true; integer indexto; indexto := 0; for indexto:=indexto+1 while indexto < stdlinelength and indexlow <= indexhigh do begin resulttext(indexto) := text1(indexlow); if resulttext(indexto) = 0 then indexlow := indexhigh + 1 else indexlow := indexlow + 1; end; movetext1 := if indexto < stdlinelength then true else false; end movetext1; boolean procedure movetext2(resulttext,indexhigh,indexlow,sourcetext); integer array resulttext,sourcetext; integer indexhigh,indexlow; begin comment moves the left justifieded sourcetext ending on a zero charakter to resulttext starting at index indexlow. indexhigh is the last position in resulttext where sourcetext is mowed to. the zero ending charakter ending sourcetext is not mowed. the result of the procedure is true if the move was succesfull otherwise false (i.e. result text was mot long enogh to take the whole of sourcetext); integer index; index:=0; for index:=index+1 while sourcetext(index) <> 0 and indexlow+index < stdlinelength do begin resulttext(indexlow+index-1) := sourcetext(index); end; movetext2 := if indexlow+index < stdlinelength then true else false; end movetext2; boolean procedure movetext3(resulttext,indexrlow,indexrhigh, sourcetext,indexslow,indexshigh); value indexrlow,indexslow,indexshigh; integer array resulttext,sourcetext; integer indexrlow,indexrhigh,indexslow,indexshigh; begin comment move sourcetext from lindexslow to indexshigh to resulttext from indexrlow to indexrhigh. indexrhigh is a result parameter. the result of the procedure is true if the move was successfully otherwise false; integer index; index :=-1; for index := index+1 while indexslow+index <= indexrhigh and indexslow+index < stdlinelength and indexrlow+index < stdlinelength do begin resulttext(indexrlow+index) := sourcetext(indexslow+index); end; movetext3 := if indexrlow+index >= stdlinelength then false else if indexslow+index >= stdlinelength then false else true; end movetext3; boolean procedure movetext4(resulttext,indexlow,sourcetext); value indexlow; integer indexlow; integer array resulttext,sourcetext; begin comment moves a left justified text from source text to result text starting at positon indexlow in resulttext; integer index; for index:=1,index+1 while sourcetext(index-1) <> 0 do begin resulttext(indexlow-1+index) := sourcetext(index); end; movetext4 := if sourcetext(index) <> 0 then false else true; end movetext4; boolean procedure movetext5(tabtext,tabindex,text); value tabindex; integer array tabtext,text; integer tabindex; begin comment moves a left justified text from text to a 2 dimentional array tabtext where the first index is tabindex and the the second index is the text; integer charindex; charindex := 0; for charindex:=charindex+1 while text(charindex) <> 0 and charindex < stdlinelength do begin tabtext(tabindex,charindex) := text(charindex); end; tabtext(tabindex,charindex) := 0; movetext5 := if text(charindex) <> 0 then false else true; end movetext5; boolean procedure movetext6(text,tabtext,tabindex); value tabindex; integer array text,tabtext; integer tabindex; begin comment movex a left justified text in the table texttable indexed with the tabindex to the text; integer charindex; charindex := 0; for charindex := charindex +1 while charindex < stdlinelength and tabtext(tabindex,charindex) <> 0 do begin text(charindex) := tabtext(tabindex,charindex); end; text(charindex) := 0; movetext6 := if tabtext(tabindex,charindex) = 0 then true else false; end movetext6; procedure converttextinteger(text,number); value number; integer number; integer array text; begin comment converts an integer number to a text with std format left justified; integer index,turnindex,help; if number < 0 then begin text(index):=minuschar; turnindex := 2; index:=2; number := -1* number; end else begin index := 1; turnindex := 1; end; for index := index ,index+1 while number > 0 do begin text(index) := ( number mod 10) + zerodigetchar; number := number // 10; end; text(index) := 0; comment turn number; for index := index -1 while index <> turnindex do begin help := text(index); text(index) := text(turnindex); turnindex := turnindex+1; end; end converttextinteger; boolean procedure convertintegertext(result,text); integer result; integer array text; begin comment converts a left justified text which contains diget charakters into a integer. result is zero if no diget charakters is met, the conversion stops when the first non diget charakter is met, convertintegertext is false if no diget is met otherwise false; integer index,number; number := 0; index := 0; for index := index+1 while class(text(index)) = digetclass do begin number := number*10 + text(index)-zerodigetchar; end; convertintegertext := if index > 1 then true else false; result := number; end convertintegertext; procedure formattext(resulttext,resultlength,position,sourcetext); value position,resultlength; integer resultlength,position; integer array resulttext,sourcetext; begin comment formats sourcetext into resulttext so it will be resultlength charakters long and start in position. not used position veill be filled with blanks; integer index; for index := 1 step 1 until position-1 do resulttext(index) := blankchar; for index := index+1 while sourcetext(index) <> 0 and index <= resultlength do resulttext(index) := sourcetext(index+1-position); for index := index step 1 until resultlength do resulttext(index) := blankchar; end formattext; procedure formatrigthtext(resulttext,resultlength,sourcetext,endspace); value resultlength,endspace; integer resultlength,endspace; integer array resulttext,sourcetext; begin comment positions sourcetext rigth in resulttext which is resulttext ling so after sourcetext their is endpace blankchars. if source text can not be in resulttext plus endspace then sourcetext is filed up with starchar; integer index,leadingblanks; if length(sourcetext) + endspace > resultlength then begin for index := 1 step 1 until resultlength do resulttext(index) := starchar; resulttext(index+1) := nullchar; end else begin leadingblanks := resultlength -(endspace+length(sourcetext)); for index := 1 step 1 until leadingblanks do resulttext(index) := blankchar; index := 0; for index := index +1 while sourcetext(index) <> 0 and index < stdlinelength do resulttext(index+leadingblanks) := sourcetext(index); for index := 1 step 1 until endspace do resulttext(resultlength+1-1) := blankchar; resulttext(resultlength+1) := nullchar; end; end formatrigthtext; integer procedure length0(text); integer array text; begin comment calcualtes the length of text which is left justified and ending on zero charakter. if the last char is not a zero char then zero char is inserted. if length is negative then text was not ending on a zero charakter. the zero char is included in the length calculation; integer index; for index :=0, index+1 while index < stdlinelength and text(index) <> 0 do; length0 := if text(index) = 0 then index else -index; if index= stdlinelength then text(index) := 0; end length0; integer procedure length(text); integer array text; begin comment catculates the length of a left justified std format text. if the last char is not a null char then a nnull char is inserted an the length is given as negative. the zero char is not included in the length calculation, see proccedure length0; integer index; for index := 0 , index +1 while index<= stdlinelength and text(index) <> 0 do; length := if text(index) = 0 then index-1 else -index-1; if index=stdlinelength then text(index) := 0; end length; boolean procedure insertnlchar(line); integer array line; begin comment inserts a nl char if before the zero char ending the text line if no nl char is present before. if the line fills the whole array the nl char is inserted instead of the zero char. if the zero char is substitueted then insertnlchar is false else true; integer index; for index :=1,index+1 while index <= stdlinelength and line(index-1) <> nlchar do begin if line(index) = 0 then begin line(index) := nlchar; if index+1 <= stdlinelength then line(index+1) := nullchar; end; end; insertnlchar := if index > stdlinelength then false else true; end procedure insertnlchar; comment reservedword symbols; comment reservedword symbols constant; integer resarray, resbegin, resconst, rescase, resdiv, resdo, resdownto, reselse, resend, resfor, resforward, resfunction, resif, resin, resmod, resnot, resof, resor, resprocedure, resprogram, resrecord, resrepeat, resset, resthen, resto, restype, resuniv, resvar, reswhile, reswith; procedure initofreservedwordsymbol; begin comment initialization of reservedword constants; resarray := 1; resbegin := 2; resconst := 3; rescase := 4; resdiv := 5; resdo := 6; resdownto := 7; reselse := 8; resend := 9; resfor := 10; resforward := 11; resfunction := 12; resif := 13; resin := 14; resmod := 15; resnot := 16; resof := 17; resor := 18; resprocedure := 19; resprogram := 20; resrecord := 21; resrepeat := 22; resset := 23; resthen := 24; resto := 25; restype := 26; resuniv := 27; resvar := 28; reswhile := 29; reswith := 30; end initofreservedwordsymbol; comment symbolconstants; integer lastreservedword, unknownnamesymbol firstidentifier, idboolean, idchar, idinteger, idreal, idfalse, idtrue, predefinedidentifier; procedure initofsymbolconstants; begin lastreservedword:=30; firstidentifier := 32; comment predeclared identifiers; comment 4 types is predeclared; idboolean := 32; idchar := 33; idinteger := 34; idreal := 35; comment the two resrved enumeration values true and false; idfalse := 36; idtrue := 37; end initofsymbolconstants; procedure initofnametable; begin comment this procedure initialize the name table with the reservedword symbol and predefined identifiers (ex. false and true); integer array texttable(1:30,1:12); integer array text(1:12); integer index,searchindex; comment initialize the tet table with the reservedword; convertstring(text,<:array:>); movetext5(texttable,1,text); convertstring(text,<:begin:>); movetext5(texttable,2,text); convertstring(text,<:case:>); movetext5(texttable,3,text); convertstring(text,<:const:>); movetext5(texttable,4,text); convertstring(text,<:div:>); movetext5(texttable,5,text); convertstring(text,<:do:>); movetext5(texttable,6,text); convertstring(text,<:downto:>); movetext5(texttable,7,text); convertstring(text,<:else:>); movetext5(texttable,8,text); convertstring(text,<:end:>); movetext5(texttable,9,text); convertstring(text,<:for:>); movetext5(texttable,10,text); convertstring(text,<:forward:>); movetext5(texttable,11,text); convertstring(text,<:function:>); movetext5(texttable,12,text); convertstring(text,<:if:>); movetext5(texttable,13,text); convertstring(text,<:in:>); movetext5(texttable,14,text); convertstring(text,<:mod:>); movetext5(texttable,15,text); convertstring(text,<:not:>); movetext5(texttable,16,text); convertstring(text,<:of:>); movetext5(texttable,17,text); convertstring(text,<:or:>); movetext5(texttable,18,text); convertstring(text,<:procedure:>); movetext5(texttable,19,text); convertstring(text,<:program:>); movetext5(texttable,20,text); convertstring(text,<:record:>); movetext5(texttable,21,text); convertstring(text,<:repeat:>); movetext5(texttable,22,text); convertstring(text,<:set:>); movetext5(texttable,23,text); convertstring(text,<:then:>); movetext5(texttable,24,text); convertstring(text,<:to:>); movetext5(texttable,25,text); convertstring(text,<:type:>); movetext5(texttable,26,text); convertstring(text,<:univ:>); movetext5(texttable,27,text); convertstring(text,<:var:>); movetext5(texttable,28,text); convertstring(text,<:while:>); movetext5(texttable,29,text); convertstring(text,<:with:>); movetext5(texttable,30,text); comment insert reservedwords symbols in name table; for index := 1 step 1 until 30 do begin movetext6(text,texttable,index); lookuptext(text,searchindex); insertname(searchindex,text,reservedword,index); end; comment insert predefined identifiers in name table; convertstring(text,<:boolean:>); movetext5(texttable,1,text); convertstring(text,<:char:>); movetext5(texttable,2,text); convertstring(text,<:integer:>); movetext5(texttable,3,text); convertstring(text,<:real:>); movetext5(texttable,4,text); convertstring(text,<:false:>); movetext5(texttable,5,text); convertstring(text,<:true:>); movetext5(texttable,6,text); for index := 1 step 1 until 6 do begin movetext6(text,texttable,index); lookuptext(text,searchindex); insertname(searchindex,text,predefinedidentifier,index+31); end; end initofnametable; procedure initclasscharsymbol; begin integer i; comment init all illegal charakters; unknownsymbol := 1; illegalclass := 1; for i:= 0 step 1 until 127 do charclass(i) := 1; comment charakters which is skipped in input; charclass(0) := 0; comment charakter null is internaly used for ending texts; nullchar := 0; comment diget is class 10; numbersymbol := 10; digetclass := 10; zerodigetchar := 48; for i:=48 step 1 until 58 do charclass(i) := 10; comment letters is class 12; comment unknown name is when the identifier is not found in the name table; unknownnamesymbol := 11; comment name symbol is when the identifier is found in the name table; namesymbol := 12; comment reservedword is when the entrytype found in the name table is of reservedword type. this value is initialised and defined in section name table record; comment initialised to 5, therefor symbol class 5 is reserved; reservedword := reservedword; letterclass := 12; for i:= 65 step 1 until 90 do charclass(i) := 12; for i:= 97 step 1 until 122 do charclass(i) := letterclass; comment single class; firstsingleclass := 14; comment plus char; plussymbol := 14; charclass(43) := 14; comment minus char; minussymbol := 15; minuschar := 45; charclass(45) := 15; comment times char or star char; starchar := 42; timessymbol := 16; charclass(42) := 16; comment slash char; slashsymbol := 17; charclass(47) := 17; comment and char; ambersandsymbol := 18; charclass(38) := 18; comment equal char ; equalsymbol := 19; charclass(61) := 19; comment snabela char; pointersymbol := 20; snabelasymbol := 20; snabelachar := 64; charclass(64) := 20; comment rigth braket; rigthbraketsymbol := 21; charclass(41) := 21; comment comma char; commasymbol := 22; charclass(44) := 22; comment semicolon char; semicolonsymbol := 23; charclass(59) := 23; comment quote char; singlequotesymbol := 24; charclass(60) := 24; lastsingleclass := 24; comment class 25 not used; comment symbols which is migth single if not double; comment colon class; charclass(58) := 26; colonsymbol := 26; comment period char; charclass(46) := 27; periodsymbol := 27; comment comment less char; charclass(60) := 28; lesssymbol := 28; comment greather char; charclass(62) := 29; greathersymbol := 29; comment init of double charakters symbol; comment colon char and equal char is assignment; colonchar := 58; equalchar := 61; assignmentsymbol := 30; firstdoubleclass := 30; comment left braket and period is left array braket; leftbraketchar := 40; periodchar := 46; leftarraybraketsymbol := 34; comment period char and rigth braket is rigth array braket; rigthbraketchar := 41; rigtharraybraketsymbol := 36; comment period char and period char is range symbol; rangeseperatorsymbol := 38; comment lesschar end greather char is notequal symbol; lesschar := 60; greatherchar := 62; notequalsymbol := 38; comment lesschar and equal char is lessequalsymbol; lessequalsymbol := 40; comment greather char and equal char is greatherequalsymbol; greatherequalsymbol := 42; lastdoubleclass := 42; comment double quote char class; charclass(34) := 59; doublequotechar := 34; doublequotesymbol := 59; firstseperatorclass := 59; comment space char class; charclass(32) := 60; blankchar := 32; comment new line , form feed and carrige return is class 20; endoflineclass := 62; nlchar := 10; charclass(10) := 62; ffchar := 12; charclass(12) := 62; crchar := 13; charclass(13) := 62; comment end medium class, the higest class number; endoffileclass := 64; emchar := 25; charclass(25) := 64; end initclasscharsymbol; comment the table contaion information about the name table when a niveau change occur; integer array niveautable(1:maxniveau,1:2); boolean procedure newniveau; begin comment the value of the first free in the niveau table entry in the name table is saved in the niveau table; if thisniveauno > maxniveau then newniveau := false else begin niveautable(thisniveauno,1) := ntabfree; thisniveau := ntabfree; thisniveauno := thisniveauno+1; end; end newniveau; boolean procedure removeniveau; begin comment removes all entry in the ntab and identifier texts connected to them until next niveau. ; integer searchindex,chain,index; comment find previus niveau; if thisniveauno -1 < 1 then removeniveau := false else begin thisniveauno := thisniveauno - 1; comment free all entreis ntab connected to thisniveauno; ntabfree := niveautable(thisniveauno,1); thisniveau := niveautable(thisniveau-1,1); for index :=1 step 1 until searchtablelength do begin chain := searchtable(index); for chain := chain while chain > ntabfree do chain := ntab(chain+entrynext); searchtable(index) := chain; end; end; end removeniveau; integer procedure allocate(elements); value elements; integer elements; begin comment allocate elementss in the ntab. result is index of first symbol ellocated; allocate := ntabfree; ntabfree := ntabfree + elements; if ntabfree > ntablength then fatalerror(<:ntab limit:>); end allocate; procedure disallocate(elements); value elements; integer elements; begin comment frees elementss in ntab; ntabfree := ntabfree - elements; if ntabfree < 1 then fatalerror(<:ntab limit zero:>); end disallocate; procedure includestackinentry(entry); value entry; integer entry; begin comment the entry is considered to be the latest inserted in ntab, a possible use of the the rest of ntab as stack is included in the ntab record, i.e the ntab records length is changed so the record length is j from entry to justbefore ntabfree; ntab(entry) := ntabfree - entry; end includestackinentry; procedure disallocatetoentry(entry); value entry; integer entry; begin comment this entry is considdered the last inserted, a possible stack use after this record is removed; ntabfree := entry + ntab(entry+entrylength); end disallocatetoentry; procedure changeentrylength(entry,change); value entry,change; integer entry,change; begin comment the latest created entry in name table is changed to the new length; if change > 0 then allocate(change); ntab(entry+entrylength) := ntab(entry+entrylength) + change; end changeentrylength; boolean procedure controldeclaration(symbol,entry); value symbol,entry; integer symbol,entry; comment control of a new identifier can be declared as a variable or a type, in the present niveau and care taken for parameters and record contents. ; begin if symbol = unknownname or ( symbol = namesymbol and entry < thisniveau ) or ( symbol = namesymbol and ( ntab(entry+entrytype) = recorcelementfixedentry or ntab(entry+entrytype) = reccordelementvariantentry)) then controldecleration := true else controldecleration := false; end controldeclaration; comment test procedures and texst facilityis; boolean array testb(1:20); integer testall, testgetsymb, testnametab; procedure initoftest; begin integer index; for index := 1 step 1 until 20 do testb(index) := false; testall := 1; testgetsymb := 2; testnametab := 3; end initoftest; boolean procedure test(index); value index; integer index; begin test := testb(testall) or testb(index); end test; comment error handling procedures; procedure fatalerror(errorstring); string errorstring; begin comment called after unrecorverable error, normaly table length violation. the only goto statement in the program; integer array errorline(1:stdlinelength); convertstring(errorline,errorstring); insertnlchar(errorline); listline(errorline); goto endprogram; end fatalerror; comment varius constants; integer nil; procedure initvariusconstants; begin comment varius generel constants is initialised in this procedure; comment nil is the terminal symbol. also used to assign variables indicate undifined condition, it schould be initialized to the max negative integer or another appropriate number. in a 24 bit 1 complement machine it is -8388607, in 2 complement -8288608; nil := -8388708; comment dummy is used for varius purposes and can not be expected thave any predefined value, specialy used in for sentences; dummy := 1234567; end initvariusconstants; comment varius variables; integer ntabfree, thisniveau, thisniveauno, dummy; procedure initvariusvariables; begin comment initialise varius variable; comment free pointer in name table and identifier table. the first symbol indexed by zero is not used; ntabfree := 1; comment the outmost niveau in a pascal program contain all predeclared identifiers, and is niveau 0, prefix niveau 1, program niveau 2, and procedures niveau 3.; thisniveauno := 0; comment points to thefirst entry in the name table containg entryes under thisniveauno; thisniveau := ntabfree; end initvariusvariables; comment global variables used in connection with code generation; integer whilelabno, replabno; procedure initofcodevariables; begin comment initializing of variables used in connection with code generation; comment label numbers used to destinguish labes generated from while and repeat statement; whilelabno := 0; replabno := 0; end initofcodevariables; procedure initofcodeconstants; begin comment initialising of constants used in conection with with code generation; end initofcodegeneration; procedure initgenerel; begin comment call of all init procedures. the order is critical betwen every group; comment first group; initvariusconstants; initclasscharsymbol; initvariusvariables; initofntabrecord; comment second group; initofsearchtable; initofsymbolconstants; comment third group; initofnametable; initofreservedwordsymbol; initofcodeconstants; comment fourth group; initofcodevariables; initoftest; initinputoutputvariables; end initgenerel; procedure scantest; begin integer i; next1; write(out,<:<10>NEXT:>,<<-dddd>,symbol1, <: INDEX::>,entry1,<: AUX::>,aux1, <: TEXT1: :>); i:=0; for i:= i+1 while i<= stdlinelength and text1(i) <> 0 do outchar(out,text1(i)); if text1(i) = 0 then outchar(out,38); end scantest; comment transformation procedures; comment the syntax graphs in the comment is in the following form. symbols is represented with their names or special charakters, fx : while + ; := <= const constructs definied by other graphs is represented as the name of teh construct enclosed in lessbraket and equalbraket, fx: <identifier> <prefix> <statement> arraows is represented with minuschars directly folowed by less braket or equal braket, fx: ---> ---->----- <---- ----<----- for shifting from one arrow line to another the charakter exclaration mark (!) is used. no direction is suplied. for syntaxgraps spreading over more lines a number enclosed in greather and lessbraket is used. fx : -----> <3> <3> ---->--- ; procedure program; begin comment sequential program is -> <prefix> -> <block> -> . -> ; prefix; block; end program; procedure prefix; begin comment prefix is --- <const definition> <-- ! ! -------------------------------> <1> ! ! --- <type definition> <-- <1> --> <prefix routines> --> <programheading> --> ; for dummy := next while symbol = namesymbol and ( aux = resconst or aux = restype ) do begin if aux = resconst then constdefinition else typedefinition; end; prefixroutines; programheading; end prefix; procedure constdefinition; begin comment constant definition is: --> const --> <identifier> --> = --> <constant> --> ; --> ! ! --------------------------------------- where the namesymbol const allready is detected. ; integer thisentry; for dummy := next while symbol <> reservedword do begin if controldeclaration(symbol,entry) then begin insertname(entry,text,constantentry,nil); if next0 = equalsymbol then begin constant; end else begin error(<:equalsign expected:>,skipreservedword); end; end else begin if symbol = namesymbol and ntab(entry+entrytype) <> reservedword then begin error(<: allready decleared identifier:>,skipreservedword); end else begin error(<:identifier expected:>,skipreservedword); end; end; end; end constdefinition; procedure constant; begin comment <constant> is : <constant> is: ----> <identifier> ----------------> ! ! !--> <enumeration constant> -->! ! ! !--> <real constant> --------->! ! ! ---> <string constant> ------->! ; integer index; next0; if symbol0= numbersymbol then begin indec := changeentrylength(entry,length0(text0)); movetext4(ntab,index,text0); comment type of the number is given in aux either real or integer type; ntab(entry+entrytypeid) := aux; end else if symbol0 = stringsymbol then begin ntab(entry+entrytypeid) := stringtype; index := changeentrylength(entry,length0(text0)); movetext4(ntab,index,text0); end else if symbol0 = charsymbol then begin ntab(entry+entrytypeid) := chartype; index := changeentrylength(entry,1); ntab(entry+index) := aux0; end else if symbol0 = namesymbol and aux0 = constantentry then begin ntab(entry+entrytypeid) := ntab(entry0+entrytypeid); end else begin error(<:illegal constant:>,skipreservedword); end; end constant; procedure typedefinition; begin comment type definitions is: -->type--><identifier>-->=--><type>--> ; --> ! ! ------------------------------------ where the reserved word type allready is met. ; integer thisentry; for dummy := next while symbol <> reservedword do begin if controldeclaration(symbol,entry) then begin insertname(entry,text,typedecentry,nil); if next0 = equalsymbol then begin comment typedeclaration; typedec(entry+typeidentry); end else begin error(<:equalsign exepcted:>,skipreservedword); end; end else if symbol = namesymbol then begin error(<:allready declared identifier:>,reservedword); end else begin error(<:identifier expected:>,reservedword); end; end; end typedefinition; procedure typedec; begin comment typedec is named type in the syntax graphs. typedec is : ----><identifier>--------------->-- !--><enumeration type>-->--! !--><real type>--------->--! !--><array type>-------->--! !--><record type>------->--! !--><set type>---------->--! !--><pointer type>------>--! ; next0; if symbol0 = reservedwordsymbol then begin if aux0 = resarray then begin arraytype; end else if aux0 = resrecord then begin recordtype; ntab(entry+entrytypeid) := recorddecentry; end else if aux0 = resset then begin settype; ntab(entry+entrytypeid) := setdecentry; end else begin error(<:illegal reserved word:>,skipsemicolon); end; end else if symbol0 = pointersymbol then begin pointertype; end else if symbol0 = namesymbol then begin if entry = typedecentry then begin comment previus defined entry; index := allocate(2); ntab(index) := previusdefinedtype; ntab(index+1) := entry; end else begin error(<:XXXXXX:>,skipsemicolon); end; end else if symbol0= namesymbol and aux0 = enumerationconstantentry then begin comment a subrangerefference type; index := allocate(3); ntab(index) := reffferencesubrance; comment insert low range refferange; ntab(index+1) := entry0; if next <> subrangesymbol then begin error(<:subrangesymbol expected:>,semicolonsymbol); end else begin next0; if sumbol0 <> namesymbol and aux0 = enumerationconstant then begin ntab(index+2) := entry0; comment control types; if ntab(ntab(index+1)+6) <> ntab(ntab(index+2)+6) then begin error(<:incompatibel subrange types:>,skipsemicolon); end else begin comment controlmin max value; movetext5(text,ntab,ntab(index+1)+7); convertintegertext(lowrange,text); movetext5(text,ntab,ntab(index+2)+7); convertintegertext(highrange,text); if lowrange > highrange then begin error(<:subrange value error:>,skipsemicolon); end; end; end; end else if symbol0 = numbersymbol then begin comment a subrange integer type; index :=allocate(3); ntab(index) := subrangenumbertype; convertintegertext(lowrange,text0); ntab(index+1) := lowrange; if next0 <> subrangesymbol then begin error(<:subrange expected:>,semicolonsymbol); end else begin next0; if symbol0 <> numbersymbol then begin error(<:subrange type error:>,semicolonsymbol); end else begin convertintegertext(highrange,text0); ntab(index+1) := highrange; comment control min max value; if lowrange > highrange then begin error(<:subrange value error:>,skipsemicolon); end; end; end; end else if symbol0=leftbraketsymbol then begin comment non standard enumeration type. var or type dec. set to next dec type. ; comment call scan identifier list, including rigth braket; identifierlist; end else begin error(<: type declaration expected:>,skipsemicolon); end; end typedec; procedure arraytype; begin integer index; index := allocate(1); ntab(index) := arraytypedecblock; next0; if symbol0 <> leftarraybrakket then begin error(<:left array braket expected:>,semicolonsymbol); end else begin arraydimensions; typedec; end; end arraytype; procedure identifierlist; begin comment identifierlist is: -->(--><identifier>-->)--> ! ! ---<--,<----- and is transformed to: enumeration type and a subrange record is placed into the stack. all identifiers is inserted inthe name table as constants and typeid as next declared type. their value is value of nextvalue, which is inserted as normal for constants. ; integer nextconstvalue; integer index; nextconstvalue := 0; index := allocate(3); ntab(index) := enumerationdeclaration; previus := index+1; for dummy := next1 while symbol = unknownnamesymbol do begin comment as type is inserted refference to next, which is either the variable or typedecleration; if controldecleration(symbol,entry) then insert(text1,entry1,enumerationstantentry,nil); ntab(previuslink) := entry1; previuslink := entry1 +5; comment insert entry to enumeration declaration; ntab(allocate(1)) := index; nextconstvalue := nextconstvalue+1; converttextinteger(constanttext,nextconstantvalue); index := allocate(length0(constanttext)); movetext4(ntab,index,constanttext); includestackinentry(entry1); end; ntab(index+2) := nextconstvalue; if symbol1 <> rigthparsymbol then begin if symbbol1 = namesymbol then error(<:identifier allready declared:>); else error(<:identifier expected:>,skipsemicolon); end; end identifierlist; procedure vardecleration; begin comment the reserved word 'var' is met; integer previusdeclaredtype; comment contain information abaut the previus delclered type; previusdeclaredtype := nil; next; if controldecleration(sy,bol,entry) then begin insert(entry,text,variabledec,nil); if next0 <> colonsymbol then begin error(<:colon expected:>,semicolonsymbol); end else begin typedec; includestackinentry(entry); if ntab(entry+5) = previusdefinedentry then definitionentry := ntab(entry+6) else definitionindex := entry+5; definitiontype := ntab(definitionindex); if definitiontype = pointertype then begin declareinteger(<:po:>,entry); end if definitiontype = subrangerefferencetype then begin declareinteger(<:uf:>,entry); end else if difinitiontype = subrangenumbertype then begin declareinteger(<:un:>,entry); end else if definitiontype = enumerationtype then begin delareinteger(<:en:>,entry); end end; end; if previusdeclaredtype <> nil then begin outcodechar(semicolon); outcodenl; end; end vardecleration; procedure declare(type,prefix,entry); value dectype,entry; string prefix; begin if type = previusdecleredtype then begin outcodechar(commachar); outcodenl; movetext6(text,ntab,entry-namelength); converttexttostring(text1,prefix); concat(text1,text); end declare; procedure prefixroutines; begin comment prefix routines is: <--<procedure heading><-- ! ! -->-------------------------------> ! ! <--<function heading><-- ; if symbol = reservedword for dummy := dummy while (symbol = reservedword and (aux = resfunction or aux = resprocedure) do begin if aux = resfunction then functionheading else if aux = resprocedure then procedureheading; end; end prefixroutines; procedure compoundstatement; begin comment compound statement is: where the reserved word begin allready is met. ; end compoundstatement; procedure statement; begin comment statement is: ; next; is symbol = reservedverd then begin if aux = resbegin then begin comment compoundstatement; compoundstatement; end else if aux = resif then begin istatement; end else if aux = resfor then begin forstatement; end else if aux = reswhile then begin whilestatement; end else if aux = resrepeat then begin repeatstatement; end else if aux = reswith then begin withstatement; end else begin error(<:illegal reserved word, statement expected:>,skipsemicolon); end else if symbol = namesymbol or symbol=unknownname then begin if symbol = unknownname then begin error(<:undeclared:>); insert(entry,text,notype,nil); end; comment after meeting a name it can be either a assignment statement or a routinecall. A routine call can be a call of a function as the call of a type procedure in algol. if the next symbol is an assignment symbol then it is assumed to be a assignment statement else a routinecall. next and next0 have the 2 first symbols in the statement. ; if next0 = assignmentsymbol then assignmentstatement else routinecallstatement; end else begin error(<:statement expected:>,skipsemicolon); end; end statement; procedure assignmentstatement; begin comment assignmentstatement used for assignment. assignment is: --><variable>-->:=--><expr>--> An assignment defines the assignment of an expression value to a variable. The varable and the expression must be compatible. The variable must not be a constant parameter. transformed to algol as: --><varaible>-->:=--><expr>--> the variable name is in next, the assignmentsymbol is in next0. ; integer assignmenttype; end assignmentstatement; procedure ifstatement; begin comment if statement is: ----- where If allready is met. ; outcodestring(<:if :>); if expr <> booleantype then begin error(<:boolean expresion expected:>,skipsemicolon); end; comment after expr the reserved word then schould be in next; if symbol <> resthen then begin error(<:then expected:>,skipreservedwordsemicolon); end else begin outcodestring(<: then:>); outcodenl; end; statement; if symbol = reselse then begin outcode(<: else :>); outcodenl; statement; end; end ifstatement; procedure forstatement; begin comment the for statement is: where the reserved word for allready is met; integer controlvariabletype; outcodestring(<:for :>); next; if symbol = nametype then begin outcodestring(<:si:>); movetext5(text,ntab,ntab(entry+entryrefname)); outcodetext(text); if next <> assignmentsymbol then begin error(<:assignment expected:>,skipsemicolon); end else begin outcodestring(<::=:>); if expr <> controlvariabletype then begin error(<:expresion type error:>,skipsemicolon); end else begin comment after expresion the reserved word to or downto is met from call of next; if symbol <> resto and symbol <> resdownto then begin error(<:to or downto expected:>,skipsemicolon); end else begin if symbol = resto then outcodestring(<: step 1 until :> else outcodestring(<: step -1 until :>); if expr <> controlvariabletype then begin error(<:expresion type error:>,skipsemicolon); end else begin comment the reserved word do is met in expresion comment after expresion the reserved word do is met from call of next; if symbol <> resdo then begin error(<:do expected:>,noskip); end; outcodestring(<: do:>); outcodenl; statement; end; end; end; end; end else begin error(<:enumeration type variable expected:>,skipsemicolon); end; end forstatement; procedure whilestatement; begin comment while statement is: -->'while'-->expr-->'do'-->statement--> where the namesymbol 'while' allready is met. transformed to algol as: -->'whilelab<no>:'--> -->'if -,('<expr>') then goto whilelab<no+1>'--> --> <statement><semicolon> --> ! ! ---------------------------- --'goto whilelab<no>'<semicolon> --> -->whilelab<no+1><semicolon>--> ; integer thiswhilelabelno; integer array whilenotext,whileno1text(1:12); thiswhilalabelno := whilelabno; whilelabno := whilelabno +1; thiswhilelabelno1 := whilelabno; whilelabno := whilelabno +1; outcodestring(<:whilelabel:>); converttextinteger(whilenotext,thiswhilelabno); outcodetext(whilenotext); outcodechar(colonchar); outcodechar(semicolonchar); outcodenl; outcodestring(<:if -,(:>); expr; if symbol <> name and aux <> resdo then begin error(<: do expected:>,skipsemicolon); end; outcodestring(<:) then goto whilelab:>); outcodetext(whileno1text); outcodechar(semicolonchar); statement; outcodestring(<:goto whilelab:>); outcodetext(whilenotext); outcodechar(semicolonchar); outcodenl; outcodestring(<:whilelab:>); outcodetext(whileno1text); outcodechar(colonchar); end whilestatement; procedure repeatstatement; begin comment repeat statement is: -->'repeat'-->statement-->'until'-->expr--> ! ! ------<semicolon><------ where the name 'repest' is met. translated to algol as: -->'replab<no>:'-->statement<semicolon>--> ! ! ------------- -->'if -,('expr') then goto replab<no>'--> ; integer thisreplabno; integer array repnotext(1:12); thisreplabno := replabno; replabno := replabno+1; converttextinteger(repnotext,thisreplabno); outcodetext(repnotext); outcodenl; outcodestringstring(<:::>); statement; if symbol = name and aux = resuntil then begin outcodenl; outcodestring(<:if -,(:>); expr; outcodestring(<:) then goto replab:>); outcodetext(repnotext); outcodechar(semicolonchar); end else begin error(<:until expected:>,skipsemicolon); end end repeatstatement; comment start program; initgenerel; program; end table dec. block; comment label called from procedure fatalerror; endprogram: end outhermost block; ▶EOF◀