void Stat() { int type; string name; Obj obj; int reg = 0, index1 = 0; string arrayName; switch (la.kind) { case 2: { Ident(out name); obj = tab.Find(name); if (la.kind == 24) { Get(); Expect(1); index1 = Convert.ToInt32(t.val); if (index1 > obj.index | index1 < 0) { SemErr("Wrong index"); } Expect(25); } if (la.kind == 26) { Get(); if (obj.kind == proc || (obj.kind == constant && obj.assign)) { if (obj.kind != constant) { SemErr("cannot assign to procedure"); } else { SemErr("Cannot re-asign already assign constant"); } } if (StartOf(3)) { Expr(out reg, out type); if (type == obj.type) { if (obj.level == 0) { gen.StoreGlobal(reg, obj.adr, name); } else { gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr, name); } } if (obj.kind == constant) { obj.assign = true; } } else if (la.kind == 24) { Get(); int arrayIndex = 0; Expect(1); index1 = Convert.ToInt32(t.val); Expect(25); Ident(out arrayName); Obj holder1 = tab.Find(arrayName); if (arrayIndex > holder1.index || arrayIndex < 0) { SemErr("Array index out of bounds"); } if (holder1.type != obj.type) { SemErr("Wrong types"); } if (holder1.kind == var || holder1.kind == constant) { if (holder1.level == 0) { gen.LoadGlobal(reg, holder1.adr + arrayIndex, arrayName); } else { gen.LoadLocal(reg, tab.curLevel - obj.level, holder1.adr + arrayIndex, arrayName); } if (obj.type == boolean) { gen.ResetZ(reg); } if (obj.level == 0) { gen.StoreGlobal(reg, obj.adr + index1, name); } else { gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr + index1, name); } obj.assign = true; } } else if (la.kind == 19) { Get(); Expr(out reg, out type); Expect(20); Expect(27); int reg1, type1, reg2, type2; int l1 = 0; int l2 = 1; if (type == boolean) { l1 = gen.NewLabel(); gen.BranchFalse(l1); } else { SemErr("Bool expected"); } Expr(out reg1, out type1); Expect(28); l2 = gen.NewLabel(); gen.Branch(l2); gen.Label(l1); if (obj.level == 0) { gen.StoreGlobal(reg1, obj.adr + index1, name); } else { gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr + index1, name); } Expr(out reg2, out type2); gen.Label(l2); if (obj.level == 0) { gen.StoreGlobal(reg2, obj.adr + index1, name); } else { gen.StoreLocal(reg2, tab.curLevel - obj.level, obj.adr + index1, name); } } else { SynErr(48); } Expect(29); } else if (la.kind == 8) { Get(); Expect(9); Expect(29); if (obj.kind == proc) { gen.Call(name); } else { SemErr("object is not a procedure"); } } else { SynErr(49); } break; } case 30: { Get(); int l1, l2; l1 = 0; Expr(out reg, out type); if (type == boolean) { l1 = gen.NewLabel(); gen.BranchFalse(l1); } else { SemErr("boolean type expected"); } l2 = gen.NewLabel(); gen.Branch(l2); gen.Label(l1); if (la.kind == 31) { Get(); Stat(); } gen.Label(l2); break; } case 32: { Get(); int l1, l2; l1 = gen.NewLabel(); gen.Label(l1); l2 = 0; Expr(out reg, out type); if (type == boolean) { l2 = gen.NewLabel(); gen.BranchFalse(l2); } else { SemErr("boolean type expected"); } Stat(); gen.Branch(l1); gen.Label(l2); break; } case 33: { Get(); Expect(8); Stat(); int loop, exit; loop = gen.NewLabel(); gen.Label(loop); exit = 0; Stat(); Expr(out reg, out type); if (type == boolean) { gen.BranchFalse(exit); } else { SemErr("Bool expected"); } Expect(9); Expect(34); Expect(16); Stat(); Expect(17); gen.Branch(loop); gen.Label(exit); break; } case 35: { Get(); Ident(out name); Expect(29); obj = tab.Find(name); if (obj.type == integer) { gen.ReadInteger(); if (obj.level == 0) { gen.StoreGlobal(0, obj.adr, name); } else { gen.StoreLocal(0, tab.curLevel - obj.level, obj.adr, name); } } else { SemErr("integer type expected"); } break; } case 36: { Get(); string text; if (StartOf(3)) { Expr(out reg, out type); switch (type) { case integer: gen.WriteInteger(reg, false); break; case boolean: gen.WriteBoolean(false); break; } } else if (la.kind == 3) { String(out text); gen.WriteString(text); } else { SynErr(50); } Expect(29); break; } case 37: { Get(); Expr(out reg, out type); switch (type) { case integer: gen.WriteInteger(reg, true); break; case boolean: gen.WriteBoolean(true); break; } Expect(29); break; } case 16: { Get(); tab.OpenSubScope(); while (StartOf(4)) { if (la.kind == 41) { ConstantDecl(); } else if (la.kind == 39 || la.kind == 40) { VarDecl(); } else { Stat(); } } Expect(17); tab.CloseSubScope(); break; } default: SynErr(51); break; } }
// close current scope public void CloseScope() { Obj obj, scope; scope = topScope; String str; while (scope != null) { obj = scope.locals; while (obj != null) { // for all objects in this scope str = "; "; str += obj.name + " is a "; if (obj.kind == 0) { if (obj.level >= 1) { str += "local variable "; } else { str += "global variable "; } str += "of type "; if (obj.type == 0) { str += "undefined"; } else if (obj.type == 1) { str += "Integer "; } else { str += "Boolean "; } } else if (obj.kind == 1) { str += "procedure "; } else if (obj.kind == 2) { str += "scope "; } else { str = "constant "; } Console.WriteLine(str); obj = obj.next; } scope = scope.outer; } topScope = topScope.outer; curLevel--; }