]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java
(refs #7498) Bugfixing implementation of skeleton refs
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / ESimpleLet.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
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;
17
18 public class ESimpleLet extends Expression {
19     public Variable variable; // may be null
20     public Expression value;
21     public Expression in;
22     
23     public ESimpleLet(Variable variable, Expression value, Expression in) {
24         if(value == null)
25             throw new NullPointerException();
26         if(in == null)
27             throw new NullPointerException();
28         this.variable = variable;
29         this.value = value;
30         this.in = in;
31     }
32
33     public ESimpleLet(long loc, Variable variable, Expression value, Expression in) {
34         super(loc);
35         if(value == null)
36             throw new NullPointerException();
37         if(in == null)
38             throw new NullPointerException();
39         this.variable = variable;
40         this.value = value;
41         this.in = in;
42     }
43
44     @Override
45     protected void updateType() throws MatchException {
46         setType(in.getType());
47     }
48
49     @Override
50     public IVal toVal(CompilationContext context, CodeWriter w) {
51         IVal valueVal = value.toVal(context, w);
52         if(variable != null)
53             variable.setVal(valueVal);
54         return in.toVal(context, w);
55     }
56
57     @Override
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);
63         }
64         in = in.simplify(context);
65         return this;
66     }
67
68     @Override
69     public Expression resolve(TranslationContext context) {
70         value = value.resolve(context);
71         in = in.resolve(context);
72         return this;
73     }
74
75     @Override
76     public Expression replace(ReplaceContext context) {
77         if(variable == null)
78             return new ESimpleLet(location,
79                     null, 
80                     value.replace(context), 
81                     in.replace(context));
82         else {
83             Variable newVariable = variable.copy();
84             context.varMap.put(variable, new EVariable(newVariable));
85             ESimpleLet result = new ESimpleLet(location, newVariable, 
86                     value.replace(context), 
87                     in.replace(context));
88             context.varMap.remove(variable);
89             return result;
90         }
91     }
92     
93     @Override
94     public void setLocationDeep(long loc) {
95         if(location == Locations.NO_LOCATION) {
96             location = loc;
97             value.setLocationDeep(loc);
98             in.setLocationDeep(loc);
99         }
100     }
101
102     @Override
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);
108         }
109         else {
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);
115         }
116     }
117
118     private void checkBinding(TypingContext context) {
119         if(variable == null)
120             value = value.checkIgnoredType(context);
121         else if(variable.getType() == null) {
122             value = value.inferType(context);
123             variable.setType(value.getType());
124         }
125         else
126             value = value.checkType(context, variable.type);
127         /*else {
128             if(variable.getType() == null)
129                 variable.setType(Types.metaVar(Kinds.STAR));
130             value = value.checkType(context, variable.type);
131         }*/
132     }
133     
134     @Override
135     public Expression inferType(TypingContext context) {
136         checkBinding(context);
137         in = in.inferType(context);
138         return this;
139     }
140     
141     @Override
142     public Expression checkBasicType(TypingContext context, Type requiredType) {
143         checkBinding(context);
144         in = in.checkType(context, requiredType);
145         return this;
146     }
147     
148     @Override
149     public Expression checkIgnoredType(TypingContext context) {
150         checkBinding(context);
151         in = in.checkIgnoredType(context);
152         return this;
153     }
154     
155     @Override
156     public void accept(ExpressionVisitor visitor) {
157         visitor.visit(this);
158     }
159     
160     public Expression getValue() {
161         return value;
162     }
163     
164     public Variable getVariable() {
165         return variable;
166     }
167     
168     public Expression getIn() {
169         return in;
170     }
171
172     @Override
173     public Expression accept(ExpressionTransformer transformer) {
174         return transformer.transform(this);
175     }
176
177     @Override
178     public int getSyntacticFunctionArity() {
179         return in.getSyntacticFunctionArity();
180     }
181 }