Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*------------------------------------------------------------------------*/
- Stat (. int type,type1,type2; string name; Obj obj;
- string name2; Obj obj2;
- int adr, adr2, loopstart;
- int loopUpdate; .)
- = Ident<out name> (. obj = tab.Find(name); .)
- ( '=' (. if (obj.kind != var) SemErr("cannot assign to procedure or constant");
- if (obj.size != 1) SemErr("Array index expected");
- .)
- Expr<out type> ([';']
- (. if (type != obj.type) SemErr("incompatible types");
- if (obj.level == 0) gen.Emit(Op.STOG, obj.adr);
- else gen.Emit(Op.STO, obj.adr); .)
- | /*Code for conditional assignment here. The same as the If statement below
- except for the store instructions after the jump instructions */
- (. if(type != boolean) SemErr("Boolean expression expected");
- gen.Emit(Op.FJMP, 0); adr = gen.pc -2;
- if (obj.level == 0) gen.Emit(Op.STOG, obj.adr);
- else gen.Emit(Op.STO, obj.adr); .)
- '?'Expr<out type1> ':'
- (. gen.Emit(Op.JMP,0); adr2 = gen.pc -2;
- gen.Patch(adr,gen.pc); adr = adr2;
- if (obj.level == 0) gen.Emit(Op.STOG, obj.adr);
- else gen.Emit(Op.STO, obj.adr);
- .)
- Expr<out type2>';'
- (. gen.Patch(adr, gen.pc); .)
- )
- |
- '('
- ')'
- ';' (. if (obj.kind != proc) SemErr("Expected procedure");
- gen.Emit(Op.CALL, obj.adr); .)
- | //Array reference
- '['
- ( Ident<out name> (. obj2 = tab.Find(name); //obj2 is index, obj is array start
- if(obj.type != integer) SemErr("Expected integer as index");
- .)
- ']'
- '=' (. if(obj.level == 0) gen.Emit(Op.LOADG, obj2.adr);
- else gen.Emit(Op.LOAD, obj2.adr); .)
- Expr<out type1>
- ';' (. if(type1 != obj.type) SemErr("incompatible types");
- // gen.Emit(Op.ADD);
- gen.Emit(Op.STO, obj.adr);
- .)
- | number (. adr = Convert.ToInt32(t.val);
- if(adr < 0 || adr > obj.size) SemErr("Array index out of bounds");.)
- ']'
- '='
- Expr<out type1>
- ';' (. gen.Emit(Op.STO, obj.adr + adr); .)
- )
- )
- | "switch" //Sperate code needed fror number
- '('
- Ident<out name> (. obj = tab.Find(name); adr2 = 0;
- ArrayList jumps = new ArrayList();
- if(obj.type != integer) SemErr("Integer type expected");
- if(obj.level == 0) gen.Emit(Op.LOADG, obj.adr);
- else gen.Emit(Op.LOAD, obj.adr);
- .)
- ')'
- '{'
- "case"
- Expr<out type> (. if(type != obj.type) SemErr("Incompatible types in case");
- gen.Emit(Op.EQU);
- gen.Emit(Op.FJMP, 0); adr = gen.pc -2;
- .)
- ':'
- Stat
- [ "break;" (. gen.Emit(Op.JMP, 0); adr2 = 1; //Record a break has been used
- jumps.Add((gen.pc -2));
- .)
- ]
- {
- "case" (. gen.Patch(adr, gen.pc);
- if(obj.level == 0) gen.Emit(Op.LOADG, obj.adr);
- else gen.Emit(Op.LOAD, obj.adr);
- .)
- Expr<out type> (. if(type != obj.type) SemErr("Incompatible types in case");
- gen.Emit(Op.EQU);
- gen.Emit(Op.FJMP, 0); adr = gen.pc -2;.)
- ':'
- Stat
- [ "break;" (. gen.Emit(Op.JMP, 0); adr2 =1; jumps.Add((gen.pc -2));
- .)
- ]
- }
- {
- "default:" (. gen.Patch(adr, gen.pc); .)
- Stat
- ["break;" ]
- }
- '}' (.
- gen.Patch(adr, gen.pc);
- if(adr2 != 0){
- foreach(int i in jumps){
- gen.Patch(i, gen.pc);
- }
- }
- .)
- | "if"
- '('
- Expr<out type>
- ')' (. if (type != boolean) SemErr("Expected boolean");
- gen.Emit(Op.FJMP, 0); adr = gen.pc - 2; .)
- Stat
- [ "else" (. gen.Emit(Op.JMP, 0); adr2 = gen.pc - 2;
- gen.Patch(adr, gen.pc); // Update the bool-check failure address
- adr = adr2; .)
- Stat
- ] (. gen.Patch(adr, gen.pc); .)
- | "while" (. loopstart = gen.pc; .)
- '('
- Expr<out type>
- ')' (. if (type != boolean) SemErr("boolean type expected");
- gen.Emit(Op.FJMP, 0); adr = gen.pc - 2; .)
- Stat (. gen.Emit(Op.JMP, loopstart); gen.Patch(adr, gen.pc); .)
- | "do" (. loopstart = gen.pc; .)
- Stat
- "while"
- '('
- Expr<out type>
- ')' (. if(type != boolean) SemErr("Boolean type expected");
- gen.Emit(Op.FJMP, 0); adr = gen.pc -2;
- gen.Emit(Op.JMP, loopstart);
- gen.Patch(adr, gen.pc); .)
- | "read"
- Ident<out name>
- ';' (. obj = tab.Find(name);
- if (obj.type != integer) SemErr("integer type expected");
- gen.Emit(Op.READ);
- if (obj.level == 0) gen.Emit(Op.STOG, obj.adr);
- else gen.Emit(Op.STO, obj.adr); .)
- | "write"
- Expr<out type>
- ';' (.if (type == integer) gen.Emit(Op.WRITE);
- else if(type == character) gen.Emit(Op.WRITEC);
- else SemErr("integer or character type expected");
- .)
- | "for"
- '('Stat (. loopstart = gen.pc; .)
- Expr<out type>
- ';' (. if(type != boolean) SemErr("boolean type expected");
- gen.Emit(Op.FJMP, 0); adr = gen.pc -2; //Jump if check fails
- gen.Emit(Op.JMP, 0); adr2 = gen.pc -2; //Jump to loop body
- loopUpdate = gen.pc; .) //Label loop update
- Stat (. gen.Emit(Op.JMP, loopstart); .) //Jump to start after update
- ')' (. gen.Patch(adr2, gen.pc); .)
- Stat (. gen.Emit(Op.JMP, loopUpdate); gen.Patch(adr, gen.pc); .) //Jump to update after body
- | '{' { Stat | VarDecl | ConstDecl } '}' .
Add Comment
Please, Sign In to add comment