public ArrIdxOperator(SrcPos sp, VarOperand arr, Expr idx) : base(Expr.Kind.arrIdxOperatorKind, sp) { this.arr = arr; this.idx = idx; this.type = Type.undefType; if (arr.sy.kind == Symbol.Kind.undefKind) { return; } if (arr.sy.kind != Symbol.Kind.parKind && arr.sy.kind != Symbol.Kind.varKind) { Errors.SemError(sp.line, sp.col, "invalid symbol kind"); return; } // if if (idx.type == Type.undefType) { return; } if (arr.type != Type.boolPtrType && arr.type != Type.intPtrType) { Errors.SemError(sp.line, sp.col, "invalid array type"); return; } // if if (idx.type != Type.intType) { Errors.SemError(sp.line, sp.col, "invalid index type"); return; } // if this.type = arr.type.BaseTypeOf(); } // ArrIdxOperator
public ReturnStat(SrcPos sp, Symbol funcSy, Expr e) : base(Stat.Kind.returnStatKind, sp) { this.e = e; if (funcSy.type == Type.undefType) { return; } if (funcSy.type == Type.voidType) { if (e != null) { Errors.SemError(sp.line, sp.col, "invalid return value for void func"); } return; } // if if (e == null) { Errors.SemError(sp.line, sp.col, "missing return value"); return; } // if if (funcSy.type != e.type && e.type != Type.undefType) { Errors.SemError(sp.line, sp.col, "mismatch in return value and func type"); } } // ReturnStat
} // NT_OutputStat private static void NT_DeleteStat(out Stat s) { int spix = 0; Symbol sy = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM sp = new SrcPos(); break; case 2: Lex.GETidentAttr(out spix); break; case 3: // SEM sy = SymTab.SymbolOf(spix, Symbol.Kind.varKind, Symbol.Kind.parKind); s = new DeleteStat(sp, new VarOperand(sy)); break; } // switch } // for } // NT_DeleteStat
} // NT_DeleteStat private static void NT_ReturnStat(out Stat s) { Expr e = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM sp = new SrcPos(); break; case 2: NT_Expr(out e); break; case 3: // SEM s = new ReturnStat(sp, curFuncSy, e); break; } // switch } // for } // NT_ReturnStat
public UnaryOperator(SrcPos sp, Operation op, Expr e) : base(Expr.Kind.unaryOperatorKind, sp) { this.op = op; this.e = e; this.type = e.type; if (op == Operation.undefOp) { Errors.SemError(sp.line, sp.col, "invalid operator"); return; } // if if (type == Type.undefType) { return; } if (op == Operation.notOp) { if (type != Type.boolType) { Errors.SemError(sp.line, sp.col, "expr of type bool expected"); } } else // op == Operation.posOp || op == Operation.negOp) { if (type != Type.intType) { Errors.SemError(sp.line, sp.col, "expr of type int expected"); } } // else } // UnaryOperator
} // NT_Term private static void NT_NotFact(out Expr nf) { SrcPos sp = null; bool hasNot = false; nf = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM hasNot = true; sp = new SrcPos(); break; case 2: NT_Fact(out nf); break; case 3: // SEM if (hasNot) { nf = new UnaryOperator(sp, UnaryOperator.Operation.notOp, nf); } break; } // switch } // for } // NT_NotFact
public ArrayList values; // either Expr, String or special String "\n" public OutputStat(SrcPos sp, ArrayList values) : base(Stat.Kind.outputStatKind, sp) { this.values = values; foreach (Object o in values) { if (o is Expr) { Expr e = o as Expr; if (e != null && e.type != Type.undefType && e.type != Type.boolType && e.type != Type.intType) { Errors.SemError(sp.line, sp.col, "invalid type"); } } else if (o is String) { // nothing to check } else { Errors.SemError(sp.line, sp.col, "invalid value"); } // else } // foreach } // OutputSta
protected Stat(Kind kind, SrcPos sp) { if (sp == null) { sp = new SrcPos(); } this.srcPos = sp; this.kind = kind; } // Stat
public WhileStat(SrcPos sp, Expr cond, Stat body) : base(Stat.Kind.whileStatKind, sp) { this.cond = cond; this.body = body; if (cond.type != Type.undefType && cond.type != Type.boolType) { Errors.SemError(sp.line, sp.col, "invalid condition type"); } } // WhileStat
public IfStat(SrcPos sp, Expr cond, Stat thenStat, Stat elseStat) : base(Stat.Kind.ifStatKind, sp) { this.cond = cond; this.thenStat = thenStat; this.elseStat = elseStat; if (cond.type != Type.undefType && cond.type != Type.boolType) { Errors.SemError(sp.line, sp.col, "invalid condition type"); } } // IfStat
} // NT_SimpleExpr private static void NT_Term(out Expr t) { Expr f = null; SrcPos sp = null; BinaryOperator.Operation binOp = BinaryOperator.Operation.undefOp; t = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_NotFact(out f); break; case 2: // SEM t = f; break; case 3: // SEM binOp = BinaryOperator.Operation.mulOp; sp = new SrcPos(); break; case 4: // SEM binOp = BinaryOperator.Operation.divOp; sp = new SrcPos(); break; case 5: // SEM binOp = BinaryOperator.Operation.modOp; sp = new SrcPos(); break; case 6: NT_NotFact(out f); break; case 7: // SEM t = new BinaryOperator(sp, binOp, t, f); break; } // switch } // for } // NT_Term
public BinaryOperator(SrcPos sp, Operation op, Expr left, Expr right) : base(Expr.Kind.binaryOperatorKind, sp) { this.op = op; this.left = left; this.right = right; if (op == Operation.undefOp) { Errors.SemError(sp.line, sp.col, "invalid operator"); } if (left.type == Type.undefType || right.type == Type.undefType) { this.type = Type.undefType; return; } // if if (op == Operation.orOp || op == Operation.andOp) { if (left.type != Type.boolType || right.type != Type.boolType) { Errors.SemError(sp.line, sp.col, "bool operands needed"); this.type = Type.undefType; } else { this.type = Type.boolType; } } else if (op == Operation.eqOp || op == Operation.neOp || op == Operation.ltOp || op == Operation.leOp || op == Operation.gtOp || op == Operation.geOp) { if (left.type != right.type) { Errors.SemError(sp.line, sp.col, "type mismatch in operands"); this.type = Type.undefType; } else { this.type = Type.boolType; } } else // addOp, subOp, mulOp, divOp, modOp { if (left.type != Type.intType || right.type != Type.intType) { Errors.SemError(sp.line, sp.col, "operands of type integer expected"); this.type = Type.undefType; } else { this.type = Type.intType; } } // else } // BinaryOperator
public DeleteStat(SrcPos sp, VarOperand vo) : base(Stat.Kind.deleteStatKind, sp) { this.vo = vo; if (vo.sy.type == Type.undefType) { return; } if (!vo.sy.type.IsPtrType()) { Errors.SemError(sp.line, sp.col, "invalid type"); } } // DeleteStat
public DecStat(SrcPos sp, VarOperand vo) : base(Stat.Kind.decStatKind, sp) { this.vo = vo; if (vo.sy.kind != Symbol.Kind.undefKind && vo.sy.kind != Symbol.Kind.varKind) { Errors.SemError(sp.line, sp.col, "no variable"); } if (vo.sy.type != Type.undefType && vo.sy.type != Type.intType) { Errors.SemError(sp.line, sp.col, "invalid type"); } } // DecStat
public InputStat(SrcPos sp, VarOperand vo) : base(Stat.Kind.inputStatKind, sp) { this.vo = vo; if (vo.sy.kind != Symbol.Kind.undefKind && vo.sy.kind != Symbol.Kind.parKind && vo.sy.kind != Symbol.Kind.varKind) { Errors.SemError(sp.line, sp.col, "invalid symbol kind"); } if (vo.sy.type != Type.undefType && vo.sy.type != Type.boolType && vo.sy.type != Type.intType) { Errors.SemError(sp.line, sp.col, "invalid type"); } } // InputStat
public FuncCallOperator(SrcPos sp, Symbol func, Expr apl) : base(Expr.Kind.funcCallOperatorKind, sp) { this.func = func; this.apl = apl; this.type = func.type; if (func.kind == Symbol.Kind.undefKind) { return; } if (func.kind != Symbol.Kind.funcKind) { Errors.SemError(sp.line, sp.col, "symbol is no function"); } Symbol fp = func.symbols; if (fp == null && !func.defined && func.hadFuncDecl) { fp = func.funcDeclParList; } Expr ap = apl; while (fp != null && fp.kind == Symbol.Kind.parKind && ap != null) { if (fp.kind != Symbol.Kind.undefKind && ap.type != Type.undefType && fp.type != ap.type) { Errors.SemError(sp.line, sp.col, "mismatch in type of parameters"); return; } // if fp = fp.next; ap = ap.next; } // while if (((fp == null) || ((fp != null) && (fp.kind != Symbol.Kind.parKind))) && (ap == null)) { } // both lists are empty else { Errors.SemError(sp.line, sp.col, "mismatch in number of parameters"); } } // FuncCallOperator
} // NT_Expr private static void NT_OrExpr(out Expr oe) { Expr ae = null; SrcPos sp = null; BinaryOperator.Operation binOp = BinaryOperator.Operation.undefOp; oe = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_AndExpr(out ae); break; case 2: // SEM oe = ae; break; case 3: // SEM binOp = BinaryOperator.Operation.orOp; sp = new SrcPos(); break; case 4: NT_AndExpr(out ae); break; case 5: // SEM oe = new BinaryOperator(sp, binOp, oe, ae); break; } // switch } // for } // NT_OrExpr
} // NT_OrExpr private static void NT_AndExpr(out Expr ae) { Expr re = null; SrcPos sp = null; BinaryOperator.Operation binOp = BinaryOperator.Operation.undefOp; ae = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_RelExpr(out re); break; case 2: // SEM ae = re; break; case 3: // SEM binOp = BinaryOperator.Operation.andOp; sp = new SrcPos(); break; case 4: NT_RelExpr(out re); break; case 5: // SEM ae = new BinaryOperator(sp, binOp, ae, re); break; } // switch } // for } // NT_AndExpr
} // NT_IfStat private static void NT_WhileStat(out Stat s) { Expr e = null; Stat body = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM sp = new SrcPos(); break; case 2: NT_Expr(out e); break; case 3: // SEM loopLevel++; break; case 4: NT_Stat(out body); break; case 5: // SEM s = new WhileStat(sp, e, body); loopLevel--; break; } // switch } // for } // NT_WhileStat
public AssignStat(SrcPos sp, Expr lhs, Expr rhs) : base(Stat.Kind.assignStatKind, sp) { this.lhs = lhs; this.rhs = rhs; if (lhs is VarOperand) { VarOperand vo = lhs as VarOperand; if (vo.sy.kind != Symbol.Kind.undefKind && vo.sy.kind != Symbol.Kind.parKind && vo.sy.kind != Symbol.Kind.varKind) { Errors.SemError(sp.line, sp.col, "lhs: no variable"); } } else if (lhs is ArrIdxOperator) { ; // nothing to check } else { Errors.SemError(sp.line, sp.col, "lhs: invalid expression"); } // else if (lhs.type == Type.undefType || rhs.type == Type.undefType || lhs.type == rhs.type) { return; } if (lhs.type.IsPtrType() && rhs.kind == Expr.Kind.litOperandKind && ((LitOperand)rhs).type.kind == Type.Kind.intKind && ((LitOperand)rhs).val == 0) { rhs.type = Type.voidPtrType; // change type of oprand form int to void* return; } // if Errors.SemError(sp.line, sp.col, "type mismatch"); } // AssignStat
} // NT_ActParList private static void NT_IfStat(out Stat s) { Expr e = null; Stat thenStat = null, elseStat = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM sp = new SrcPos(); break; case 2: NT_Expr(out e); break; case 3: NT_Stat(out thenStat); break; case 4: NT_Stat(out elseStat); break; case 5: // SEM s = new IfStat(sp, e, thenStat, elseStat); break; } // switch } // for } // NT_IfStat
public NewOperator(SrcPos sp, Type elemType, Expr noe) : base(Expr.Kind.newOperatorKind, sp) { this.elemType = elemType; this.noe = noe; this.type = Type.undefType; if (elemType == Type.undefType || noe.type == Type.undefType) { return; } if (elemType == Type.boolPtrType || elemType == Type.boolPtrType) { Errors.SemError(sp.line, sp.col, "invalid type"); return; } // if if (noe.type != Type.intType) { Errors.SemError(sp.line, sp.col, "invalid type"); return; } // if this.type = elemType.PtrTypeOf(); } // NewOperator
} // NT_InputStat private static void NT_OutputStat(out Stat s) { Expr e = null; String str = null; SrcPos sp = null; System.Collections.ArrayList values = new System.Collections.ArrayList(); s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM sp = new SrcPos(); break; case 2: NT_Expr(out e); break; case 3: // SEM values.Add(e); break; case 4: Lex.GETstringAttr(out str); break; case 5: // SEM values.Add(str); break; case 6: // SEM values.Add("\n"); break; case 7: NT_Expr(out e); break; case 8: // SEM values.Add(e); break; case 9: Lex.GETstringAttr(out str); break; case 10: // SEM values.Add(str); break; case 11: // SEM values.Add("\n"); break; case 12: // SEM s = new OutputStat(sp, values); break; } // switch } // for } // NT_OutputStat
} // NT_Stat private static void NT_IncDecAssignOrCallStat(out Stat s) { int spix = 0; Symbol sy = null; Expr lhs = null, e = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: Lex.GETidentAttr(out spix); break; case 2: // SEM sy = SymTab.SymbolOf(spix, Symbol.Kind.varKind, Symbol.Kind.parKind, Symbol.Kind.funcKind); break; case 3: // SEM s = new IncStat(sp, new VarOperand(sy)); break; case 4: // SEM s = new DecStat(sp, new VarOperand(sy)); break; case 5: // SEM lhs = new VarOperand(sy); break; case 6: // SEM sp = new SrcPos(); break; case 7: NT_Expr(out e); break; case 8: // SEM lhs = new ArrIdxOperator(sp, new VarOperand(sy), e); break; case 9: // SEM sp = new SrcPos(); break; case 10: NT_Expr(out e); break; case 11: // SEM s = new AssignStat(sp, lhs, e); break; case 12: // SEM sp = new SrcPos(); break; case 13: NT_ActParList(out e); break; case 14: // SEM s = new CallStat(sp, sy, e); break; } // switch } // for } // NT_IncDecAssignOrCallStat
} // NT_Block private static void NT_Stat(out Stat s) { Symbol locSymbols = null; Stat statList = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_IncDecAssignOrCallStat(out s); break; case 2: NT_IfStat(out s); break; case 3: NT_WhileStat(out s); break; case 4: NT_BreakStat(out s); break; case 5: NT_InputStat(out s); break; case 6: NT_OutputStat(out s); break; case 7: NT_DeleteStat(out s); break; case 8: NT_ReturnStat(out s); break; case 9: // SEM sp = new SrcPos(); break; case 10: NT_Block(out locSymbols, out statList); break; case 11: // SEM s = new BlockStat(sp, statList); break; case 12: // SEM s = new EmptyStat(null); break; } // switch } // for } // NT_Stat
} // NT_NotFact private static void NT_Fact(out Expr f) { Expr e = null; SrcPos sp = null; Symbol sy = null; int spix = 0; int number = 0; Type t = null; f = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM f = new LitOperand(Type.boolType, 0); break; case 2: // SEM f = new LitOperand(Type.boolType, 1); break; case 3: Lex.GETnumberAttr(out number); break; case 4: // SEM f = new LitOperand(Type.intType, number); break; case 5: Lex.GETidentAttr(out spix); break; case 6: // SEM sp = new SrcPos(); break; case 7: // SEM sy = SymTab.SymbolOf(spix, Symbol.Kind.constKind, Symbol.Kind.varKind, Symbol.Kind.parKind); f = new VarOperand(sy); break; case 8: // SEM sy = SymTab.SymbolOf(spix, Symbol.Kind.varKind, Symbol.Kind.parKind); break; case 9: // SEM sp = new SrcPos(); break; case 10: NT_Expr(out e); break; case 11: // SEM f = new ArrIdxOperator(sp, new VarOperand(sy), e); break; case 12: // SEM sy = SymTab.SymbolOf(spix, Symbol.Kind.funcKind); break; case 13: NT_ActParList(out e); break; case 14: // SEM f = new FuncCallOperator(sp, sy, e); break; case 15: // SEM sp = new SrcPos(); break; case 16: NT_Type(out t); break; case 17: NT_Expr(out e); break; case 18: // SEM f = new NewOperator(sp, t, e); break; case 19: NT_Expr(out e); break; case 20: // SEM f = e; break; } // switch } // for } // NT_Fact
protected Operand(Kind kind, SrcPos sp) : base(kind, sp) { } // Operand
} // NT_RelExpr private static void NT_SimpleExpr(out Expr se) { Expr t = null; SrcPos sp = null; UnaryOperator.Operation unOp = UnaryOperator.Operation.undefOp; BinaryOperator.Operation binOp = BinaryOperator.Operation.undefOp; se = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: // SEM unOp = UnaryOperator.Operation.posOp; sp = new SrcPos(); break; case 2: // SEM unOp = UnaryOperator.Operation.negOp; sp = new SrcPos(); break; case 3: NT_Term(out t); break; case 4: // SEM if (unOp != UnaryOperator.Operation.undefOp) { se = new UnaryOperator(sp, unOp, t); } else { se = t; } break; case 5: // SEM binOp = BinaryOperator.Operation.addOp; sp = new SrcPos(); break; case 6: // SEM binOp = BinaryOperator.Operation.subOp; sp = new SrcPos(); break; case 7: NT_Term(out t); break; case 8: // SEM se = new BinaryOperator(sp, binOp, se, t); break; } // switch } // for } // NT_SimpleExpr
} // NT_AndExpr private static void NT_RelExpr(out Expr re) { Expr se = null; SrcPos sp = null; BinaryOperator.Operation binOp = BinaryOperator.Operation.undefOp; re = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_SimpleExpr(out se); break; case 2: // SEM re = se; break; case 3: // SEM binOp = BinaryOperator.Operation.eqOp; sp = new SrcPos(); break; case 4: // SEM binOp = BinaryOperator.Operation.neOp; sp = new SrcPos(); break; case 5: // SEM binOp = BinaryOperator.Operation.ltOp; sp = new SrcPos(); break; case 6: // SEM binOp = BinaryOperator.Operation.leOp; sp = new SrcPos(); break; case 7: // SEM binOp = BinaryOperator.Operation.gtOp; sp = new SrcPos(); break; case 8: // SEM binOp = BinaryOperator.Operation.geOp; sp = new SrcPos(); break; case 9: NT_SimpleExpr(out se); break; case 10: // SEM re = new BinaryOperator(sp, binOp, re, se); break; } // switch } // for } // NT_RelExpr
public BreakStat(SrcPos sp) : base(Stat.Kind.breakStatKind, sp) { } // BreakStat