package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.query.QExists; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.set.hash.TIntHashSet; public class EEnforce extends SimplifiableExpression { public Query query; public EEnforce(Query query) { this.query = query; } public Query getQuery() { return query; } @Override public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { query.collectVars(allVars, vars); } @Override protected void updateType() throws MatchException { setType(Types.tupleConstructor(0)); } @Override public Expression inferType(TypingContext context) { query.checkType(context); //context.declareEffect(location, query.getEffect(Query.W)); return compile(context); } public Expression compile(TypingContext context) { return query.generateEnforce(new EnforcingContext(context)); } @Override public Expression simplify(SimplificationContext context) { /*query = query.simplify(context); return query.generateEnforce(context);*/ throw new InternalCompilerError(); } @Override public Expression resolve(TranslationContext context) { context.pushExistentialFrame(); query = query.resolve(context); Variable[] variables = context.popExistentialFrame(); if(variables.length > 0) query = new QExists(variables, query); return this; } @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { location = loc; query.setLocationDeep(loc); } } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } @Override public Expression replace(ReplaceContext context) { return new EEnforce(query.replace(context)); } @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); } }