} // Symbol public void FuncDef() { if (kind == Kind.undefKind) { return; } if (kind == Kind.funcKind) { if (!defined) { if (NameList.NameOf(spix) == "main") { if (type != Type.undefType && type != Type.voidType) { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "main func must be void"); } if (symbols != null) { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "main func must not have parameters"); } } // if defined = true; if (hadFuncDecl) // do decl and def parameters match? { Symbol declPar = funcDeclParList; Symbol defPar = symbols; while (declPar != null && defPar != null) { if (declPar.kind != Kind.undefKind && defPar.kind != Kind.undefKind && declPar.type != defPar.type) { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "mismatch in type of parameters in decl and def"); return; } // if declPar = declPar.next; defPar = defPar.next; } // while if (declPar != null || defPar != null) { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "mismatch in number of parameters in decl and def"); } } // if } else // defined { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "invalid function redefinition"); } } else // kind != Kind.funcKind { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "symbol is no function"); } } // FuncDef
} // LeaveScope public static Symbol Insert(int spix, Symbol.Kind kind, Type type, bool asPtrType) { //-----------------------------------|---------------------------------------- Symbol prev = null; Symbol sy = curScope.symbols; while (sy != null) { if (sy.spix == spix) { Errors.SemError(MiniCppLex.tokenLine, MiniCppLex.tokenCol, "multiple definition"); sy.kind = Symbol.Kind.undefKind; return(sy); } // if prev = sy; sy = sy.next; } // while // assert: sy == null sy = new Symbol(spix, kind, type, asPtrType); if (kind == Symbol.Kind.parKind) { sy.addr = curScope.nrOfParams; curScope.nrOfParams++; } else if (kind == Symbol.Kind.constKind || kind == Symbol.Kind.varKind) { sy.addr = curScope.nrOfLocals; curScope.nrOfLocals++; } // else if (sy.kind == Symbol.Kind.funcKind && NameList.NameOf(spix) == "main") { mainFunc = sy; } if (prev == null) { curScope.symbols = sy; } else { prev.next = sy; } return(sy); } // Insert
} //WriteFuncDecls public static void WriteFuncDecl(Symbol sy) { genMcpp.WriteLine(); genMcpp.Write(Indent() + sy.type + " " + NameList.NameOf(sy.spix) + "("); Symbol localSy = sy.symbols; bool first = true; while (localSy != null && localSy.kind == Symbol.Kind.parKind) { if (!first) { genMcpp.Write(", "); } first = false; genMcpp.Write(localSy.type + " " + NameList.NameOf(localSy.spix)); localSy = localSy.next; } // while genMcpp.Write(")"); } // WriteFuncDecl
} // WriteSymbolList public static void WriteSymbol(Symbol sy) { switch (sy.kind) { case Symbol.Kind.undefKind: genMcpp.WriteLine(Indent() + "undefined " + NameList.NameOf(sy.spix) + ";"); break; case Symbol.Kind.constKind: genMcpp.WriteLine(Indent() + "const " + sy.type + " " + NameList.NameOf(sy.spix) + " = " + sy.val + ";"); break; case Symbol.Kind.parKind: break; // nothing to do case Symbol.Kind.varKind: genMcpp.Write(Indent() + sy.type + " " + NameList.NameOf(sy.spix)); if (sy.init) { genMcpp.Write(" = " + sy.val); } genMcpp.WriteLine(";"); break; case Symbol.Kind.funcKind: WriteFuncDecl(sy); genMcpp.WriteLine(" {"); IncIndent(); Symbol localSy = sy.symbols; WriteSymbolList(localSy); WriteStatList(sy.statList); DecIndent(); genMcpp.WriteLine(Indent() + "} // " + NameList.NameOf(sy.spix)); break; default: throw new Exception("invalid symbol kind"); } // case } // WriteSymbol
} // FuncDef public override String ToString() { if (Symbol.shortSymbolInfo) { return(NameList.NameOf(spix)); } StringBuilder sb = new StringBuilder(); sb.Append(NameList.NameOf(spix) + ": "); switch (kind) { case Kind.undefKind: sb.Append("undef"); break; case Kind.constKind: sb.Append("const"); sb.Append(", type = " + type); sb.Append(", val = " + val); sb.Append(", addr = " + addr); break; case Kind.varKind: sb.Append("var"); sb.Append(", type = " + type); sb.Append(", init = " + init); sb.Append(", addr = " + addr); break; case Kind.parKind: sb.Append("par"); sb.Append(", type = " + type); sb.Append(", addr = " + addr); break; case Kind.funcKind: sb.Append("func"); sb.Append(", type = " + type); sb.Append(", addr = " + addr); sb.Append(", defined = " + defined); break; } // switch return(sb.ToString()); } // ToString
} // DumpSymTab // === generate source text from symbol table and AST === public static void WriteStat(Stat stat) { switch (stat.kind) { case Stat.Kind.emptyStatKind: genMcpp.WriteLine(Indent() + ";"); break; case Stat.Kind.blockStatKind: BlockStat b_s = (BlockStat)stat; genMcpp.WriteLine(Indent() + "{"); IncIndent(); WriteStatList(b_s.statList); DecIndent(); genMcpp.WriteLine(Indent() + "}"); break; case Stat.Kind.incStatKind: IncStat i_s = (IncStat)stat; genMcpp.WriteLine(Indent() + i_s.vo.sy + "++;"); break; case Stat.Kind.decStatKind: DecStat d_s = (DecStat)stat; genMcpp.WriteLine(Indent() + d_s.vo.sy + "--;"); break; case Stat.Kind.assignStatKind: AssignStat a_s = (AssignStat)stat; genMcpp.WriteLine(Indent() + a_s.lhs + " = " + a_s.rhs + ";"); break; case Stat.Kind.callStatKind: CallStat c_s = (CallStat)stat; genMcpp.WriteLine(Indent() + c_s.func + "(" + c_s.apl + ");"); break; case Stat.Kind.ifStatKind: IfStat if_s = (IfStat)stat; genMcpp.WriteLine(Indent() + "if (" + if_s.cond + ")"); IncIndent(); WriteStatList(if_s.thenStat); DecIndent(); if (if_s.elseStat != null) { genMcpp.WriteLine(Indent() + "else "); IncIndent(); WriteStatList(if_s.elseStat); DecIndent(); } // if break; case Stat.Kind.whileStatKind: WhileStat w_s = (WhileStat)stat; genMcpp.WriteLine(Indent() + "while (" + w_s.cond + ")"); IncIndent(); WriteStatList(w_s.body); DecIndent(); break; case Stat.Kind.breakStatKind: genMcpp.WriteLine(Indent() + "break;"); break; case Stat.Kind.inputStatKind: InputStat in_s = (InputStat)stat; genMcpp.WriteLine(Indent() + "cin >> " + in_s.vo.sy + ";"); break; case Stat.Kind.outputStatKind: OutputStat out_s = (OutputStat)stat; genMcpp.Write(Indent() + "cout"); foreach (Object o in out_s.values) { genMcpp.Write(" << "); if (o is Expr) { genMcpp.Write(o); } else if (o is String) { String s = o as String; if (s == "\n") { genMcpp.Write("endl"); } else { genMcpp.Write('"' + s + '"'); } } else { throw new Exception("invalid value"); } } // foreach genMcpp.WriteLine(";"); break; case Stat.Kind.deleteStatKind: DeleteStat del_s = (DeleteStat)stat; genMcpp.WriteLine(Indent() + "delete[] " + NameList.NameOf(del_s.vo.sy.spix) + ";"); break; case Stat.Kind.returnStatKind: ReturnStat r_s = (ReturnStat)stat; genMcpp.Write(Indent() + "return"); if (r_s.e != null) { genMcpp.Write(" " + r_s.e); } genMcpp.WriteLine(";"); break; default: throw new Exception("invalid statement kind"); } // switch } // WriteStatList
} // BaseTypeOf public override String ToString() { return(NameList.NameOf(spix)); } // ToString