package org.overture.pog.visitors; import java.util.List; import java.util.Vector; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.analysis.QuestionAnswerAdaptor; import org.overture.ast.expressions.AApplyExp; import org.overture.ast.expressions.AExistsExp; import org.overture.ast.expressions.AFieldExp; import org.overture.ast.expressions.AMkTypeExp; import org.overture.ast.expressions.APostOpExp; import org.overture.ast.expressions.AVariableExp; import org.overture.ast.expressions.PExp; import org.overture.ast.expressions.SBinaryExp; import org.overture.ast.expressions.SUnaryExp; import org.overture.ast.node.INode; import org.overture.pog.utility.Substitution; //FIXME complete the variable substitution visitor public class VariableSubVisitor extends QuestionAnswerAdaptor<Substitution, PExp> implements IVariableSubVisitor { private IVariableSubVisitor main; public VariableSubVisitor() { main = this; } public VariableSubVisitor(IVariableSubVisitor main) { this.main = main; } // Let's try to do most stuff with S family @Override public PExp defaultSBinaryExp(SBinaryExp node, Substitution question) throws AnalysisException { PExp subl = node.getLeft().clone().apply(main, question); PExp subr = node.getRight().clone().apply(main, question); node.setLeft(subl.clone()); node.setRight(subr.clone()); return node; } @Override public PExp defaultSUnaryExp(SUnaryExp node, Substitution question) throws AnalysisException { PExp sub = node.getExp().clone().apply(main, question); node.setExp(sub.clone()); return node; } // cases here for what we need @Override public PExp caseAExistsExp(AExistsExp node, Substitution question) throws AnalysisException { PExp sub = node.getPredicate().clone().apply(main, question); node.setPredicate(sub.clone()); return node; } @Override public PExp caseAFieldExp(AFieldExp node, Substitution question) throws AnalysisException { PExp obj = node.getObject().clone().apply(main, question); node.setObject(obj.clone()); return node; } @Override public PExp caseAPostOpExp(APostOpExp node, Substitution question) throws AnalysisException { PExp sub = node.getPostexpression().clone().apply(main, question); node.setPostexpression(sub.clone()); return node; } @Override public PExp caseAVariableExp(AVariableExp node, Substitution question) throws AnalysisException { if (question.containsKey(node)) { return question.get(node).clone(); } return node; } @Override public PExp caseAApplyExp(AApplyExp node, Substitution question) throws AnalysisException { node.setArgs(distribute(node.getArgs(), question)); return node; } @Override public PExp caseAMkTypeExp(AMkTypeExp node, Substitution question) throws AnalysisException { node.setArgs(distribute(node.getArgs(), question)); return node; } @Override public PExp defaultPExp(PExp node, Substitution question) throws AnalysisException { return node; } @Override public PExp createNewReturnValue(Object arg0, Substitution arg1) throws AnalysisException { throw new AnalysisException("Substitution visitor applied to non-expression object " + arg0.toString()); } @Override public PExp createNewReturnValue(INode arg0, Substitution arg1) throws AnalysisException { throw new AnalysisException("Substitution visitor applied to non-expression object " + arg0.toString()); } private List<PExp> distribute(List<PExp> args, Substitution question) throws AnalysisException { List<PExp> subs = new Vector<PExp>(); for (PExp a : args) { subs.add(a.clone().apply(main, question)); } return subs; } }