]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java
fccc62e9869cfc4f5469d2804588d4ed465baf41
[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 import java.util.Collections;
5 import java.util.Set;
6
7 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
8 import org.simantics.scl.compiler.compilation.CompilationContext;
9 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
10 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
11 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
12 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
13 import org.simantics.scl.compiler.errors.Locations;
14 import org.simantics.scl.compiler.internal.codegen.references.IVal;
15 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
16 import org.simantics.scl.compiler.internal.interpreted.IExpression;
17 import org.simantics.scl.compiler.internal.interpreted.IVariable;
18 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
19 import org.simantics.scl.compiler.types.Type;
20 import org.simantics.scl.compiler.types.Types;
21 import org.simantics.scl.compiler.types.exceptions.MatchException;
22 import org.simantics.scl.compiler.types.kinds.Kinds;
23 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
24
25 import gnu.trove.map.hash.TObjectIntHashMap;
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     public 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     @Override
51     public void collectVars(TObjectIntHashMap<Variable> allVars,
52             TIntHashSet vars) {
53         int id = allVars.get(variable);
54         if(id >= 0)
55             vars.add(id);
56     }
57     
58     @Override
59     public Set<Variable> getFreeVariables() {
60         if(variable == null)
61             return Collections.emptySet();
62         else
63             return Collections.singleton(variable);
64     }
65
66     public void toString(StringBuilder b, TypeUnparsingContext tuc) {
67         b.append(variable == null ? "???" : variable.toString());
68     }
69
70     @Override
71     protected void updateType() throws MatchException {
72         setType(variable.getType());
73     }
74
75     @Override
76     public IVal toVal(CompilationContext context, CodeWriter w) {
77         return variable.getVal();
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 Expression resolveAsPattern(TranslationContext context) {
101         return this;
102     }
103
104     @Override
105     public Expression replace(ReplaceContext context) {
106         if(context.inPattern) {
107             Type type = variable.getType().replace(context.tvarMap);
108             
109             Variable newVariable = new Variable(variable.name);
110             newVariable.setType(type);
111             EVariable result = new EVariable(newVariable);
112             context.varMap.put(variable, result);
113             return result;
114         }
115         else {
116             if(variable == null) {
117                 EVariable newVariable = new EVariable(location, null);
118                 newVariable.setType(getType().replace(context.tvarMap));
119                 if(context.typingContext == null)
120                     throw new InternalCompilerError(location, "Encountered unresolved variable but not in type checking phase.");
121                 context.typingContext.addConstraintDemand(newVariable);
122                 return newVariable;
123             }
124             else {
125                 Expression expression = context.varMap.get(variable);
126                 if(expression != null)
127                     return expression.copy(context.typingContext);
128                 else {
129                     return new EVariable(variable);
130                 }
131             }
132         }
133     }
134     
135     @Override
136     public IExpression toIExpression(ExpressionInterpretationContext target) {
137         return new IVariable(target.getVariableId(variable));
138     }
139     
140     @Override
141     public Expression inferType(TypingContext context) {
142         if(context.isInPattern()) {
143             variable.setType(Types.metaVar(Kinds.STAR));
144             return this;
145         }
146         else
147             return applyPUnit(context);
148     }
149     
150     @Override
151     public Expression checkBasicType(TypingContext context, Type requiredType) {
152         if(context.isInPattern()) {
153             variable.setType(requiredType);
154             return this;
155         }
156         else
157             return context.subsume(this, requiredType);
158     }
159     
160     @Override
161     public boolean isEffectful() {
162         return false;
163     }
164     
165     @Override
166     public void setLocationDeep(long loc) {
167         if(location == Locations.NO_LOCATION)
168             location = loc;
169     }
170     
171     @Override
172     public void accept(ExpressionVisitor visitor) {
173         visitor.visit(this);
174     }
175     
176     @Override
177     public boolean isPattern(int arity) {
178         return arity == 0;
179     }
180     
181     @Override
182     public Expression accept(ExpressionTransformer transformer) {
183         return transformer.transform(this);
184     }
185     
186     @Override
187     public boolean equalsExpression(Expression expression) {
188         if(expression.getClass() != getClass())
189             return false;
190         EVariable other = (EVariable)expression;
191         return variable == other.variable;
192     }
193
194 }