1 package org.simantics.scl.compiler.elaboration.query.compilation;
3 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.Just;
4 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.Nothing;
5 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
6 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda;
7 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
9 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
10 import org.simantics.scl.compiler.common.names.Name;
11 import org.simantics.scl.compiler.common.names.Names;
12 import org.simantics.scl.compiler.compilation.CompilationContext;
13 import org.simantics.scl.compiler.constants.BooleanConstant;
14 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
15 import org.simantics.scl.compiler.elaboration.expressions.Case;
16 import org.simantics.scl.compiler.elaboration.expressions.EApply;
17 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
18 import org.simantics.scl.compiler.elaboration.expressions.EIf;
19 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
20 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
21 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
22 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
23 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
24 import org.simantics.scl.compiler.elaboration.expressions.Expression;
25 import org.simantics.scl.compiler.elaboration.expressions.Variable;
26 import org.simantics.scl.compiler.elaboration.java.Builtins;
27 import org.simantics.scl.compiler.errors.Locations;
28 import org.simantics.scl.compiler.types.TPred;
29 import org.simantics.scl.compiler.types.Type;
30 import org.simantics.scl.compiler.types.Types;
31 import org.simantics.scl.compiler.types.exceptions.MatchException;
33 public class QueryCompilationContext {
34 TypingContext context;
35 QueryCompilationMode mode;
37 Expression continuation;
38 double branching = 1.0;
41 public QueryCompilationContext(
42 TypingContext context,
43 QueryCompilationMode mode,
45 Expression continuation) {
46 this.context = context;
48 this.resultType = resultType;
49 this.continuation = continuation;
52 public Expression failure() {
54 case ITERATE: return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
55 case GET_FIRST: return new EConstant(Builtins.Nothing, resultType);
56 case GET_ALL: return new EConstant(Builtins.LIST_CONSTRUCTORS[0], resultType);
57 case CHECK: return new ELiteral(new BooleanConstant(false));
58 default: throw new InternalCompilerError();
62 public Expression disjunction(Expression a, Expression b) {
64 case ITERATE: return new ESimpleLet(new Variable("_", Types.UNIT), a, b);
66 Variable var = new Variable("temp", a.getType());
68 new Case(new EConstant(Builtins.Nothing), b),
69 new Case(new EVariable(var), new EVariable(var)));
73 return new EApply(context.getCompilationContext().getConstant(Names.Prelude_appendList,
74 Types.matchApply(Types.LIST, a.getType())), a, b);
75 } catch (MatchException e) {
76 throw new InternalCompilerError();
79 case CHECK: return new EIf(a, new ELiteral(new BooleanConstant(true)), b);
80 default: throw new InternalCompilerError();
84 public Expression condition(Expression condition, Expression continuation) {
85 return new EIf(condition, continuation, failure());
88 public void condition(Expression condition) {
89 continuation = condition(condition, continuation);
92 public void equalityCondition(long location, Expression a, Expression b) {
93 Type type = a.getType();
97 context.getCompilationContext().getConstant(Names.Builtin_equals, type),
105 public void let(Variable variable, Expression value) {
106 continuation = new ESimpleLet(variable, value, continuation);
109 public void iterateMaybe(Variable variable, Expression value) {
110 continuation = new EMatch(value,
111 new Case(Nothing(variable.getType()), failure()),
112 new Case(Just(var(variable)), continuation));
115 public void match(Expression pattern, Expression value, boolean mayFail) {
117 continuation = new EMatch(value,
118 new Case(pattern, continuation),
119 new Case(new EVariable(new Variable("_", pattern.getType())), failure()));
121 continuation = new EMatch(value,
122 new Case(pattern, continuation));
125 public void iterateList(Variable variable, Expression list) {
129 continuation = new EApply(
130 Locations.NO_LOCATION,
132 context.getCompilationContext().getConstant(Names.Prelude_iterList, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
134 new ESimpleLambda(Types.PROC, variable, continuation),
140 continuation = new EApply(
141 Locations.NO_LOCATION,
143 context.getCompilationContext().getConstant(Names.Prelude_any, variable.getType(), Types.PROC),
145 new ESimpleLambda(Types.PROC, variable, continuation),
151 continuation = new EApply(
152 Locations.NO_LOCATION,
154 context.getCompilationContext().getConstant(Names.Prelude_concatMap, variable.getType(), Types.PROC,
155 Types.matchApply(Types.LIST, continuation.getType())),
157 new ESimpleLambda(Types.PROC, variable, continuation),
163 continuation = new EApply(
164 Locations.NO_LOCATION,
166 context.getCompilationContext().getConstant(Names.Prelude_mapFirst, variable.getType(), Types.PROC,
167 Types.matchApply(Types.MAYBE, continuation.getType())),
169 new ESimpleLambda(Types.PROC, variable, continuation),
174 default: throw new InternalCompilerError("iterateList could not handle mode " + mode);
176 } catch(MatchException e) {
177 throw new InternalCompilerError(e);
181 public void iterateVector(Variable variable, Expression vector) {
185 continuation = new EApply(
186 Locations.NO_LOCATION,
188 context.getCompilationContext().getConstant(Names.Vector_iterVector, variable.getType(), Types.PROC, continuation.getType()),
190 new ESimpleLambda(Types.PROC, variable, continuation),
196 continuation = new EApply(
197 Locations.NO_LOCATION,
199 context.getCompilationContext().getConstant(Names.Vector_anyVector, variable.getType(), Types.PROC),
201 new ESimpleLambda(Types.PROC, variable, continuation),
207 continuation = new EApply(
208 Locations.NO_LOCATION,
210 context.getCompilationContext().getConstant(Names.Vector_concatMapVector, variable.getType(), Types.PROC,
211 Types.matchApply(Types.LIST, continuation.getType())),
213 new ESimpleLambda(Types.PROC, variable, continuation),
219 continuation = new EApply(
220 Locations.NO_LOCATION,
222 context.getCompilationContext().getConstant(Names.Vector_mapFirstVector, variable.getType(), Types.PROC,
223 Types.matchApply(Types.MAYBE, continuation.getType())),
225 new ESimpleLambda(Types.PROC, variable, continuation),
230 default: throw new InternalCompilerError("iterateVector could not handle mode " + mode);
232 } catch(MatchException e) {
233 throw new InternalCompilerError(e);
237 public void iterateMSet(Variable variable, Expression set) {
241 continuation = apply(context.getCompilationContext(), Types.PROC, Names.MSet_iter, variable.getType(), Types.PROC, continuation.getType(),
242 lambda(Types.PROC, variable, continuation),
247 continuation = apply(context.getCompilationContext(), Types.PROC, Names.MSet_mapFirst, variable.getType(), Types.PROC,
248 Types.matchApply(Types.MAYBE, continuation.getType()),
249 lambda(Types.PROC, variable, continuation),
253 default: throw new InternalCompilerError("iterateMSet could not handle mode " + mode);
255 } catch(MatchException e) {
256 throw new InternalCompilerError(e);
260 public void updateCost(double localBranching, double localCost) {
261 branching *= localBranching;
262 cost *= localBranching;
266 public Expression getConstant(Name name, Type[] typeParameters) {
267 return context.getCompilationContext().getConstant(name, typeParameters);
270 public QueryCompilationContext createCheckContext() {
271 return new QueryCompilationContext(context, QueryCompilationMode.CHECK,
272 null, new ELiteral(new BooleanConstant(true)));
275 public double getBranching() {
279 public double getCost() {
283 public QueryCompilationContext createSubcontext(Expression innerExpression) {
284 return new QueryCompilationContext(context, mode, resultType, innerExpression);
287 public void setContinuation(Expression continuation) {
288 this.continuation = continuation;
291 public Expression getContinuation() {
295 public Expression disjunction(Expression[] disjuncts) {
296 Expression result = failure();
297 for(int i=disjuncts.length-1;i>=0;--i)
298 result = disjunction(disjuncts[i], result);
302 public TypingContext getTypingContext() {
306 public EVariable getEvidence(long location, TPred pred) {
307 EVariable evidence = new EVariable(location, null);
308 evidence.setType(pred);
309 context.addConstraintDemand(evidence);
313 public CompilationContext getCompilationContext() {
314 return context.getCompilationContext();