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.constants.Constant;
6 import org.simantics.scl.compiler.elaboration.expressions.Case;
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;
8 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
9 import org.simantics.scl.compiler.elaboration.expressions.EError;
10 import org.simantics.scl.compiler.elaboration.expressions.EIf;
11 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
12 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
13 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
14 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
15 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
16 import org.simantics.scl.compiler.elaboration.expressions.Expression;
17 import org.simantics.scl.compiler.elaboration.expressions.Variable;
18 import org.simantics.scl.compiler.elaboration.java.Builtins;
19 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
20 import org.simantics.scl.compiler.environment.Environment;
21 import org.simantics.scl.compiler.errors.ErrorLog;
22 import org.simantics.scl.compiler.errors.Locations;
23 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
24 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
25 import org.simantics.scl.compiler.types.Type;
26 import org.simantics.scl.compiler.types.Types;
27 import org.simantics.scl.compiler.types.exceptions.MatchException;
28 import org.simantics.scl.compiler.types.util.MultiFunction;
30 import gnu.trove.list.array.TLongArrayList;
31 import gnu.trove.map.hash.THashMap;
33 public class SimplificationContext implements EnvironmentalContext {
34 Environment environment;
37 public static final Name MAP_LIST = Name.create("Prelude", "mapList");
38 public static final Name GUARD_LIST = Name.create("Prelude", "guardList");
39 public static final Name CONCAT_MAP = Name.create("Prelude", "concatMap");
40 public static final Name EMPTY_LIST = Name.create("Prelude", "emptyList");
41 public static final Name SINGLETON_LIST = Name.create("Prelude", "singletonList");
42 public static final Name APPEND_LIST = Name.create("Prelude", "appendList");
43 public static final Name ADD_LIST = Name.create("Prelude", "addList");
44 public static final Name FROM_INTEGER = Name.create("Prelude", "fromInteger");
45 public static final Name FROM_DOUBLE = Name.create("Prelude", "fromDouble");
47 THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
48 THashMap<Variable, Expression> inlinedVariables = new THashMap<Variable, Expression>();
50 TLongArrayList locatableStack = new TLongArrayList();
52 JavaTypeTranslator javaTypeTranslator;
53 JavaReferenceValidator<?, ?, ?, ?> validator;
55 public SimplificationContext(Environment environment, ErrorLog errorLog,
56 JavaTypeTranslator javaTypeTranslator, JavaReferenceValidator<?, ?, ?, ?> validator) {
57 this.environment = environment;
58 this.errorLog = errorLog;
59 this.javaTypeTranslator = javaTypeTranslator;
60 this.validator = validator;
63 public Environment getEnvironment() {
67 public ErrorLog getErrorLog() {
71 public void pushLocation(long loc) {
72 locatableStack.add(locatable);
76 public void popLocation() {
77 locatable = locatableStack.removeAt(locatableStack.size()-1);
80 public SCLValue getValue(Name name) {
81 if(constants.containsKey(name))
82 return constants.get(name);
83 SCLValue value = environment.getValue(name);
85 errorLog.log(locatable, "Couldn't find " + name + ".");
86 constants.put(name, value);
90 public Expression getConstant(Name name, Type ... typeParameters) {
91 SCLValue value = getValue(name);
93 return new EError(locatable);
94 return new EConstant(value, typeParameters);
97 public Expression apply(Expression f, Expression ... ps) {
98 Expression result = f;
99 Type type = f.getType();
100 for(Expression p : ps) {
101 result = new EApply(locatable, result, p);
104 mfun = Types.matchFunction(type, 1);
105 } catch (MatchException e) {
106 throw new InternalCompilerError(e);
108 type = mfun.returnType;
109 result.setType(type);
114 public Expression tuple(Expression ... cs) {
117 Type[] typeParameters = new Type[cs.length];
118 for(int i=0;i<cs.length;++i)
119 typeParameters[i] = cs[i].getType();
120 Expression result = new EConstant(locatable, Builtins.TUPLE_CONSTRUCTORS[cs.length], typeParameters);
121 for(Expression c : cs)
122 result = new EApply(locatable, result, c);
123 result.setType(Types.tuple(Types.getTypes(cs)));
127 public Expression var(Variable var) {
128 EVariable result = new EVariable(locatable, var);
129 result.setType(var.getType());
133 public Expression simpleLambda(Variable var, Expression val) {
134 ESimpleLambda result = new ESimpleLambda(var, val);
135 result.setType(Types.function(var.getType(), val.getType()));
139 public Expression lambda(Expression pat, Expression val) {
140 return new ELambda(locatable, pat, val);
143 public Expression lambda(Case ... cases) {
144 return new ELambda(locatable, cases);
148 public Expression constant(SCLValue value) {
149 Expression result = new EConstant(loc, value);
150 result.setType(value.getType());
154 public Expression constant(SCLValue value, Type ... typeParameters) {
155 Expression result = constant(value);
156 for(Type typeParameter : typeParameters)
157 result = new EApplyType(loc, result, typeParameter);
158 result.setType(Types.instantiate(value.getType(), typeParameters));
163 public Expression if_(Expression condition, Expression then_, Expression else_) {
164 return new EIf(locatable, condition, then_, else_);
167 public Expression mapList(Expression f, Expression l) {
169 MultiFunction mfun = Types.matchFunction(f.getType(), 1);
170 return apply(getConstant(MAP_LIST, new Type[] {mfun.parameterTypes[0], mfun.returnType}), f, l);
171 } catch (MatchException e) {
172 throw new InternalCompilerError(e);
176 public Expression guardList(Expression cond) {
177 return apply(getConstant(GUARD_LIST), cond);
180 public Expression concatMap(Expression f, Expression l) {
182 MultiFunction mfun = Types.matchFunction(f.getType(), 1);
183 return apply(getConstant(CONCAT_MAP, new Type[] {
184 mfun.parameterTypes[0], mfun.effect,
185 Types.matchApply(Types.LIST, mfun.returnType)}
187 } catch (MatchException e) {
188 throw new InternalCompilerError(e);
192 public Expression emptyList(Type type) {
193 return getConstant(EMPTY_LIST, type);
196 public Expression singletonList(Expression e) {
197 return apply(getConstant(SINGLETON_LIST, e.getType()), e);
200 public Expression match(Expression scrutinee, Expression pattern, Expression value) {
201 Case case_ = new Case(pattern, value);
202 return new EMatch(scrutinee, new Case[] { case_ });
205 public Expression match(Expression scrutinee, Case ... cases) {
206 return new EMatch(scrutinee, cases);
209 public Expression literal(Constant constant) {
210 return new ELiteral(constant);
213 @SuppressWarnings({ "unchecked" })
214 public JavaReferenceValidator<Object,Object,Object,Object> getJavaReferenceValidator() {
215 return (JavaReferenceValidator<Object,Object,Object,Object>)validator;
218 public JavaTypeTranslator getJavaTypeTranslator() {
219 return javaTypeTranslator;
223 * Variable added to the context will be inlined to the
224 * given expression in subsequent simplifications. It is assumed
225 * that the value is already simplified.
227 public void addInlinedVariable(Variable variable, Expression value) {
228 inlinedVariables.put(variable, value);
231 public Expression getInlinedValue(Variable variable) {
232 return inlinedVariables.get(variable);
235 public EVariable blank() {
236 return new EVariable(new Variable("_"));
239 public Expression conditionalExecution(Expression condition, Expression continuation) {
240 return new EIf(condition, continuation, new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]));
243 public Expression iteratedExecution(Expression list, Variable variable, Expression continuation) {
245 Locations.NO_LOCATION,
247 getConstant(Name.create("Prelude", "iterList"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
249 new ESimpleLambda(Types.PROC, variable, continuation),
255 public Expression iteratedVectorExecution(EApply vector, Variable variable,
256 Expression continuation) {
258 Locations.NO_LOCATION,
260 getConstant(Name.create("Vector", "iterVector"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
262 new ESimpleLambda(Types.PROC, variable, continuation),
268 public Expression[] vars(Variable[] parameters) {
269 Expression[] result = new Expression[parameters.length];
270 for(int i=0;i<parameters.length;++i)
271 result[i] = new EVariable(parameters[i]);