1 package org.simantics.scl.compiler.elaboration.expressions;
3 import org.simantics.scl.compiler.compilation.CompilationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
5 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
7 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
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.interpreted.IExpression;
12 import org.simantics.scl.compiler.internal.interpreted.ILet;
13 import org.simantics.scl.compiler.internal.interpreted.ISeq;
14 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.exceptions.MatchException;
18 import gnu.trove.map.hash.TObjectIntHashMap;
19 import gnu.trove.set.hash.THashSet;
20 import gnu.trove.set.hash.TIntHashSet;
22 public class ESimpleLet extends Expression {
23 Variable variable; // may be null
27 public ESimpleLet(Variable variable, Expression value, Expression in) {
29 throw new NullPointerException();
31 throw new NullPointerException();
32 this.variable = variable;
37 public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
40 throw new NullPointerException();
42 throw new NullPointerException();
43 this.variable = variable;
49 public void collectVars(TObjectIntHashMap<Variable> allVars,
51 value.collectVars(allVars, vars);
52 in.collectVars(allVars, vars);
56 protected void updateType() throws MatchException {
57 setType(in.getType());
61 public IVal toVal(CompilationContext context, CodeWriter w) {
62 IVal valueVal = value.toVal(context, w);
64 variable.setVal(valueVal);
65 return in.toVal(context, w);
69 public void collectFreeVariables(THashSet<Variable> vars) {
70 value.collectFreeVariables(vars);
71 in.collectFreeVariables(vars);
72 vars.remove(variable);
76 public Expression simplify(SimplificationContext context) {
77 value = value.simplify(context);
78 if(value instanceof EConstant || value instanceof ELiteral) {
79 context.addInlinedVariable(variable, value);
80 return in.simplify(context);
82 in = in.simplify(context);
87 public Expression resolve(TranslationContext context) {
88 value = value.resolve(context);
89 in = in.resolve(context);
94 public Expression replace(ReplaceContext context) {
96 return new ESimpleLet(location,
98 value.replace(context),
101 Variable newVariable = variable.copy();
102 context.varMap.put(variable, new EVariable(newVariable));
103 ESimpleLet result = new ESimpleLet(location, newVariable,
104 value.replace(context),
105 in.replace(context));
106 context.varMap.remove(variable);
112 public void setLocationDeep(long loc) {
113 if(location == Locations.NO_LOCATION) {
115 value.setLocationDeep(loc);
116 in.setLocationDeep(loc);
121 public IExpression toIExpression(ExpressionInterpretationContext context) {
122 if(variable == null) {
123 IExpression valueI = value.toIExpression(context);
124 IExpression inI = in.toIExpression(context);
125 return new ISeq(valueI, inI);
128 IExpression valueI = value.toIExpression(context);
129 int variableId = context.push(variable);
130 IExpression inI = in.toIExpression(context);
131 context.pop(variable);
132 return new ILet(variableId, valueI, inI);
136 private void checkBinding(TypingContext context) {
138 value = value.checkIgnoredType(context);
139 else if(variable.getType() == null) {
140 value = value.inferType(context);
141 variable.setType(value.getType());
144 value = value.checkType(context, variable.type);
146 if(variable.getType() == null)
147 variable.setType(Types.metaVar(Kinds.STAR));
148 value = value.checkType(context, variable.type);
153 public Expression inferType(TypingContext context) {
154 checkBinding(context);
155 in = in.inferType(context);
160 public Expression checkBasicType(TypingContext context, Type requiredType) {
161 checkBinding(context);
162 in = in.checkType(context, requiredType);
167 public Expression checkIgnoredType(TypingContext context) {
168 checkBinding(context);
169 in = in.checkIgnoredType(context);
174 public void collectEffects(THashSet<Type> effects) {
175 value.collectEffects(effects);
176 in.collectEffects(effects);
180 public void accept(ExpressionVisitor visitor) {
184 public Expression getValue() {
188 public Variable getVariable() {
192 public Expression getIn() {
197 public Expression accept(ExpressionTransformer transformer) {
198 return transformer.transform(this);
202 public int getSyntacticFunctionArity() {
203 return in.getSyntacticFunctionArity();