package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.elaboration.transformations.TransformationBuilder; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; public class ETransformation extends SimplifiableExpression { public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object(); public final String name; public Query seed; public ETransformation(String name, Query seed) { this.name = name; this.seed = seed; } @Override protected void updateType() throws MatchException { setType(Types.UNIT); } @Override public Expression inferType(TypingContext context) { context.declareEffect(location, Types.PROC); seed.checkType(context); return compile(context); } private Expression compile(TypingContext context) { ArrayList rules = new ArrayList(); context.getEnvironment().collectRules(rules); Collections.sort(rules, new Comparator() { @Override public int compare(TransformationRule o1, TransformationRule o2) { return Integer.compare(Locations.beginOf(o1.location), Locations.beginOf(o2.location)); } }); // Translation TransformationBuilder tb = new TransformationBuilder(context.getErrorLog(), context); tb.handleSeed(seed); for(TransformationRule rule : rules) if(!rule.isAbstract) tb.handleRule(rule); Expression expression = tb.compileRules(); if(SCLCompilerConfiguration.SHOW_COMPILED_RULES) System.out.println(expression); return expression; } @Override public Expression resolve(TranslationContext context) { seed = seed.resolve(context); return this; } @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { location = loc; seed.setLocationDeep(loc); } } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); } }