]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java
(refs #7278, refs #7279) Small fixes to InternalCompilerExceptions
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EVariable.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
8 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
9 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
10 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
11 import org.simantics.scl.compiler.errors.Locations;
12 import org.simantics.scl.compiler.internal.codegen.references.IVal;
13 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
14 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
15 import org.simantics.scl.compiler.internal.interpreted.IExpression;
16 import org.simantics.scl.compiler.internal.interpreted.IVariable;
17 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
18 import org.simantics.scl.compiler.types.Type;
19 import org.simantics.scl.compiler.types.Types;
20 import org.simantics.scl.compiler.types.exceptions.MatchException;
21 import org.simantics.scl.compiler.types.kinds.Kinds;
22 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
23
24 import gnu.trove.map.hash.TObjectIntHashMap;
25 import gnu.trove.set.hash.THashSet;
26 import gnu.trove.set.hash.TIntHashSet;
27
28 public class EVariable extends Expression {
29     public static final EVariable[] EMPTY_ARRAY = new EVariable[0];
30     
31     Variable variable;
32     
33     public EVariable(Variable variable) {
34         this.variable = variable;
35     }
36
37     public EVariable(long loc, Variable variable) {
38         super(loc);
39         this.variable = variable;
40     }
41
42     public Variable getVariable() {
43         return variable;
44     }
45     
46     public void setVariable(Variable variable) {
47         this.variable = variable;
48     }
49
50         public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
51     }
52         
53         @Override
54         public void collectVars(TObjectIntHashMap<Variable> allVars,
55                 TIntHashSet vars) {
56             int id = allVars.get(variable);
57             if(id >= 0)
58                 vars.add(id);
59         }
60
61         public void toString(StringBuilder b, TypeUnparsingContext tuc) {
62         b.append(variable == null ? "???" : variable.toString());
63     }
64
65         @Override
66         protected void updateType() throws MatchException {
67             setType(variable.getType());
68         }
69         
70         @Override
71         public IVal toVal(CompilationContext context, CodeWriter w) {
72         return variable.getVal();
73     }
74
75     @Override
76     public void collectFreeVariables(THashSet<Variable> vars) {
77         vars.add(variable);
78     }
79
80     @Override
81     public Expression simplify(SimplificationContext context) {
82         Expression expression = context.getInlinedValue(variable);
83         if(expression != null)
84             return expression.copy();
85         else
86             return this;
87     }
88
89     @Override
90     public Expression resolve(TranslationContext context) {
91         return this;
92     }
93     
94     @Override
95     public void getParameters(TranslationContext translationContext,
96             ArrayList<Expression> parameters) {
97     }
98     
99     @Override
100     public void removeFreeVariables(THashSet<Variable> vars) {
101         vars.remove(variable);
102     }
103     
104     @Override
105     public Expression resolveAsPattern(TranslationContext context) {
106         return this;
107     }
108
109     @Override
110     public Expression replace(ReplaceContext context) {
111         if(context.inPattern) {
112             Type type = variable.getType().replace(context.tvarMap);
113             
114             Variable newVariable = new Variable(variable.name);
115             newVariable.setType(type);
116             EVariable result = new EVariable(newVariable);
117             context.varMap.put(variable, result);
118             return result;
119         }
120         else {
121             if(variable == null) {
122                 EVariable newVariable = new EVariable(location, null);
123                 newVariable.setType(getType().replace(context.tvarMap));
124                 if(context.typingContext == null)
125                     throw new InternalCompilerError(location, "Encountered unresolved variable but not in type checking phase.");
126                 context.typingContext.addConstraintDemand(newVariable);
127                 return newVariable;
128             }
129             else {
130                 Expression expression = context.varMap.get(variable);
131                 if(expression != null)
132                     return expression.copy(context.typingContext);
133                 else {
134                     return new EVariable(variable);
135                 }
136             }
137         }
138     }
139     
140     @Override
141     public IExpression toIExpression(ExpressionInterpretationContext target) {
142         return new IVariable(target.getVariableId(variable));
143     }
144     
145     @Override
146     public Expression inferType(TypingContext context) {
147         if(context.isInPattern()) {
148             variable.setType(Types.metaVar(Kinds.STAR));
149             return this;
150         }
151         else
152             return applyPUnit(context);
153     }
154     
155     @Override
156     public Expression checkBasicType(TypingContext context, Type requiredType) {
157         if(context.isInPattern()) {
158             variable.setType(requiredType);
159             return this;
160         }
161         else
162             return context.subsume(this, requiredType);
163     }
164     
165     @Override
166     public Expression decorate(ExpressionDecorator decorator) {     
167         return decorator.decorate(this);
168     }
169     
170     @Override
171     public boolean isEffectful() {
172         return false;
173     }
174     
175     @Override
176     public void collectEffects(THashSet<Type> effects) {
177     }
178     
179     @Override
180     public void setLocationDeep(long loc) {
181         if(location == Locations.NO_LOCATION)
182             location = loc;
183     }
184     
185     @Override
186     public void accept(ExpressionVisitor visitor) {
187         visitor.visit(this);
188     }
189
190     @Override
191     public void forVariables(VariableProcedure procedure) {
192         if(variable != null)
193             procedure.execute(location, variable);
194     }
195     
196     @Override
197     public boolean isPattern(int arity) {
198         return arity == 0;
199     }
200     
201     @Override
202     public Expression accept(ExpressionTransformer transformer) {
203         return transformer.transform(this);
204     }
205     
206     @Override
207     public boolean equalsExpression(Expression expression) {
208         if(expression.getClass() != getClass())
209             return false;
210         EVariable other = (EVariable)expression;
211         return variable == other.variable;
212     }
213
214 }