1 package org.simantics.scl.compiler.elaboration.expressions;
3 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
4 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
7 import org.simantics.scl.compiler.environment.Environment;
8 import org.simantics.scl.compiler.errors.Locations;
9 import org.simantics.scl.compiler.internal.codegen.references.IVal;
10 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
11 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
12 import org.simantics.scl.compiler.internal.interpreted.IExpression;
13 import org.simantics.scl.compiler.internal.interpreted.ILet;
14 import org.simantics.scl.compiler.internal.interpreted.ISeq;
15 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
16 import org.simantics.scl.compiler.types.Type;
17 import org.simantics.scl.compiler.types.exceptions.MatchException;
19 import gnu.trove.map.hash.TObjectIntHashMap;
20 import gnu.trove.set.hash.THashSet;
21 import gnu.trove.set.hash.TIntHashSet;
23 public class ESimpleLet extends Expression {
24 Variable variable; // may be null
28 public ESimpleLet(Variable variable, Expression value, Expression in) {
30 throw new NullPointerException();
32 throw new NullPointerException();
33 this.variable = variable;
38 public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
41 throw new NullPointerException();
43 throw new NullPointerException();
44 this.variable = variable;
49 public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
50 value.collectRefs(allRefs, refs);
51 in.collectRefs(allRefs, refs);
55 public void collectVars(TObjectIntHashMap<Variable> allVars,
57 value.collectVars(allVars, vars);
58 in.collectVars(allVars, vars);
62 protected void updateType() throws MatchException {
63 setType(in.getType());
67 public IVal toVal(Environment env, CodeWriter w) {
68 IVal valueVal = value.toVal(env, w);
70 variable.setVal(valueVal);
71 return in.toVal(env, w);
75 public void collectFreeVariables(THashSet<Variable> vars) {
76 value.collectFreeVariables(vars);
77 in.collectFreeVariables(vars);
78 vars.remove(variable);
82 public Expression simplify(SimplificationContext context) {
83 value = value.simplify(context);
84 if(value instanceof EConstant || value instanceof ELiteral) {
85 context.addInlinedVariable(variable, value);
86 return in.simplify(context);
88 in = in.simplify(context);
93 public Expression resolve(TranslationContext context) {
94 value = value.resolve(context);
95 in = in.resolve(context);
100 public Expression replace(ReplaceContext context) {
102 return new ESimpleLet(location,
104 value.replace(context),
105 in.replace(context));
107 Variable newVariable = variable.copy();
108 context.varMap.put(variable, new EVariable(newVariable));
109 ESimpleLet result = new ESimpleLet(location, newVariable,
110 value.replace(context),
111 in.replace(context));
112 context.varMap.remove(variable);
118 public void setLocationDeep(long loc) {
119 if(location == Locations.NO_LOCATION) {
121 value.setLocationDeep(loc);
122 in.setLocationDeep(loc);
127 public IExpression toIExpression(ExpressionInterpretationContext context) {
128 if(variable == null) {
129 IExpression valueI = value.toIExpression(context);
130 IExpression inI = in.toIExpression(context);
131 return new ISeq(valueI, inI);
134 IExpression valueI = value.toIExpression(context);
135 int variableId = context.push(variable);
136 IExpression inI = in.toIExpression(context);
137 context.pop(variable);
138 return new ILet(variableId, valueI, inI);
142 private void checkBinding(TypingContext context) {
144 value = value.checkIgnoredType(context);
145 else if(variable.getType() == null) {
146 value = value.inferType(context);
147 variable.setType(value.getType());
150 value = value.checkType(context, variable.type);
152 if(variable.getType() == null)
153 variable.setType(Types.metaVar(Kinds.STAR));
154 value = value.checkType(context, variable.type);
159 public Expression inferType(TypingContext context) {
160 checkBinding(context);
161 in = in.inferType(context);
166 public Expression checkBasicType(TypingContext context, Type requiredType) {
167 checkBinding(context);
168 in = in.checkType(context, requiredType);
173 public Expression checkIgnoredType(TypingContext context) {
174 checkBinding(context);
175 in = in.checkIgnoredType(context);
180 public Expression decorate(ExpressionDecorator decorator) {
181 value = value.decorate(decorator);
182 in = in.decorate(decorator);
183 return decorator.decorate(this);
187 public void collectEffects(THashSet<Type> effects) {
188 value.collectEffects(effects);
189 in.collectEffects(effects);
193 public void accept(ExpressionVisitor visitor) {
197 public Expression getValue() {
201 public Variable getVariable() {
205 public Expression getIn() {
210 public void forVariables(VariableProcedure procedure) {
211 value.forVariables(procedure);
212 in.forVariables(procedure);
216 public Expression accept(ExpressionTransformer transformer) {
217 return transformer.transform(this);
221 public int getSyntacticFunctionArity() {
222 return in.getSyntacticFunctionArity();