//----------------------------------------------------------- private Type Visit(Call node, Table table) { var procName = node.AnchorToken.Lexeme; if (!GPTable.Contains(procName)) { throw new SemanticError("The procedure " + procName + " is not defined", node.AnchorToken); } GlobalProcedure gp = GPTable[procName]; var parameterList = gp.getParameters(); if (node.Count() != parameterList.Length) { throw new SemanticError("Incorrect arity. Expecting " + parameterList.Length + " arguments, but found " + node.Count(), node.AnchorToken); } int i = 0; foreach (var parameter in gp.getParameters()) { Type argumType = Visit((dynamic)node[i], table); if (argumType != parameter.LocalType) { throw new SemanticError("Incorrect argument. Expecting a " + parameter.LocalType + ", but found a " + argumType, node[i].AnchorToken); } i++; } return(gp.ReturnType); }
//----------------------------------------------------------- private Type Visit(ProcedureDeclaration node, Table table) { GlobalSymbolTable gstable = table as GlobalSymbolTable; if (table == null) { throw new TypeAccessException("Expecting a GlobalSymbolTable"); } var procedureName = node.AnchorToken.Lexeme; if (gstable.Contains(procedureName)) { throw new SemanticError("Duplicated procedure: " + procedureName, node.AnchorToken); } if (node[1] is SimpleType || node[1] is ListType) { GPTable[procedureName] = new GlobalProcedure(false, Visit((dynamic)node[1], table)); var i = 0; foreach (var n in node) { if (i != 1) { Visit((dynamic)n, GPTable[procedureName].LocalSymbols); } i++; } } else { GPTable[procedureName] = new GlobalProcedure(false); VisitChildren(node, GPTable[procedureName].LocalSymbols); } return(Type.VOID); }
//----------------------------------------------------------- public SemanticAnalyzer() { GSTable = new GlobalSymbolTable(); GPTable = new GlobalProcedureTable(); GPTable["WrInt"] = new GlobalProcedure(true, Type.VOID); GPTable["WrInt"].LocalSymbols["i"] = new LocalSymbol(0, Type.INTEGER); GPTable["WrStr"] = new GlobalProcedure(true, Type.VOID); GPTable["WrStr"].LocalSymbols["s"] = new LocalSymbol(0, Type.STRING); GPTable["WrBool"] = new GlobalProcedure(true, Type.VOID); GPTable["WrBool"].LocalSymbols["b"] = new LocalSymbol(0, Type.BOOLEAN); GPTable["WrLn"] = new GlobalProcedure(true, Type.VOID); GPTable["RdInt"] = new GlobalProcedure(true, Type.INTEGER); GPTable["RdStr"] = new GlobalProcedure(true, Type.STRING); GPTable["AtStr"] = new GlobalProcedure(true, Type.STRING); GPTable["AtStr"].LocalSymbols["s"] = new LocalSymbol(0, Type.STRING); GPTable["AtStr"].LocalSymbols["i"] = new LocalSymbol(1, Type.INTEGER); GPTable["LenStr"] = new GlobalProcedure(true, Type.INTEGER); GPTable["LenStr"].LocalSymbols["s"] = new LocalSymbol(0, Type.STRING); GPTable["CmpStr"] = new GlobalProcedure(true, Type.INTEGER); GPTable["CmpStr"].LocalSymbols["s1"] = new LocalSymbol(0, Type.STRING); GPTable["CmpStr"].LocalSymbols["s2"] = new LocalSymbol(1, Type.STRING); GPTable["CatStr"] = new GlobalProcedure(true, Type.STRING); GPTable["CatStr"].LocalSymbols["s1"] = new LocalSymbol(0, Type.STRING); GPTable["CatStr"].LocalSymbols["s2"] = new LocalSymbol(1, Type.STRING); GPTable["LenLstInt"] = new GlobalProcedure(true, Type.INTEGER); GPTable["LenLstInt"].LocalSymbols["loi"] = new LocalSymbol(0, Type.LIST_OF_INTEGER); GPTable["LenLstStr"] = new GlobalProcedure(true, Type.INTEGER); GPTable["LenLstStr"].LocalSymbols["los"] = new LocalSymbol(0, Type.LIST_OF_STRING); GPTable["LenLstBool"] = new GlobalProcedure(true, Type.INTEGER); GPTable["LenLstBool"].LocalSymbols["lob"] = new LocalSymbol(0, Type.LIST_OF_BOOLEAN); GPTable["NewLstInt"] = new GlobalProcedure(true, Type.LIST_OF_INTEGER); GPTable["NewLstInt"].LocalSymbols["size"] = new LocalSymbol(0, Type.INTEGER); GPTable["NewLstStr"] = new GlobalProcedure(true, Type.LIST_OF_STRING); GPTable["NewLstStr"].LocalSymbols["size"] = new LocalSymbol(0, Type.INTEGER); GPTable["NewLstBool"] = new GlobalProcedure(true, Type.LIST_OF_BOOLEAN); GPTable["NewLstBool"].LocalSymbols["size"] = new LocalSymbol(0, Type.INTEGER); GPTable["IntToStr"] = new GlobalProcedure(true, Type.STRING); GPTable["IntToStr"].LocalSymbols["i"] = new LocalSymbol(0, Type.INTEGER); GPTable["StrToInt"] = new GlobalProcedure(true, Type.INTEGER); GPTable["StrToInt"].LocalSymbols["s"] = new LocalSymbol(0, Type.STRING); LoopNestingLevel = 0; }