]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java
Merge "Ensure GetElementClassRequest is not constructed without elementFactory"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / contexts / SimplificationContext.java
1 package org.simantics.scl.compiler.elaboration.contexts;
2
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.common.names.Name;
5 import org.simantics.scl.compiler.common.names.Names;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.constants.Constant;
8 import org.simantics.scl.compiler.elaboration.expressions.Case;
9 import org.simantics.scl.compiler.elaboration.expressions.EApply;
10 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
11 import org.simantics.scl.compiler.elaboration.expressions.EError;
12 import org.simantics.scl.compiler.elaboration.expressions.EIf;
13 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
14 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
15 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
16 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
17 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
18 import org.simantics.scl.compiler.elaboration.expressions.Expression;
19 import org.simantics.scl.compiler.elaboration.expressions.Variable;
20 import org.simantics.scl.compiler.elaboration.java.Builtins;
21 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
22 import org.simantics.scl.compiler.environment.Environment;
23 import org.simantics.scl.compiler.errors.ErrorLog;
24 import org.simantics.scl.compiler.errors.Locations;
25 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
26 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
27 import org.simantics.scl.compiler.types.Type;
28 import org.simantics.scl.compiler.types.Types;
29 import org.simantics.scl.compiler.types.exceptions.MatchException;
30 import org.simantics.scl.compiler.types.util.MultiFunction;
31
32 import gnu.trove.list.array.TLongArrayList;
33 import gnu.trove.map.hash.THashMap;
34
35 public class SimplificationContext implements EnvironmentalContext {
36     CompilationContext compilationContext;
37     Environment environment;
38     ErrorLog errorLog;
39     
40     THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
41     THashMap<Variable, Expression> inlinedVariables = new THashMap<Variable, Expression>();
42     
43     TLongArrayList locatableStack = new TLongArrayList();
44     long locatable;
45     JavaTypeTranslator javaTypeTranslator;
46     JavaReferenceValidator<?, ?, ?, ?> validator;
47     
48     public SimplificationContext(CompilationContext compilationContext, JavaReferenceValidator<?, ?, ?, ?> validator) {
49         this.compilationContext = compilationContext;
50         this.environment = compilationContext.environment;
51         this.errorLog = compilationContext.errorLog;
52         this.javaTypeTranslator = compilationContext.javaTypeTranslator;
53         this.validator = validator;         
54     }
55     
56     public Environment getEnvironment() {
57         return environment;
58     }
59     
60     public ErrorLog getErrorLog() {
61         return errorLog;
62     }
63     
64     public void pushLocation(long loc) {
65         locatableStack.add(locatable);
66         locatable = loc;
67     }
68     
69     public void popLocation() {
70         locatable = locatableStack.removeAt(locatableStack.size()-1);
71     }
72     
73     public SCLValue getValue(Name name) {
74         if(constants.containsKey(name))
75             return constants.get(name);
76         SCLValue value = environment.getValue(name);
77         if(value == null)
78             errorLog.log(locatable, "Couldn't find " + name + ".");
79         constants.put(name, value);
80         return value;
81     }
82     
83     public Expression getConstant(Name name, Type ... typeParameters) {
84         SCLValue value = getValue(name);
85         if(value == null)
86             return new EError(locatable);
87         return new EConstant(value, typeParameters);
88     }
89     
90     public Expression apply(Expression f, Expression ... ps) {
91         Expression result = f;
92         Type type = f.getType();
93         for(Expression p : ps) {
94             result = new EApply(locatable, result, p);
95             MultiFunction mfun;
96             try {
97                 mfun = Types.matchFunction(type, 1);
98             } catch (MatchException e) {
99                 throw new InternalCompilerError(e);
100             }
101             type = mfun.returnType;
102             result.setType(type);
103         }
104         return result;
105     }
106     
107     public Expression tuple(Expression ... cs) {
108         if(cs.length == 1)
109             return cs[0];
110         Type[] typeParameters = new Type[cs.length];
111         for(int i=0;i<cs.length;++i)
112             typeParameters[i] = cs[i].getType();
113         Expression result = new EConstant(locatable, Builtins.TUPLE_CONSTRUCTORS[cs.length], typeParameters);
114         for(Expression c : cs)
115             result = new EApply(locatable, result, c);
116         result.setType(Types.tuple(Types.getTypes(cs)));
117         return result;
118     }
119
120     public Expression var(Variable var) {
121         EVariable result =  new EVariable(locatable, var);
122         result.setType(var.getType());
123         return result;
124     }
125     
126     public Expression simpleLambda(Variable var, Expression val) {
127         ESimpleLambda result = new ESimpleLambda(var, val);
128         result.setType(Types.function(var.getType(), val.getType()));
129         return result;
130     }
131     
132     public Expression lambda(Expression pat, Expression val) {
133         return new ELambda(locatable,  pat, val);
134     }
135     
136     public Expression lambda(Case ... cases) {
137         return new ELambda(locatable, cases);
138     }
139     
140     /*
141     public Expression constant(SCLValue value) {
142         Expression result = new EConstant(loc, value);
143         result.setType(value.getType());
144         return result;
145     }
146     
147     public Expression constant(SCLValue value, Type ... typeParameters) {
148         Expression result = constant(value);
149         for(Type typeParameter : typeParameters)
150             result = new EApplyType(loc, result, typeParameter);
151         result.setType(Types.instantiate(value.getType(), typeParameters));
152         return result;
153     }
154     */
155     
156     public Expression if_(Expression condition, Expression then_, Expression else_) {
157         return new EIf(locatable, condition, then_, else_);
158     }
159     
160     public Expression mapList(Expression f, Expression l) {
161         try {
162             MultiFunction mfun = Types.matchFunction(f.getType(), 1);
163             return apply(getConstant(Names.Prelude_mapList, new Type[] {mfun.parameterTypes[0], mfun.returnType}), f, l);
164         } catch (MatchException e) {
165             throw new InternalCompilerError(e);
166         }
167     }
168     
169     public Expression guardList(Expression cond) {
170         return apply(getConstant(Names.Prelude_guardList), cond);
171     }
172
173     public Expression concatMap(Expression f, Expression l) {
174         try {
175             MultiFunction mfun = Types.matchFunction(f.getType(), 1);
176             return apply(getConstant(Names.Prelude_concatMap, new Type[] {
177                     mfun.parameterTypes[0], mfun.effect,
178                     Types.matchApply(Types.LIST, mfun.returnType)}
179             ), f, l);
180         } catch (MatchException e) {
181             throw new InternalCompilerError(e);
182         }
183     }
184     
185     public Expression emptyList(Type type) {
186         return getConstant(Names.Prelude_emptyList, type);
187     }
188     
189     public Expression singletonList(Expression e) {
190         return apply(getConstant(Names.Prelude_singletonList, e.getType()), e);
191     }
192
193     public Expression match(Expression scrutinee, Expression pattern, Expression value) {
194         Case case_ = new Case(pattern, value);
195         return new EMatch(scrutinee, new Case[] { case_ });        
196     }
197     
198     public Expression match(Expression scrutinee, Case ... cases) {
199         return new EMatch(scrutinee, cases);
200     }
201
202     public Expression literal(Constant constant) {
203         return new ELiteral(constant);
204     }
205     
206     @SuppressWarnings({ "unchecked" })
207     public JavaReferenceValidator<Object,Object,Object,Object> getJavaReferenceValidator() {
208         return (JavaReferenceValidator<Object,Object,Object,Object>)validator;
209     }
210     
211     public JavaTypeTranslator getJavaTypeTranslator() {
212         return javaTypeTranslator;
213     }
214
215     /**
216      * Variable added to the context will be inlined to the
217      * given expression in subsequent simplifications. It is assumed
218      * that the value is already simplified.
219      */
220     public void addInlinedVariable(Variable variable, Expression value) {
221         inlinedVariables.put(variable, value);        
222     }
223
224     public Expression getInlinedValue(Variable variable) {
225         return inlinedVariables.get(variable);
226     }
227
228     public EVariable blank() {
229         return new EVariable(new Variable("_"));
230     }
231
232     public Expression conditionalExecution(Expression condition, Expression continuation) {
233         return new EIf(condition, continuation, new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]));
234     }
235     
236     public Expression iteratedExecution(Expression list, Variable variable, Expression continuation) {
237         return new EApply(
238                 Locations.NO_LOCATION,
239                 Types.PROC,
240                 getConstant(Names.Prelude_iterList, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
241                 new Expression[] {
242                     new ESimpleLambda(Types.PROC, variable, continuation), 
243                     list
244                 }
245                 );
246     }
247
248     public Expression iteratedVectorExecution(EApply vector, Variable variable,
249             Expression continuation) {
250         return new EApply(
251                 Locations.NO_LOCATION,
252                 Types.PROC,
253                 getConstant(Names.Vector_iterVector, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
254                 new Expression[] {
255                     new ESimpleLambda(Types.PROC, variable, continuation), 
256                     vector
257                 }
258                 );
259     }
260
261     public Expression[] vars(Variable[] parameters) {
262         Expression[] result = new Expression[parameters.length];
263         for(int i=0;i<parameters.length;++i)
264             result[i] = new EVariable(parameters[i]);
265         return result;
266     }
267
268     public CompilationContext getCompilationContext() {
269         return compilationContext;
270     }
271 }