Här kommer nu an massa bifogade filer dessa finns också elektroniskt på ~/d94sz/proj/ bra att ha komandon är: mlex - genererar lex.sim msyn - genererar kompilatorn (syn) qc - kompilerar och assemblerar och länkar, ut kommer .s och .3add Programfiler: --------------------------------lex.tra------------------------------------------ ###Name ###End ###INTERNAL OUTPUT ###END ###FEATURES WriteOutSymbol Single ###END ###INPUT ASCII ###END ###OUTPUT ##NONATTRIBUTED "{" "}" "(" ")" "[" "]" "@" "~" "»" "«" "?" "!" ":)" ":(" ".#" ".$" "·#" "·$" "," ";" "=" "+" "-" "/" "*" "=?" ">?" "=+ ##END ##RULE = / / / / /' ' ##END ##RULE =(load (load )* ) KLART #DECLARATIONS text res_txt; #END #ACTIONS ACTION load res_txt:-res_txt&" "; res_txt.sub(res_txt.length,1).putchar(char(Intoken)); ACTION KLART if not Writeoutsymbol(res_txt, %"{" , %"·$" ) then begin errorline; outtext("LEX:Reserverat ord är dåligt :"&res_txt); outimage; end; #END ##END ##RULE =(load (load )*) KLART #DECLARATIONS text op_txt; #END #ACTIONS ACTION load op_txt:-op_txt&" "; op_txt.sub(op_txt.length,1).putchar(char(Intoken)); ACTION KLART if not Writeoutsymbol(op_txt,%",",%"$") then begin errorline; outtext("LEX:Operator är dåligt :"&op_txt); outimage; end; #END ##END ##RULE = init (mulAdd )+ KLART #ATTRIBUTES integer Val; #END #ACTIONS ACTION init Val := 0; ACTION mulAdd Val := 10 * Val + Intoken - rank('0'); ACTION KLART &"const" := Val; Write(%"const"); #END ##END ##RULE = load (load ( / ))* KLART #DECLARATIONS text id_txt; character ch; #END #ACTIONS ACTION load id_txt:-id_txt&" "; ch := char(Intoken); ! if letter(ch) And then ch > 'Z' then ch:=char(Rank(ch)-32); !konvertera till stora bokstäver; ! if ch = 'å' then ch := 'Å' else if ch = 'ä' then ch := 'Ä' else if ch = 'ö' then ch := 'Ö'; id_txt.sub(id_txt.Length,1).putchar(ch); ACTION KLART if not WriteOutSymbol(id_txt,%"{",%"nein") then !ifall det det parsas fel; Begin &"id" :- id_txt; Write(%"id"); End; #END ##END ##RULE = '"' (load )* '"' KLART #DECLARATIONS text str_txt; #END #ACTIONS ACTION load str_txt:-str_txt&" "; str_txt.sub(str_txt.Length,1).putchar(char(Intoken)); ACTION KLART &"string" :- str_txt; Write(%"string"); #END ##END ##RULE = / 'å' / 'Å' / 'ò' / 'Ò' / 'ô' / 'Ô' / 'ù' / 'Ù' / 'õ' / 'Õ' / 'é' / 'É' / 'ï' / 'Ï' / 'ð' / 'Ð' / 'þ' / 'Þ' / 'á' / 'Á' / 'ó' / 'Ó' / 'ä' / 'Ä' / 'æ' / 'Æ' / 'ç' / 'Ç' / 'è' / 'È' / 'ê' / 'Ê' / 'ë' / 'Ë' / 'ì' / 'Ì' / 'ö' / 'Ö' / 'ä' / 'Ä' / 'ú' / 'Ú' / 'ø' / 'Ø' / 'ã' / 'Ã' / 'ö' / 'Ö' / 'â' / 'Â' ##END ##RULE = / '_' / '¤' / '^' / '`' / '%' / '£' / '§' / 'ª' / '¼' / '¾' / '±' / '¡' / '²' / '¢' / '³' / '¤' / 'µ' / '¦' / '¯' / '¸' / '¨' / '¹' / '©' / '°' / '½' / '¿' / 'ñ' / 'Ñ' / '÷' / '×' / '¬' / '®' / 'º' / '­' / 'ß' ##END ##RULE = '{' / '}' / '(' / ')' / '[' / ']'/ '@' / '~' / '»' / '«' / '?' / '!' / ':' / '.' / '·' ##END ##RULE = '$' / '#' / '(' / ')' ##END ##RULE = ','/ ';' / '=' / '+' / '-' / '/' / '*' / '>' / '<' / '&' / '|' / '\' / '#' / '$' ##END ##RULE = '?' ##END ##RULE = / / '#'/ '$' / / / ' ' / ##END ###END --------------------------------syn.tra------------------------------------------ ###Name ###End ###INTERNAL INPUT FROM lex.sim ###END ###FEATURES WriteOutSymbol Single ###END ###INPUT ##NONATTRIBUTED '{' '}' '(' ')' '[' ']' '@' '~' '»' '«' '?' '!' ':)' ':(' '.#' '.$' 's#' 's$' ',' ';' '=' '+' '-' '/' '*' '=?' '>?' ' remove colorhilti bug in Tralala-Abbrev in emacs; %include SymbolTable.sim %include asm.sim % external procedure calldebugger; BlockDescription class BlkDes(nextRelAdd);integer nextRelAdd; begin integer StaticLevel; end; VariableDescription class VarDes(Type,lab,RelAddr,level); integer Type;text lab; integer RelAddr,level; begin integer Kind; end; link class level(i);integer i; !-- Håller reda på var gränserna går för locala variabler; begin integer GetLevel; GetLevel:=i; end; procedure ErrorLine; begin outtext("ERROR @ "); outint(LineNumber,0); outtext(":");outchar('"'); Outtext(copy(Image__).strip); outchar('"'); outtext(" :"); Breakoutimage; end; procedure Error(txt); text txt; begin outtext("Error:");outtext(txt);outimage; end; procedure DelTemp; begin TempNr:=TempNr-1; end; ref(temparg) procedure NewTemp(type);Integer type; !-- Ger ny temorär variabel, klarar högst MaxInt variable; begin TempNr:=TempNr+1; NewTemp:-new TempArg(fixtype(Type),TempNr); end; text procedure GetNewLabel; begin text lb; tempLB:=tempLB+1; lb:-blanks(log10(tempLB)+.5); lb.putint(tempLB); lb.strip; GetNewLabel:-"L"&lb; end; procedure Emit(opn);ref(opcode) opn; begin opn.into(genprog); opn.treadd; opn.FixAsm; ! opn.asm; end; procedure Emit2(opn);ref(opcode) opn; !-- för kod i data segmentet; begin opn.into(gendata); ! opn.treadd; opn.FixAsm; end; integer procedure GetLevelStop; begin GetLevelStop:=LevelH.last qua level.GetLevel; end; procedure gctemp(place); ref(arg) place; begin if place in temparg then deltemp; if place==none then begin outtext("WARNIGN INTERNAL ERROR");outimage; end; end; procedure clearTemp; TempNr:=0; integer procedure fixtype(i);integer i; begin if i=STATICINTE or i=STATICBOOL then fixtype:=i-2 else fixtype:=i; end; integer TempNr; !Nummret på aktuell temporär variabel; integer TempLB; !Nummret på aktuell temporär unik Label; character TAB='!9!',nxx=','; integer INTE=0,BOOL=1,STATICINTE=2,STATICBOOL=3,FUNCTION=4,RETURN=5; integer WORDSIZE=4; ref(SymbolTable) ST; ref(head) genprog,gendata,levelH; ref(OPCode) op; ref(outfile) SourceCode; text sourcename; ###END ###SYNTAXRULES ##RULE = Klart #ACTIONS ACTION Klart ! outtext("Kompilerat ett prog :)"); ! outimage; #END ##END ##RULE = '{' enterBlk getantdef * * '}' exitblk #ATTRIBUTES ref(BlkDes) BD; integer antdef; #END #ACTIONS ACTION enterBlk BD:-ST.CurrentBlock; ST.EnterBlock(new BlkDes(BD.nextRelAdd)); ACTION getantdef antdef:=&.antdef; if antdef > 0 then emit(new Aallocfunc("allocfunc",new constArg(INTE,antdef*WORDSIZE))); ACTION exitblk if antdef > 0 then emit(new ADeAllocfunc("deallocfunc",new constArg(INTE,antdef*WORDSIZE))); ST.ExitBlock; #END ##END ##RULE = ((('.#' 'id' number (',' 'id' number)* )/ ('s#' 'id' staticnumber (',' 'id' staticnumber)* )/ ('.$' 'id' bool (',' 'id' bool )*)/ ('s$' 'id' staticbool (',' 'id' staticbool )*)) ';')* #ATTRIBUTES integer boolsk; ref(VarDes) VD; ref(BlkDes) BD; integer antdef; #END #ACTIONS ACTION number if ST.AlreadyDeclared(&'id') then begin ErrorLine; Outtext("Variabeln "); outtext(&'id'); outtext(" är ju redan deklarerad"); Outimage; end; BD:-ST.CurrentBlock; VD:-new VarDes(&'id',INTE,"Error",BD.nextRelAdd,ST.CurrentLevel); BD.nextRelAdd:=BD.nextRelAdd+4; ST.DeclareVariable(VD); !info emit2(new ADeclar(&'id'&VD.lab,new ConstArg(0))); !emit2(new ADeclar(VD.lab,new ConstArg(0))); ! emit(new Aallocfunc("allocfunc",new idarg(VD))); antdef:=antdef+1; ACTION StaticNumber if ST.AlreadyDeclared(&'id') then begin ErrorLine; Outtext("Variabeln "); outtext(&'id'); outtext(" är ju redan deklarerad"); Outimage; end; VD:-new VarDes(&'id',STATICINTE,getnewlabel,99,ST.CurrentLevel); ST.DeclareVariable(VD); !info emit2(new ADeclar(&'id'&VD.lab,new ConstArg(0))); emit2(new ADeclar(VD.lab,new ConstArg(INTE,0))); ACTION bool if ST.AlreadyDeclared(&'id') then begin ErrorLine; Outtext("Variabeln "); outtext(&'id'); outtext(" är ju redan deklarerad"); Outimage; end; BD:-ST.CurrentBlock; VD:-new VarDes(&'id',BOOL,"error",BD.nextRelAdd,ST.CurrentLevel); BD.nextRelAdd:=BD.nextRelAdd+4; ST.DeclareVariable(VD); !info emit2(new ADeclar(&'id'&VD.lab,new ConstArg(0))); !emit2(new ADeclar(VD.lab,new ConstArg(0))); ! emit(new Aallocfunc("allocfunc",new idarg(VD))); antdef:=antdef+1; ACTION StaticBool if ST.AlreadyDeclared(&'id') then begin ErrorLine; Outtext("Variabeln "); outtext(&'id'); outtext(" är ju redan deklarerad"); Outimage; end; VD:-new VarDes(&'id',STATICBOOL,getnewlabel,99,ST.CurrentLevel); ST.DeclareVariable(VD); !info emit2(new ADeclar(&'id'&VD.lab,new ConstArg(0))); emit2(new ADeclar(VD.lab,new ConstArg(BOOL,0))); ACTION comit #END ##END ##RULE = clr / ';' clr / clr / / clr #ACTIONS ACTION dummy; ACTION clr; ClearTemp; #END ##END ##RULE = / ##END ##RULE = load (( '=?' cmpIt / '>?' gt / ' lt) / $) #DECLARATIONS ref(arg) oldp; boolean minus; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy; Action load place:-&.place; Action cmpIt; Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); place:-NewTemp(BOOL); Emit(new cmp("CMP",Oldp,&.Place,Place)); end else if oldp.type=BOOL and &.place.type=BOOL then begin gctemp(oldp); gctemp(&.place); place:-NewTemp(BOOL); Emit(new cmp("CMP",Oldp,&.Place,Place)); end else begin ErrorLine; Outtext("Operatorn =? vill ha Samma typ på båda sidor om sig"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; Action gt; Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); place:-NewTemp(BOOL); Emit(new Agt("GT",Oldp,&.Place,Place)); end else begin ErrorLine; Outtext("Operatorn >? vill heltals typer på båda sidor om sig"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; Action lt; Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); place:-NewTemp(BOOL); Emit(new Alt("LT",Oldp,&.Place,Place)); end else begin ErrorLine; Outtext("Operatorn = load ( ('+' addme ) / ('-' subme ) / ('|' orme ))* #DECLARATIONS ref(arg) oldp; boolean minus; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy; ACTION Load place:-&.place; Action Addme Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); Place:-newtemp(INTE); Emit(new add("ADD",oldp,&.place,place)) end else begin ErrorLine; Outtext("Addition mellan annat änn heltals typer är olämpligt"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; Action Subme Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); Place:-newtemp(INTE); Emit(new sub("SUB",oldp,&.place,place)); end else begin ErrorLine; Outtext("Subtraktion mellan annat änn heltals typer är olämpligt"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; Action Orme Oldp:-place; if oldp.type=BOOL and &.place.type=BOOL then begin gctemp(oldp); gctemp(&.Place); place:-NewTemp(BOOL); Emit(new Aor("OR",Oldp,&.Place,Place)); end else begin ErrorLine; Outtext("Or bör göras mellan booliska typer"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; #END ##END ##RULE = load (('*' mulme )/ ('/' divme)/ ('&' andme))* #DECLARATIONS ref(arg) oldp; boolean minus; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy; ACTION Load place:-&.place; ACTION mulme Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); Place:-newtemp(INTE); Emit(new mul("MUL",oldp,&.place,place)); end else begin ErrorLine; Outtext("Heltalstyper är det enda du kan multiplicera"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; ACTION divme Oldp:-place; if oldp.type=INTE and &.place.type=INTE then begin gctemp(oldp); gctemp(&.place); Place:-newtemp(INTE); Emit(new div("DIV",oldp,&.place,place)); end else begin ErrorLine; Outtext("Heltalstyper är det enda du kan Dividera"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; ACTION Andme Oldp:-place; if oldp.type=BOOL and &.place.type=BOOL then begin gctemp(oldp); gctemp(&.place); place:-NewTemp(BOOL); Emit(new Aand("AND",Oldp,&.Place,Place)); end else begin ErrorLine; Outtext("And bör vara mellan Booliska typer"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; #END ##END ##RULE = ('(' load ')')/ loadid/ ('-' neg)/( '\' not)/ 'const' loadconst / loadbconst/ '#' castInt/'$' CastBool/ loadSysin #DECLARATIONS ref(arg) oldp; boolean minus; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy; ACTION Load place:-&.place; ACTION Loadid place:-&.place; ACTION Neg if &.place.type<>INTE then begin ErrorLine; Outtext("Du kan ju inte ta - på en boolisk typ"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; place:-&.place; Emit(new Aneg("NEG",place)); ACTION Not if &.place.type<>BOOL then begin ErrorLine; Outtext("Du kan ju inte ta \ på en heltalstyp"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; place:-&.place; Emit(new Anot("NOT",Place)); ACTION Loadconst place:-NewTemp(INTE); emit(new move("MOV",new ConstArg(INTE,&'const'),place)); ACTION Loadbconst if &.place.type<>BOOL then begin ErrorLine; Outtext("Den booliska konstanten är ju inte boolsk"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; place:-&.place; Action castInt if &.place.type<>BOOL then begin ErrorLine; Outtext("Typkonvertering till heltal kräver en boolisk typ"); outimage; ErrorLine; Outtext("Du har antagligen en typkonvertering för mycket"); outimage; end; place:-&.place; place.type:=INTE; Action castBool if &.place.type<>INTE then begin ErrorLine; Outtext("Typkonvertering till boolisk typ kräver en heltalstyp"); outimage; ErrorLine; Outtext("Du har antagligen en typkonvertering för mycket"); outimage; end; Place:-&.Place; Emit(new cmp("CMP",new ConstArg(INTE,0),Place,Place)); Emit(new Anot("NOT",Place)); place.type:=BOOL; ACTION LoadSysin place:-&.place; #END ##END ##RULE = 'ja' true / 'nein' false #ATTRIBUTES ref(arg) Place; #END #ACTIONS Action dummy; Action true; place:-NewTemp(BOOL); emit(new move("MOV",new ConstArg(BOOL,-1),place)); Action false; place:-NewTemp(BOOL); emit(new move("MOV",new ConstArg(BOOL,0),place)); #end ##END ##RULE = '@' 'id' addFun '(' enterBlk getantdef')' ladda exitblk #DECLARATIONS ref(VarDes) VD,t; ref(vardes) vh; ref(BlkDes) blockinfo,funkblock; ref(BlkDes) BD; text lb; ref(BlkDes) blockinfo2,funkblock2; integer i,antdef; #END #ACTIONS ACTION addFun lb:-GetNewLabel; emit(new AGoto("goto",new LabelArg(INTE,lb))); if ST.AlreadyDeclared(&'id') then begin Errorline; Outtext("Funktionen "); Outtext(&'id'); outtext(" är ju redan deklarerad"); end; VD:-new VarDes(&'id',FUNCTION,getnewlabel,99,ST.CurrentLevel); t:-VD; ST.DeclareFunction(VD ); !info emit(new ALabel(&'id'&VD.lab)); emit(new ALabel(VD.lab)); ACTION enterBlk ST.EnterBlock(new BlkDes(0)); new Level(ST.CurrentLevel).into(LevelH); t.level:=ST.CurrentLevel; !-- Fixa så man kan göra rekursiva procedurer; ACTION getantdef antdef:=&.antdef+1; !ant defs + return; emit(new Aallocfunc("allocfunc",new constArg(INTE,antdef*WORDSIZE))); ACTION ladda if ST.AlreadyDeclared("..return") then begin ErrorLine; Outtext("Variabeln ..return används internt, så låt bli den.");Outimage; end; BD:-ST.CurrentBlock; VD:-new VarDes("..return",RETURN,"Error Return",BD.nextRelAdd,ST.CurrentLevel); BD.nextRelAdd:=BD.nextRelAdd+4; ST.DeclareVariable(VD); ! emit(new Aallocfunc("allocfunc",new idarg(VD))); st.LookUpDeclaration(t.getvarname,blockinfo2,funkblock2); vh:-ST.FirstDeclaration; while vh.type<>RETURN do begin BD:-ST.currentBlock; emit(new fununload("UNload", new StIdArg(INTE,vh,BD.nextRelAdd-vh.reladdr),i)); ! obs Omvänd parameter följd; i:=i+1; vh:-ST.nextdeclaration; end; ACTION exitblk VD:-ST.LookUpDeclaration("..return",blockinfo,funkblock); if VD==none then begin ErrorLine; Outtext("..return är inte deklarerad i den här blocknivån. Gör om.");Outimage; end; BD:-ST.currentBlock; emit(new Afunload("funload", new StIdArg(INTE,VD,BD.nextRelAdd-vd.reladdr))); emit(new ADeAllocfunc("deallocfunc",new constArg(INTE,antdef*WORDSIZE))); emit(new Areturn("return")); ST.ExitBlock; LevelH.last.out; emit(new ALabel(lb)); #END ##END ##RULE = 'id' lookup (( '(' var1 (( check (',' var check )*)/$) ')' parcheck funcall)/ (('=' calc tildel) /($ variabel))) #DECLARATIONS integer parnr; ref(VarDes) VD,VDi; ref(arg) newp; ref(BlkDes) blockinfo,funkblock; ref(BlkDes) BD; integer i; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy ACTION lookup parnr:=0; VD:-ST.LookUpDeclaration(&'id',blockinfo,funkblock); VDi:-VD; if VD=/=none and then (VD.Type= FUNCTION or VD.Type =STATICINTE or VD.Type=STATICBOOL or VD.level >= GetLevelStop) then begin !ok; end else begin ErrorLine; Outtext("Du har nog glömt att deklarera "); outtext(&'id');outtext("."); Outimage; end; ACTION var1 i:=0; if funkblock==none then begin ErrorLine; Outtext("Funktionen du använde finns ju inte.");Outimage; end else begin VD:-ST.FirstDeclaration; emit(new Aallochead("allochead")); end; ACTION check parnr:=parnr+1; % outtext("check");outimage; if funkblock==none then begin ErrorLine; Outtext("Funktionen du använde finns ju fortfarande inte."); Outimage; end else begin if &.place in TempArg then begin if VD=/=none and then VD.Type<>RETURN and then VD.Type=&.place qua TempArg.Type then begin !ok; emit(new Aparam("param",&.place,i)); i:=i+1; gctemp(&.place); end else begin if VD=/=none and then VD.Type<>RETURN then begin ErrorLine; Outtext("Parameter (ID'n menar jag) nr ");outint(parnr,0); outtext(" är av fel typ."); outimage; end else begin ErrorLine; Outtext("Du har anget för många parametrar."); outimage; end; end; end else if VD=/=none and then VD.Type<>RETURN and then VD.Type=INTE then begin !ok; emit(new Aparam("param",&.place,i)); i:=i+1; gctemp(&.place); end else begin if VD=/=none and then VD.Type<>RETURN then begin ErrorLine; Outtext("Parameter nr ");outint(parnr,0); outtext(" är av fel typ."); outimage; end else begin ErrorLine; Outtext("Du har anget för många parametrar."); outimage; end; end; end; ACTION var if funkblock==none then begin ErrorLine; Outtext("Funktionen du använde finns ju inte. Sa jag ju."); Outimage; end else begin VD:-ST.NextDeclaration; end; ACTION parcheck if funkblock==none then begin ErrorLine; Outtext("Funktionen du ... Oj vad jag tjatar!"); Outimage; end else begin VD:-ST.NextDeclaration; if VD=/=none and then VD.Type<>RETURN then begin if VD=/=none then begin ErrorLine; Outtext("För få parametrar till funktionen."); Outimage; end; end; end; ACTION funcall if VDi=/=none then begin newp:-new IdArg(Fixtype(VDi.Type),VDi); place:-NewTemp(INTE); emit(new Acall("call",newp,parnr)); emit(new Adealloc("dealloc",newp)); emit(new Afunstore("funstore",place)); end else place:-newtemp(INTE); ACTION alock ACTION calc begin place:-&.place; end; ACTION tildel if VDi=/=none then begin if VDi.type<> place.type then begin ErrorLine; Outtext("Typerna är inte kompatibla"); outimage; ErrorLine; Outtext("Du har antagligen glömt en typkonvertering"); outimage; end; gctemp(place); newp:-NewTemp(VDi.Type); Emit(new move("MOV",place,newp)); if VDi.Type=INTE or VDi.Type=BOOL then begin BD:-ST.currentBlock; emit(new move("MOV",newp,new StIdArg(VDI.Type,VDi,BD.nextRelAdd-vd.reladdr))); end else emit(new move("MOV",newp,new IdArg(VDi.Type,VDi))); place:-newp; end; ACTION variabel place:-NewTemp(INTE); if VDi=/=none then begin if VDi.Type=INTE or VDi.Type=BOOL then begin BD:-ST.currentBlock; emit(new move("MOV",new StIdArg(VDi.type,VDi,BD.nextRelAdd-vd.reladdr),place)); end else emit(new move("MOV",new IdArg(VDI.Type,VDi),place)); place.type:=fixtype(VDI.Type); end; #END ##END ##RULE = '~' calc ';' #DECLARATIONS ref(VarDes) VD; ref(BlkDes) blockinfo,funkblock,BD; #END #ATTRIBUTES ref(arg) place; #END #ACTIONS ACTION dummy ACTION calc VD:-ST.LookUpDeclaration("..return",blockinfo,funkblock); if VD==none then begin ErrorLine; Outtext("Return är inte deklarerad i den här blocknivån. Gör om.");Outimage; end; place:-&.place; BD:-ST.currentBlock; emit(new move("MOV",place,new StIdArg(VD.Type,VD,BD.nextRelAdd-vd.reladdr))); #END ##END ##RULE = '?' tst (':)' / $ ) (':(' jmp2 add1 / $ add1 ) add2 #DECLARATIONS text t1,t2; #END #ATTRIBUTES #END #ACTIONS ACTION tst t1:-GetNewLabel; t2:-GetNewLabel; emit(new ATst("TST",&.place)); emit(new Abeq("BEQ",new LabelArg(INTE,t1))); ACTION jmp2 emit(new AGoto("GOTO",new LabelArg(INTE,t2))); ACTION add1 emit(new ALabel(t1)); ACTION add2 emit(new ALabel(t2)); #END ##END ##RULE = '!' add1 tst ':)' jmp add2 #DECLARATIONS text t1,t2; #END #ATTRIBUTES #END #ACTIONS ACTION add1 t1:-GetNewLabel; t2:-GetNewLabel; emit(new ALabel(t1)); ACTION tst emit(new ATst("TST",&.place)); emit(new Abeq("BEQ",new LabelArg(INTE,t2))); ACTION jmp emit(new AGoto("GOTO",new LabelArg(INTE,t1))); ACTION add2 emit(new ALabel(t2)); #END ##END ##RULE = '»' scanf #ATTRIBUTES ref(arg) place; #END #ACTIONS Action scanf Place:-new RegArg(INTE,"%o0"); Emit(new AsmCall("Call",new LabelArg(INTE,"readint"))); Emit(new nop("NOP")); #END ##END ##RULE = '«' ( printInt/ 'string' printf) ';' #ACTIONS Action printInt emit(new AsmWriteInt("WriteInt",&.place)); gctemp(&.place); Action printf emit(new AsmWriteText("WriteText",new TextArg(INTE,&'string'))); #END ##END ###END ###PROLOG ! Innan start ; ST:-new SymbolTable; genprog:-new head; gendata:-new head; levelH:-new head; ST.EnterBlock(new BlkDes(0)); new Level(ST.CurrentLevel).into(LevelH); outimage; ###END ###EPILOG ! När vi är klara, även vid error; ST.ExitBlock; !-- skriv ut asm koden; sourcename:-copy(infilename.sub(1,infilename.length-2))&".s"; sourcecode:-new outfile(sourcename); sourcecode.open(blanks(132)); initasm; !-- Deklarationer ; op:-gendata.first; while op=/=none do begin op.asm; op:-op.suc; end; inittext; !-- text segmentets progamkod; op:-genprog.first; while op=/=none do begin op.asm; op:-op.suc; end; endasm; sourcecode.close; ###END