1 package org.simantics.scl.compiler.elaboration.contexts;
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;
32 import gnu.trove.list.array.TLongArrayList;
33 import gnu.trove.map.hash.THashMap;
35 public class SimplificationContext implements EnvironmentalContext {
36 CompilationContext compilationContext;
37 Environment environment;
40 THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
41 THashMap<Variable, Expression> inlinedVariables = new THashMap<Variable, Expression>();
43 TLongArrayList locatableStack = new TLongArrayList();
45 JavaTypeTranslator javaTypeTranslator;
46 JavaReferenceValidator<?, ?, ?, ?> validator;
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;
56 public Environment getEnvironment() {
60 public ErrorLog getErrorLog() {
64 public void pushLocation(long loc) {
65 locatableStack.add(locatable);
69 public void popLocation() {
70 locatable = locatableStack.removeAt(locatableStack.size()-1);
73 public SCLValue getValue(Name name) {
74 if(constants.containsKey(name))
75 return constants.get(name);
76 SCLValue value = environment.getValue(name);
78 errorLog.log(locatable, "Couldn't find " + name + ".");
79 constants.put(name, value);
83 public Expression getConstant(Name name, Type ... typeParameters) {
84 SCLValue value = getValue(name);
86 return new EError(locatable);
87 return new EConstant(value, typeParameters);
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);
97 mfun = Types.matchFunction(type, 1);
98 } catch (MatchException e) {
99 throw new InternalCompilerError(e);
101 type = mfun.returnType;
102 result.setType(type);
107 public Expression tuple(Expression ... cs) {
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)));
120 public Expression var(Variable var) {
121 EVariable result = new EVariable(locatable, var);
122 result.setType(var.getType());
126 public Expression simpleLambda(Variable var, Expression val) {
127 ESimpleLambda result = new ESimpleLambda(var, val);
128 result.setType(Types.function(var.getType(), val.getType()));
132 public Expression lambda(Expression pat, Expression val) {
133 return new ELambda(locatable, pat, val);
136 public Expression lambda(Case ... cases) {
137 return new ELambda(locatable, cases);
141 public Expression constant(SCLValue value) {
142 Expression result = new EConstant(loc, value);
143 result.setType(value.getType());
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));
156 public Expression if_(Expression condition, Expression then_, Expression else_) {
157 return new EIf(locatable, condition, then_, else_);
160 public Expression mapList(Expression f, Expression l) {
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);
169 public Expression guardList(Expression cond) {
170 return apply(getConstant(Names.Prelude_guardList), cond);
173 public Expression concatMap(Expression f, Expression l) {
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)}
180 } catch (MatchException e) {
181 throw new InternalCompilerError(e);
185 public Expression emptyList(Type type) {
186 return getConstant(Names.Prelude_emptyList, type);
189 public Expression singletonList(Expression e) {
190 return apply(getConstant(Names.Prelude_singletonList, e.getType()), e);
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_ });
198 public Expression match(Expression scrutinee, Case ... cases) {
199 return new EMatch(scrutinee, cases);
202 public Expression literal(Constant constant) {
203 return new ELiteral(constant);
206 @SuppressWarnings({ "unchecked" })
207 public JavaReferenceValidator<Object,Object,Object,Object> getJavaReferenceValidator() {
208 return (JavaReferenceValidator<Object,Object,Object,Object>)validator;
211 public JavaTypeTranslator getJavaTypeTranslator() {
212 return javaTypeTranslator;
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.
220 public void addInlinedVariable(Variable variable, Expression value) {
221 inlinedVariables.put(variable, value);
224 public Expression getInlinedValue(Variable variable) {
225 return inlinedVariables.get(variable);
228 public EVariable blank() {
229 return new EVariable(new Variable("_"));
232 public Expression conditionalExecution(Expression condition, Expression continuation) {
233 return new EIf(condition, continuation, new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]));
236 public Expression iteratedExecution(Expression list, Variable variable, Expression continuation) {
238 Locations.NO_LOCATION,
240 getConstant(Names.Prelude_iterList, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
242 new ESimpleLambda(Types.PROC, variable, continuation),
248 public Expression iteratedVectorExecution(EApply vector, Variable variable,
249 Expression continuation) {
251 Locations.NO_LOCATION,
253 getConstant(Names.Vector_iterVector, variable.getType(), Types.PROC, Types.tupleConstructor(0)),
255 new ESimpleLambda(Types.PROC, variable, continuation),
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]);
268 public CompilationContext getCompilationContext() {
269 return compilationContext;