//----------------------------------------------------------- private Type Visit(Identifier node, Table table) { GlobalSymbolTable gstable = table as GlobalSymbolTable; LocalSymbolTable lstable = table as LocalSymbolTable; var symbolName = node.AnchorToken.Lexeme; if (table is GlobalSymbolTable) { if (gstable.Contains(symbolName)) { return(gstable[symbolName].TheType); } throw new SemanticError("Undeclared variable: " + symbolName, node.AnchorToken); } else if (table is LocalSymbolTable) { if (lstable.Contains(symbolName)) { return(lstable[symbolName].LocalType); } if (GSTable.Contains(symbolName)) { return(GSTable[symbolName].TheType); } throw new SemanticError("Undeclared variable: " + symbolName, node.AnchorToken); } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } }
//----------------------------------------------------------- private Type Visit(AssignmentStatement node, Table table) { Type leftExpressionType = Visit((dynamic)node[0], table); Type rightExpressionType = Visit((dynamic)node[1], table); if (leftExpressionType != rightExpressionType) { if (!((leftExpressionType == Type.LIST_OF_BOOLEAN || leftExpressionType == Type.LIST_OF_INTEGER || leftExpressionType == Type.LIST_OF_STRING) && rightExpressionType == Type.LIST_OF_ANYTHING)) { throw new SemanticError("Expecting type " + leftExpressionType + " instead of " + rightExpressionType + " in assignment statement", node.AnchorToken); } } if (node[0] is Identifier) { GlobalSymbolTable gstable = table as GlobalSymbolTable; LocalSymbolTable lstable = table as LocalSymbolTable; var symbolName = node[0].AnchorToken.Lexeme; if (table is GlobalSymbolTable) { if (gstable[symbolName].IsConstant) { throw new SemanticError("Cannot perform assignment to constant " + symbolName, node[0].AnchorToken); } } else if (table is LocalSymbolTable) { if (lstable.Contains(symbolName)) { if (lstable[symbolName].Kind == Clasification.CONST) { throw new SemanticError("Cannot perform assignment to constant " + symbolName, node[0].AnchorToken); } } else { if (GSTable.Contains(symbolName) && GSTable[symbolName].IsConstant) { throw new SemanticError("Cannot perform assignment to constant " + symbolName, node[0].AnchorToken); } } } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } } else if (node[0] is ListIndexExpression) { } else { throw new TypeAccessException("Expecting either a Idenetifier or a ListIndexExpression " + node[0]); } return(Type.VOID); }
//----------------------------------------------------------- private Type Visit(VariableDeclaration node, Table table) { GlobalSymbolTable gstable = table as GlobalSymbolTable; LocalSymbolTable lstable = table as LocalSymbolTable; Type declarationType = Visit((dynamic)node[1], table); foreach (var n in node[0]) { var symbolName = n.AnchorToken.Lexeme; if (table is GlobalSymbolTable) { if (GSTable.Contains(symbolName)) { throw new SemanticError("Duplicated symbol: " + symbolName, n.AnchorToken); } } else if (table is LocalSymbolTable) { if (lstable.Contains(symbolName)) { throw new SemanticError("Duplicated symbol: " + symbolName, n.AnchorToken); } } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } if (table is GlobalSymbolTable) { gstable[symbolName] = new GlobalSymbol(declarationType); } else if (table is LocalSymbolTable) { lstable[symbolName] = new LocalSymbol(declarationType); } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } } return(Type.VOID); }
//----------------------------------------------------------- private Type Visit(ConstantDeclaration node, Table table) { GlobalSymbolTable gstable = table as GlobalSymbolTable; LocalSymbolTable lstable = table as LocalSymbolTable; var symbolName = node.AnchorToken.Lexeme; if (table is GlobalSymbolTable) { if (GSTable.Contains(symbolName)) { throw new SemanticError("Duplicated symbol: " + symbolName, node[0].AnchorToken); } } else if (table is LocalSymbolTable) { if (lstable.Contains(symbolName)) { throw new SemanticError("Duplicated symbol: " + symbolName, node[0].AnchorToken); } } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } Type nodeType = Visit((dynamic)node[0], table); if (node[0] is Lst) { if (node[0].Count() == 0) { throw new SemanticError("Constant lists cannot be empty: " + symbolName, node.AnchorToken); } dynamic lst; if (nodeType == Type.LIST_OF_BOOLEAN) { lst = new Boolean[node[0].Count()]; } else if (nodeType == Type.LIST_OF_INTEGER) { lst = new Int32[node[0].Count()]; } else if (nodeType == Type.LIST_OF_STRING) { lst = new String[node[0].Count()]; } else { throw new TypeAccessException("Expecting one of the following node types: LIST_OF_BOOLEAN, LIST_OF_INTEGER, LIST_OF_STRING"); } int i = 0; foreach (var n in node[0]) { lst[i++] = n.ExtractValue(); } if (table is GlobalSymbolTable) { gstable[symbolName] = new GlobalSymbol(nodeType, lst); } else if (table is LocalSymbolTable) { lstable[symbolName] = new LocalSymbol(nodeType, lst); } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } } else { if (table is GlobalSymbolTable) { gstable[symbolName] = new GlobalSymbol(nodeType, node[0].ExtractValue()); } else if (table is LocalSymbolTable) { lstable[symbolName] = new LocalSymbol(nodeType, node[0].ExtractValue()); } else { throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable"); } } return(Type.VOID); }