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 public class ESimpleLet extends Expression {
19 public Variable variable; // may be null
20 public Expression value;
23 public ESimpleLet(Variable variable, Expression value, Expression in) {
25 throw new NullPointerException();
27 throw new NullPointerException();
28 this.variable = variable;
33 public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
36 throw new NullPointerException();
38 throw new NullPointerException();
39 this.variable = variable;
45 protected void updateType() throws MatchException {
46 setType(in.getType());
50 public IVal toVal(CompilationContext context, CodeWriter w) {
51 IVal valueVal = value.toVal(context, w);
53 variable.setVal(valueVal);
54 return in.toVal(context, w);
58 public Expression simplify(SimplificationContext context) {
59 value = value.simplify(context);
60 if(value instanceof EConstant || value instanceof ELiteral) {
61 context.addInlinedVariable(variable, value);
62 return in.simplify(context);
64 in = in.simplify(context);
69 public Expression resolve(TranslationContext context) {
70 value = value.resolve(context);
71 in = in.resolve(context);
76 public Expression replace(ReplaceContext context) {
78 return new ESimpleLet(location,
80 value.replace(context),
83 Variable newVariable = variable.copy();
84 context.varMap.put(variable, new EVariable(newVariable));
85 ESimpleLet result = new ESimpleLet(location, newVariable,
86 value.replace(context),
88 context.varMap.remove(variable);
94 public void setLocationDeep(long loc) {
95 if(location == Locations.NO_LOCATION) {
97 value.setLocationDeep(loc);
98 in.setLocationDeep(loc);
103 public IExpression toIExpression(ExpressionInterpretationContext context) {
104 if(variable == null) {
105 IExpression valueI = value.toIExpression(context);
106 IExpression inI = in.toIExpression(context);
107 return new ISeq(valueI, inI);
110 IExpression valueI = value.toIExpression(context);
111 int variableId = context.push(variable);
112 IExpression inI = in.toIExpression(context);
113 context.pop(variable);
114 return new ILet(variableId, valueI, inI);
118 private void checkBinding(TypingContext context) {
120 value = value.checkIgnoredType(context);
121 else if(variable.getType() == null) {
122 value = value.inferType(context);
123 variable.setType(value.getType());
126 value = value.checkType(context, variable.type);
128 if(variable.getType() == null)
129 variable.setType(Types.metaVar(Kinds.STAR));
130 value = value.checkType(context, variable.type);
135 public Expression inferType(TypingContext context) {
136 checkBinding(context);
137 in = in.inferType(context);
142 public Expression checkBasicType(TypingContext context, Type requiredType) {
143 checkBinding(context);
144 in = in.checkType(context, requiredType);
149 public Expression checkIgnoredType(TypingContext context) {
150 checkBinding(context);
151 in = in.checkIgnoredType(context);
156 public void accept(ExpressionVisitor visitor) {
160 public Expression getValue() {
164 public Variable getVariable() {
168 public Expression getIn() {
173 public Expression accept(ExpressionTransformer transformer) {
174 return transformer.transform(this);
178 public int getSyntacticFunctionArity() {
179 return in.getSyntacticFunctionArity();