MyTable=TSymbolTable[3] FindVarName = proc (src:string) returns (string,string) signals (CMP_SyntaxError) key:array[char]:=array[char]$create(0) value:string found:bool:=false for c:char in string$chars(src) do if ~(c=' ') then found:=true if (c='"' | c='=') then break end array[char]$addh(key,c) else if (c=' ') & found then break else signal CMP_SyntaxError end end end if string$indexc('"',src)=0 then signal CMP_SyntaxError end Value:=string$rest(src,string$indexc('"',src)+1) if string$indexc('"',Value)=0 then signal CMP_SyntaxError end Value:=string$substr(Value,1,string$indexc('"',Value)-1) return (string$ac2s(key),value) end FindVarName Compile = proc (inp,outp:stream) signals (CMP_BadArg(string)) if ~stream$can_read(inp) then signal CMP_BadArg("input file") end if ~stream$can_write(outp) then signal CMP_BadArg("output file") end Table:MyTable Key:string Value:string ThisLine:string Dept:int:=0 Indent:array[char]:=array[char]$Create(0) Table:=MyTable$Create() while (true) do ThisLine:=stream$getl(inp) % stream$putl(outp,ThisLine) if string$indexs("procedure",ThisLine)>0 then MyTable$Enter(Table) stream$puts(outp,string$ac2s(indent)) stream$putl(outp,"Enter new procedure frame") dept:=dept+3 Indent:=array[char]$fill(0,dept,' ') end if string$indexs("endproc",ThisLine)>0 then MyTable$Leave(Table) dept:=dept-3 Indent:=array[char]$fill(0,dept,' ') stream$puts(outp,string$ac2s(indent)) stream$putl(outp,"Leave procedure frame") end if string$indexs("var",ThisLine)>0 then % variable definition stream$puts(outp,string$ac2s(indent)) ThisLine:=string$rest(ThisLine,string$indexs("var",ThisLine)+4) begin Key,Value:=FindVarName(ThisLine) end except when CMP_SyntaxError: stream$puts(outp,"*** Syntax error at definition: var ") stream$putl(outp,ThisLine) continue end stream$puts(outp,"Storing '") stream$puts(outp,Key) stream$puts(outp,"' with the defined value '") stream$puts(outp,Value) stream$putl(outp,"'") begin Value:=MyTable$Store(Table,Key,Value) end except when SYM_Redefine(s:string): stream$puts(outp,string$ac2s(indent)) stream$puts(outp,"*** Redefinition error: ") stream$putl(outp,s) end end if string$indexc('#',ThisLine)>0 then % compiler directive calling stream$puts(outp,string$ac2s(indent)) ThisLine:=string$rest(ThisLine,string$indexc('#',ThisLine)+1) if string$indexs("report",ThisLine)>0 then Key:=string$rest(ThisLine,string$indexs("report",ThisLine)+7) stream$puts(outp,"### Reporting current value of ") stream$puts(outp,Key) stream$puts(outp,": ") begin Value:=MyTable$Search(Table,Key) stream$putl(outp,Value) end except when SYM_NotFound: stream$putl(outp,"NOT FOUND") end else stream$puts(outp,"*** Unknown compiler directive: ") stream$putl(outp,ThisLine) end end end except when End_Of_File: end end Compile start_up=proc() Compile(stream$open(file_name$parse("source.in"),"read"),stream$primary_output()) end start_up