]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java
bf3b818f56c01c844b078705751ca1f3d20fd873
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / ECHRSelect.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.common.names.Names;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.constants.NoRepConstant;
8 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
9 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
10 import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
11 import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;
12 import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;
13 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
14 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
15 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
16 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
17 import org.simantics.scl.compiler.errors.Locations;
18 import org.simantics.scl.compiler.internal.codegen.references.IVal;
19 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
20 import org.simantics.scl.compiler.types.Types;
21 import org.simantics.scl.compiler.types.exceptions.MatchException;
22 import org.simantics.scl.compiler.types.kinds.Kinds;
23
24 public class ECHRSelect extends Expression {
25     public CHRQuery query;
26     public Variable[] existentialVariables;
27     public Expression expression;
28     private ArrayList<PlanOp> planOps;
29     private CHRRuleset currentRuleset;
30     
31     public ECHRSelect(Expression expression, CHRQuery query) {
32         this.expression = expression;
33         this.query = query;
34     }
35
36     @Override
37     protected void updateType() throws MatchException {
38         setType(Types.list(expression.getType()));
39     }
40
41     @Override
42     public Expression inferType(TypingContext context) {
43         for(Variable variable : existentialVariables)
44             variable.setType(Types.metaVar(Kinds.STAR));
45         query.checkType(context);
46         expression = expression.inferType(context);
47         return this;
48     }
49     
50     @Override
51     public Expression simplify(SimplificationContext simplificationContext) {
52         this.expression = expression.simplify(simplificationContext);
53         query.simplify(simplificationContext);
54         
55         CompilationContext compilationContext = simplificationContext.getCompilationContext();
56         QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
57         if(query.createQueryPlan(context, null, -1, null))
58             planOps = context.getPlanOps();
59
60         return this;
61     }
62     
63     @Override
64     public IVal toVal(CompilationContext context, CodeWriter w) {
65         IVal list = w.apply(location, context.getValue(Names.MList_create).getValue(), NoRepConstant.UNIT);
66         planOps.add(new PlanOp(location) {
67             @Override
68             public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
69                 w.apply(location, context.getValue(Names.MList_add).getValue(), list, expression.toVal(context, w));
70             }
71         });
72         PlanRealizer realizer = new PlanRealizer(context, currentRuleset, currentRuleset != null ? currentRuleset.runtimeRulesetVariable : null, null, planOps);
73         realizer.nextOp(w);
74         return w.apply(location, context.getValue(Names.MList_freeze).getValue(), list);
75     }
76
77     @Override
78     public Expression resolve(TranslationContext context) {
79         currentRuleset = context.currentRuleset;
80         
81         context.pushExistentialFrame();
82         query.resolve(context);
83         context.disallowNewExistentials();
84         expression = expression.resolve(context);
85         existentialVariables = context.popExistentialFrame();
86         return this;
87     }
88
89     @Override
90     public void setLocationDeep(long loc) {
91         if(location == Locations.NO_LOCATION) {
92             query.setLocationDeep(loc);
93             expression.setLocationDeep(loc);
94         }
95     }
96
97     @Override
98     public void accept(ExpressionVisitor visitor) {
99         visitor.visit(this);
100     }
101
102     @Override
103     public Expression accept(ExpressionTransformer transformer) {
104         return transformer.transform(this);
105     }
106 }