+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor;
+import org.simantics.scl.compiler.elaboration.equation.EqBasic;
+import org.simantics.scl.compiler.elaboration.equation.EqGuard;
+import org.simantics.scl.compiler.elaboration.equation.Equation;
+import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.Assignment;
+import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EBinary;
+import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
+import org.simantics.scl.compiler.elaboration.expressions.EBind;
+import org.simantics.scl.compiler.elaboration.expressions.EBlock;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
+import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
+import org.simantics.scl.compiler.elaboration.expressions.EEquations;
+import org.simantics.scl.compiler.elaboration.expressions.EError;
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
+import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
+import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
+import org.simantics.scl.compiler.elaboration.expressions.EIf;
+import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ELambda;
+import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
+import org.simantics.scl.compiler.elaboration.expressions.ELet;
+import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
+import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.EMatch;
+import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
+import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
+import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ERange;
+import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
+import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ESelect;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
+import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
+import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
+import org.simantics.scl.compiler.elaboration.expressions.EVar;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EWhen;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.ExpressionTransformer;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
+import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
+import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
+import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
+import org.simantics.scl.compiler.elaboration.expressions.block.StatementVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifierTransformer;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
+import org.simantics.scl.compiler.elaboration.query.QAlternative;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+import org.simantics.scl.compiler.elaboration.query.QConjunction;
+import org.simantics.scl.compiler.elaboration.query.QDisjunction;
+import org.simantics.scl.compiler.elaboration.query.QExists;
+import org.simantics.scl.compiler.elaboration.query.QIf;
+import org.simantics.scl.compiler.elaboration.query.QMapping;
+import org.simantics.scl.compiler.elaboration.query.QNegation;
+import org.simantics.scl.compiler.elaboration.query.Query;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
+
+public class StandardExpressionTransformer implements
+ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor,
+EquationVisitor, CHRAstQueryVisitor {
+
+ @Override
+ public Expression transform(EAmbiguous expression) {
+ if(expression.resolvedExpression != null)
+ expression.resolvedExpression = expression.resolvedExpression.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EApply expression) {
+ expression.function = expression.function.accept(this);
+ for(int i=0;i<expression.parameters.length;++i)
+ expression.parameters[i] = expression.parameters[i].accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EApplyType expression) {
+ expression.expression = expression.expression.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EAsPattern expression) {
+ expression.pattern = expression.pattern.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EBinary expression) {
+ expression.left = expression.left.accept(this);
+ for(EBinaryRightSide rs : expression.rights)
+ rs.right = rs.right.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EBind expression) {
+ expression.pattern = expression.pattern.accept(this);
+ expression.value = expression.value.accept(this);
+ expression.in = expression.in.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EViewPattern expression) {
+ expression.expression = expression.expression.accept(this);
+ expression.pattern = expression.pattern.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EBlock expression) {
+ for(Statement statement : expression.statements)
+ statement.accept(this);
+ return expression;
+ }
+
+ @Override
+ public void visit(BindStatement statement) {
+ statement.pattern = statement.pattern.accept(this);
+ statement.value = statement.value.accept(this);
+ }
+
+ @Override
+ public void visit(GuardStatement statement) {
+ statement.value = statement.value.accept(this);
+ }
+
+ @Override
+ public void visit(LetStatement statement) {
+ statement.pattern = statement.pattern.accept(this);
+ statement.value = statement.value.accept(this);
+ }
+
+ @Override
+ public void visit(RuleStatement statement) {
+ statement.head = statement.head.accept(this);
+ statement.body = statement.body.accept(this);
+ }
+
+ @Override
+ public void visit(IncludeStatement statement) {
+ statement.value = statement.value.accept(this);
+ }
+
+ public void transform(CHRQuery query) {
+ for(CHRLiteral lit : query.literals)
+ for(int i=0;i<lit.parameters.length;++i)
+ lit.parameters[i] = lit.parameters[i].accept(this);
+ }
+
+ public void transform(CHRRuleset ruleset) {
+ for(CHRRule rule : ruleset.rules) {
+ transform(rule.head);
+ transform(rule.body);
+ }
+ }
+
+ @Override
+ public Expression transform(ECHRRuleset expression) {
+ expression.in = expression.in.accept(this);
+ transform(expression.ruleset);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ECHRSelect expression) {
+ expression.expression = expression.expression.accept(this);
+ transform(expression.query);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ECHRRulesetConstructor expression) {
+ transform(expression.ruleset);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EConstant expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EEnforce expression) {
+ expression.query = expression.query.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EError expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EExternalConstant expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EFieldAccess expression) {
+ expression.parent = expression.parent.accept(this);
+ if(expression.accessor instanceof ExpressionAccessor) {
+ ExpressionAccessor expAcc = (ExpressionAccessor)expression.accessor;
+ expAcc.fieldName = expAcc.fieldName.accept(this);
+ }
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EGetConstraint expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EIf expression) {
+ expression.condition = expression.condition.accept(this);
+ expression.then_ = expression.then_.accept(this);
+ if(expression.else_ != null)
+ expression.else_ = expression.else_.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EIntegerLiteral expression) {
+ return expression;
+ }
+
+ protected void transformCases(Case[] cases) {
+ for(Case case_ : cases) {
+ for(int i=0;i<case_.patterns.length;++i)
+ case_.patterns[i] = case_.patterns[i].accept(this);
+ case_.value = case_.value.accept(this);
+ }
+ }
+
+ @Override
+ public Expression transform(ELambda expression) {
+ transformCases(expression.cases);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ELambdaType expression) {
+ expression.value = expression.value.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ELet expression) {
+ expression.in = expression.in.accept(this);
+ for(Assignment assign : expression.assignments) {
+ assign.pattern = assign.pattern.accept(this);
+ assign.value = assign.value.accept(this);
+ }
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EListComprehension expression) {
+ expression.head = expression.head.accept(this);
+ expression.qualifier = expression.qualifier.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EListLiteral expression) {
+ for(int i=0;i<expression.components.length;++i)
+ expression.components[i] = expression.components[i].accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ELiteral expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EMatch expression) {
+ for(int i=0;i<expression.scrutinee.length;++i)
+ expression.scrutinee[i] = expression.scrutinee[i].accept(this);
+ transformCases(expression.cases);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EPlaceholder expression) {
+ expression.expression = expression.expression.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EPreLet expression) {
+ for(LetStatement statement : expression.assignments) {
+ statement.pattern = statement.pattern.accept(this);
+ statement.value = statement.value.accept(this);
+ }
+ expression.in = expression.in.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EPreRuleset expression) {
+ for(RuleStatement rule : expression.statements) {
+ rule.body = rule.body.accept(this);
+ rule.head = rule.head.accept(this);
+ }
+ expression.in = expression.in.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ECoveringBranchPoint expression) {
+ expression.expression = expression.expression.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ERange expression) {
+ expression.from = expression.from.accept(this);
+ expression.to = expression.to.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ERealLiteral expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ERecord expression) {
+ for(FieldAssignment field : expression.fields)
+ if(field.value != null)
+ field.value = field.value.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ERuleset expression) {
+ for(ERuleset.DatalogRule rule : expression.rules) {
+ rule.body = rule.body.accept(this);
+ for(int i=0;i<rule.headParameters.length;++i)
+ rule.headParameters[i] = rule.headParameters[i].accept(this);
+ }
+ expression.in = expression.in.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ESelect expression) {
+ expression.query = expression.query.accept(this);
+ expression.expression = expression.expression.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ESimpleLambda expression) {
+ expression.value = expression.value.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ESimpleLet expression) {
+ expression.value = expression.value.accept(this);
+ expression.in = expression.in.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EStringLiteral expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ETransformation expression) {
+ expression.seed = expression.seed.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(ETypeAnnotation expression) {
+ expression.value = expression.value.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EVar expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EVariable expression) {
+ return expression;
+ }
+
+ @Override
+ public Expression transform(EWhen expression) {
+ expression.query = expression.query.accept(this);
+ expression.action = expression.action.accept(this);
+ return expression;
+ }
+
+ @Override
+ public Expression transform(GuardedExpressionGroup expression) {
+ for(GuardedExpression ge : expression.expressions) {
+ for(int i=0;i<ge.guards.length;++i)
+ ge.guards[i] = ge.guards[i].accept(this);
+ ge.value = ge.value.accept(this);
+ }
+ return expression;
+ }
+
+ @Override
+ public ListQualifier transform(ListAssignment qualifier) {
+ qualifier.pattern = qualifier.pattern.accept(this);
+ qualifier.value = qualifier.value.accept(this);
+ return qualifier;
+ }
+
+ @Override
+ public ListQualifier transform(ListGenerator qualifier) {
+ qualifier.pattern = qualifier.pattern.accept(this);
+ qualifier.value = qualifier.value.accept(this);
+ return qualifier;
+ }
+
+ @Override
+ public ListQualifier transform(ListGuard qualifier) {
+ qualifier.condition = qualifier.condition.accept(this);
+ return qualifier;
+ }
+
+ @Override
+ public ListQualifier transform(ListSeq qualifier) {
+ qualifier.a = qualifier.a.accept(this);
+ qualifier.b = qualifier.b.accept(this);
+ return qualifier;
+ }
+
+ @Override
+ public ListQualifier transform(ListThen qualifier) {
+ qualifier.left = qualifier.left.accept(this);
+ qualifier.transformer = qualifier.transformer.accept(this);
+ if(qualifier.by != null)
+ qualifier.by = qualifier.by.accept(this);
+ return qualifier;
+ }
+
+ @Override
+ public Query transform(QAlternative query) {
+ for(int i=0;i<query.queries.length;++i)
+ query.queries[i] = query.queries[i].accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QAtom query) {
+ for(int i=0;i<query.parameters.length;++i)
+ query.parameters[i] = query.parameters[i].accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QConjunction query) {
+ for(int i=0;i<query.queries.length;++i)
+ query.queries[i] = query.queries[i].accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QDisjunction query) {
+ for(int i=0;i<query.queries.length;++i)
+ query.queries[i] = query.queries[i].accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QExists query) {
+ query.query = query.query.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QIf query) {
+ query.condition = query.condition.accept(this);
+ query.thenQuery = query.thenQuery.accept(this);
+ query.elseQuery = query.elseQuery.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QMapping query) {
+ for(int i=0;i<query.parameters.length;++i)
+ query.parameters[i] = query.parameters[i].accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QNegation query) {
+ query.query = query.query.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QPreBinds query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QPreEquals query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QPreExists query) {
+ query.query = query.query.accept(this);
+ return query;
+ }
+
+ @Override
+ public Query transform(QPreGuard query) {
+ query.guard = query.guard.accept(this);
+ return query;
+ }
+
+ @Override
+ public Expression transform(EEquations expression) {
+ for(Equation equation : expression.equations)
+ equation.accept(this);
+ return expression;
+ }
+
+ @Override
+ public void visit(EqBasic equation) {
+ equation.left = equation.left.accept(this);
+ equation.right = equation.right.accept(this);
+ }
+
+ @Override
+ public void visit(EqGuard equation) {
+ equation.guard = equation.guard.accept(this);
+ }
+
+ @Override
+ public void visit(CHRStatement statement) {
+ statement.head.accept(this);
+ statement.body.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstAtom query) {
+ query.expression = query.expression.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstBinds query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstConjunction query) {
+ for(CHRAstQuery conjunct : query.conjuncts)
+ conjunct.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstEquals query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstNegation query) {
+ query.subquery.accept(this);
+ }
+
+}