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