]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expressions.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / Expressions.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import java.util.List;
4
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.common.names.Name;
7 import org.simantics.scl.compiler.constants.IntegerConstant;
8 import org.simantics.scl.compiler.constants.JavaComparisonToZeroOperation;
9 import org.simantics.scl.compiler.constants.JavaMathOperation;
10 import org.simantics.scl.compiler.constants.NoRepConstant;
11 import org.simantics.scl.compiler.constants.StringConstant;
12 import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
13 import org.simantics.scl.compiler.elaboration.java.Builtins;
14 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
15 import org.simantics.scl.compiler.elaboration.query.Query;
16 import org.simantics.scl.compiler.errors.Locations;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.exceptions.MatchException;
20 import org.simantics.scl.compiler.types.util.MultiFunction;
21
22 public class Expressions {
23     public static Expression apply(Expression function, Expression ... parameters) {
24         if(parameters.length == 0)
25             return function;
26         Type ftype = function.getType();
27         try {
28             MultiFunction mfun = Types.matchFunction(ftype, parameters.length);
29             EApply apply = new EApply(Locations.NO_LOCATION, mfun.effect, function, parameters);
30             apply.setType(mfun.returnType);
31             return apply;
32         } catch (MatchException e) {
33             throw new InternalCompilerError("Type of the function " + ftype + " is not compatible with the number of parameters.");
34         }
35     }
36     
37     public static Expression apply(Type effect, Expression function, Expression ... parameters) {
38         return new EApply(Locations.NO_LOCATION, effect, function, parameters);
39     }
40     
41     public static Expression apply(EnvironmentalContext context, Type effect, Name name, Expression ... parameters) {
42         return apply(effect, constant(context, name), parameters);
43     }
44     
45     public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Expression ... parameters) {
46         return apply(effect, constant(context, name, typeParameter1), parameters);
47     }
48     
49     public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Type typeParameter2, Expression ... parameters) {
50         return apply(effect, constant(context, name, typeParameter1, typeParameter2), parameters);
51     }
52
53     public static Expression apply(EnvironmentalContext context, Type effect, Name name, Type typeParameter1, Type typeParameter2, Type typeParameter3, Expression ... parameters) {
54         return apply(effect, constant(context, name, typeParameter1, typeParameter2, typeParameter3), parameters);
55     }
56
57     public static Expression constant(SCLValue value) {
58         return new EConstant(value);
59     }
60     
61     public static Expression constant(EnvironmentalContext context, Name name) {
62         return new EConstant(context.getValue(name));
63     }
64     
65     public static Expression constant(EnvironmentalContext context, Name name, Type ... typeParameters) {
66         return new EConstant(context.getValue(name), typeParameters);
67     }
68
69     public static Expression if_(Expression condition, Expression then_, Expression else_) {
70         return new EIf(condition, then_, else_);
71     }
72     
73     public static Expression var(Variable variable) {
74         return new EVariable(variable);
75     }
76     
77     public static Variable newVar(String name, Type type) {
78         return new Variable(name, type);
79     }
80     
81     public static Variable newBlankVar(Type type) {
82         return new Variable("_", type);
83     }
84     
85     public static Expression computation(Type effect, Expression value) {
86         return new ESimpleLambda(
87                 effect,
88                 newBlankVar(Types.PUNIT),
89                 value);
90     }
91     
92     public static Expression blank(Type type) {
93         return new EVariable(newBlankVar(type));
94     }
95     public static Expression integer(int value) {
96         return new ELiteral(new IntegerConstant(value));
97     }
98
99     public static Expression string(String value) {
100         return new ELiteral(new StringConstant(value));
101     }
102
103     public static Expression tuple() {
104         return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
105     }
106     
107     public static Expression punit() {
108         return new ELiteral(NoRepConstant.PUNIT);
109     }
110     
111     public static Expression tuple(Expression ... cs) {
112         if(cs.length == 1)
113             return cs[0];
114         Type[] typeParameters = new Type[cs.length];
115         for(int i=0;i<cs.length;++i)
116             typeParameters[i] = cs[i].getType();
117         EApply result = new EApply(
118                 new EConstant(Builtins.TUPLE_CONSTRUCTORS[cs.length], typeParameters),
119                 cs);
120         result.setType(Types.tuple(Types.getTypes(cs)));
121         return result;
122     }
123     
124     public static Expression[] vars(Variable ... variables) {
125         Expression[] expressions = new Expression[variables.length];
126         for(int i=0;i<variables.length;++i)
127             expressions[i] = new EVariable(variables[i]);
128         return expressions;
129     }
130     
131     public static Expression[] vars(List<Variable> variables) {
132         Expression[] expressions = new Expression[variables.size()];
133         for(int i=0;i<variables.size();++i)
134             expressions[i] = new EVariable(variables.get(i));
135         return expressions;
136     }
137     
138     public static Expression match(Expression scrutinee,
139             Expression pattern1, Expression value1) {
140         return new EMatch(scrutinee, new Case(pattern1, value1));
141     }
142     
143     public static Expression match(Expression scrutinee,
144             Expression pattern1, Expression value1,
145             Expression pattern2, Expression value2) {
146         return new EMatch(scrutinee, new Case(pattern1, value1), new Case(pattern2, value2));
147     }
148     
149     public static Expression matchWithDefault(Expression scrutinee,
150             Expression pattern1, Expression value1,
151             Expression default_) {
152         return new EMatch(scrutinee, new Case(pattern1, value1), new Case(blank(pattern1.getType()), default_));
153     }
154     
155     public static Expression let(Variable target, Expression value, Expression in) {
156         return new ESimpleLet(target, value, in);
157     }
158     
159     public static Expression letRec(Variable target, Expression value, Expression in) {
160         return new ELet(Locations.NO_LOCATION, new Assignment[] {new Assignment(var(target), value)}, in);
161     }
162     
163     public static Expression letRec(Variable[] targets, Expression[] values, Expression in) {
164         if(targets.length != values.length)
165             throw new InternalCompilerError();
166         Assignment[] assignments = new Assignment[targets.length];
167         for(int i=0;i<targets.length;++i)
168             assignments[i] = new Assignment(var(targets[i]), values[i]);
169         return new ELet(Locations.NO_LOCATION, assignments, in);
170     }
171     
172     public static Expression lambda(Type effect, Variable var, Expression value) {
173         return new ESimpleLambda(effect, var, value);
174     }
175     
176     public static Expression lambda(Variable var, Expression value) {
177         return new ESimpleLambda(value.getEffect(), var, value);
178     }
179     
180     public static Expression lambda(Type effect, Variable[] vars, Expression value) {
181         for(int i=vars.length-1;i>=0;--i) {
182             value = new ESimpleLambda(effect, vars[i], value);
183             effect = Types.NO_EFFECTS;
184         }
185         return value;
186     }
187     
188     public static Expression lambda(Type effect, List<Variable> vars, Expression value) {
189         for(int i=vars.size()-1;i>=0;--i) {
190             value = new ESimpleLambda(effect, vars.get(i), value);
191             effect = Types.NO_EFFECTS;
192         }
193         return value;
194     }
195     
196     public static Expression lambda(Variable[] vars, Expression value) {
197         return lambda(value.getEffect(), vars, value);
198     }
199     
200     public static Expression lambda(List<Variable> vars, Expression value) {
201         return lambda(value.getEffect(), vars, value);
202     }
203     
204     public static Expression Nothing(Type type) {
205         return new EConstant(Builtins.Nothing, type);
206     }
207     
208     public static Expression Just(Expression expression) {
209         return apply(Types.NO_EFFECTS, new EConstant(Builtins.Just, expression.getType()), expression);
210     }
211     
212     public static Expression seq(Expression first, Expression second) {
213         return let(newBlankVar(first.getType()), first, second);
214     }
215     
216     public static Expression as(Variable var, Expression value) {
217         return new EAsPattern(var, value);
218     }
219     
220     public static Expression loc(long location, Expression expression) {
221         expression.setLocationDeep(location);
222         return expression;
223     }
224     
225     public static Query loc(long location, Query query) {
226         query.setLocationDeep(location);
227         return query;
228     }
229
230     public static Expression applyTypes(Expression expression, Type[] types) {
231         for(Type type : types)
232             expression = new EApplyType(expression, type);
233         return expression;
234     }
235     
236     public static Expression isZeroInteger(Expression value) {
237         return apply(Types.NO_EFFECTS, new ELiteral(JavaComparisonToZeroOperation.IEQUAL), value);
238     }
239     
240     public static Expression addInteger(Expression a, Expression b) {
241         return apply(Types.NO_EFFECTS, new ELiteral(JavaMathOperation.IADD), a, b);
242     }
243
244     public static Expression externalConstant(Object value, Type type) {
245         return new EExternalConstant(value, type);
246     }
247 }