package typeChecker; import java.util.LinkedList; import java.util.List; import nodeAST.ASTNode; import nodeAST.Expression; import nodeAST.arithmetic.Add; import nodeAST.arithmetic.Div; import nodeAST.arithmetic.Mul; import nodeAST.arithmetic.Sub; import nodeAST.conditional.And; import nodeAST.conditional.Or; import nodeAST.relational.Eq; import nodeAST.relational.GEq; import nodeAST.relational.GT; import nodeAST.relational.LEq; import nodeAST.relational.LT; import nodeAST.relational.NEq; import visitor.ASTVisitor; import visitor.IdentifiersTypeMatcher; import nodeAST.sign.Neg; import nodeAST.sign.Not; import nodeAST.sign.Pos; public class InvalidTypeOperands extends ASTVisitor { protected List<Expression> operandsList; private IdentifiersTypeMatcher typeMatcher; public InvalidTypeOperands() { this.operandsList = new LinkedList<>(); this.typeMatcher=new IdentifiersTypeMatcher(); } public void check(ASTNode root) throws Exception { this.typeMatcher.search(root); root.accept(this); if(operandsList.size()!=0) { String message= "ERROR: The following expressions contain operands of invalid" + " type to operators: \n"; for(Expression e: operandsList) message+=e.toString()+"\n"; throw new Exception(message); } } private void visitBoth(Expression leftHandOperand, Expression rightHandOperand) { leftHandOperand.accept(this); rightHandOperand.accept(this); } @Override public void visit(Add add, Expression leftHandOperand, Expression rightHandOperand) { if(! add.areOperandsTypeValid(typeMatcher)) this.recordError(add); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Div div, Expression leftHandOperand, Expression rightHandOperand) { if(! div.areOperandsTypeValid(typeMatcher)) this.recordError(div); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Mul mul, Expression leftHandOperand, Expression rightHandOperand) { if(! mul.areOperandsTypeValid(typeMatcher)) this.recordError(mul); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Sub sub, Expression leftHandOperand, Expression rightHandOperand) { if(! sub.areOperandsTypeValid(typeMatcher)) this.recordError(sub); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(And and, Expression leftHandOperand, Expression rightHandOperand) { if(! and.areOperandsTypeValid(typeMatcher)) this.recordError(and); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Or or, Expression leftHandOperand, Expression rightHandOperand) { if(! or.areOperandsTypeValid(typeMatcher)) this.recordError(or); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Eq eq, Expression leftHandOperand, Expression rightHandOperand) { if(! eq.areOperandsTypeValid(typeMatcher)) this.recordError(eq); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(GEq gEq, Expression leftHandOperand, Expression rightHandOperand) { if(! gEq.areOperandsTypeValid(typeMatcher)) this.recordError(gEq); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(GT gt, Expression leftHandOperand, Expression rightHandOperand) { if(! gt.areOperandsTypeValid(typeMatcher)) this.recordError(gt); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(LEq lEq, Expression leftHandOperand, Expression rightHandOperand) { if(! lEq.areOperandsTypeValid(typeMatcher)) this.recordError(lEq); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(LT lt, Expression leftHandOperand, Expression rightHandOperand) { if(! lt.areOperandsTypeValid(typeMatcher)) this.recordError(lt); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(NEq nEq, Expression leftHandOperand, Expression rightHandOperand) { if(! nEq.areOperandsTypeValid(typeMatcher)) this.recordError(nEq); visitBoth(leftHandOperand, rightHandOperand); } @Override public void visit(Neg neg, Expression operand) { if(! neg.areOperandsTypeValid(typeMatcher)) this.recordError(neg); operand.accept(this); } @Override public void visit(Not not, Expression operand) { if(! not.areOperandsTypeValid(typeMatcher)) this.recordError(not); operand.accept(this); } @Override public void visit(Pos pos, Expression operand) { if(! pos.areOperandsTypeValid(typeMatcher)) this.recordError(pos); operand.accept(this); } private boolean recordError(Expression exp) { return this.operandsList.add(exp); } }