package visitor.identification; import ast.definition.Definition; import ast.definition.classes.FuncDefinition; import ast.definition.classes.VarDefinition; import ast.expression.classes.Variable; import ast.statement.classes.IfElse; import ast.statement.classes.WhileLoop; import ast.type.classes.ErrorType; import ast.type.classes.FunctionType; import visitor.AbstractVisitor; public class IdentificationVisitor extends AbstractVisitor { private SymbolTable st = new SymbolTable(); //DEFINITIONS @Override public Void visit(FuncDefinition ast, Void param) { if (!st.insert(ast)) new ErrorType(ast.getLine(), ast.getColumn(), "Function \"" + ast.getName() + "\" already defined"); else { st.set(); super.visit(ast, param); st.reset(); } return null; } @Override public Void visit(VarDefinition ast, Void param) { if (!st.insert(ast)) new ErrorType(ast.getLine(), ast.getColumn(), "Variable \"" + ast.getName() + "\" already defined"); else { super.visit(ast, param); } return null; } // TYPE @Override public Void visit(FunctionType ast, Void param) { ast.getParameters().forEach(parameter -> { if (!st.insert(parameter)) new ErrorType(parameter.getLine(), parameter.getColumn(), "Variable \"" + parameter.getName() + "\" already defined"); }); return null; } // STATEMENTS @Override public Void visit(IfElse ast, Void param) { st.set(); super.visit(ast, param); st.reset(); return null; } @Override public Void visit(WhileLoop ast, Void param) { st.set(); super.visit(ast, param); st.reset(); return null; } @Override public Void visit(Variable ast, Void param) { Definition definition = st.find(ast.getName()); if (definition != null) ast.setDefinition(definition); /* -- Error is assigned in the TypeCheckingVisitor (in order not to repeat the error), as the definition associated to the variable is null. else new ErrorType(ast.getLine(),ast.getColumn(),"Variable \"" + ast.getName() +"\" not defined"); */ return null; } }