]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java
Improvements to resolving primitive properties in document server
[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 public class EVariable extends Expression {
26     public static final EVariable[] EMPTY_ARRAY = new EVariable[0];
27     
28     public Variable variable;
29     
30     public EVariable(Variable variable) {
31         this.variable = variable;
32     }
33
34     public EVariable(long loc, Variable variable) {
35         super(loc);
36         this.variable = variable;
37     }
38
39     public Variable getVariable() {
40         return variable;
41     }
42     
43     public void setVariable(Variable variable) {
44         this.variable = variable;
45     }
46
47     @Override
48     public Set<Variable> getFreeVariables() {
49         if(variable == null)
50             return Collections.emptySet();
51         else
52             return Collections.singleton(variable);
53     }
54
55     public void toString(StringBuilder b, TypeUnparsingContext tuc) {
56         b.append(variable == null ? "???" : variable.toString());
57     }
58
59     @Override
60     protected void updateType() throws MatchException {
61         setType(variable.getType());
62     }
63
64     @Override
65     public IVal toVal(CompilationContext context, CodeWriter w) {
66         return variable.getVal();
67     }
68
69     @Override
70     public Expression simplify(SimplificationContext context) {
71         Expression expression = context.getInlinedValue(variable);
72         if(expression != null)
73             return expression.copy();
74         else
75             return this;
76     }
77
78     @Override
79     public Expression resolve(TranslationContext context) {
80         return this;
81     }
82     
83     @Override
84     public void getParameters(TranslationContext translationContext,
85             ArrayList<Expression> parameters) {
86     }
87     
88     @Override
89     public Expression resolveAsPattern(TranslationContext context) {
90         return this;
91     }
92
93     @Override
94     public Expression replace(ReplaceContext context) {
95         if(context.inPattern) {
96             Type type = variable.getType().replace(context.tvarMap);
97             
98             Variable newVariable = new Variable(variable.name);
99             newVariable.setType(type);
100             EVariable result = new EVariable(newVariable);
101             context.varMap.put(variable, result);
102             return result;
103         }
104         else {
105             if(variable == null) {
106                 EVariable newVariable = new EVariable(location, null);
107                 newVariable.setType(getType().replace(context.tvarMap));
108                 if(context.typingContext == null)
109                     throw new InternalCompilerError(location, "Encountered unresolved variable but not in type checking phase.");
110                 context.typingContext.addConstraintDemand(newVariable);
111                 return newVariable;
112             }
113             else {
114                 Expression expression = context.varMap.get(variable);
115                 if(expression != null)
116                     return expression.copy(context.typingContext);
117                 else {
118                     return new EVariable(variable);
119                 }
120             }
121         }
122     }
123     
124     @Override
125     public IExpression toIExpression(ExpressionInterpretationContext target) {
126         return new IVariable(target.getVariableId(variable));
127     }
128     
129     @Override
130     public Expression inferType(TypingContext context) {
131         if(context.isInPattern()) {
132             variable.setType(Types.metaVar(Kinds.STAR));
133             return this;
134         }
135         else
136             return applyPUnit(context);
137     }
138     
139     @Override
140     public Expression checkBasicType(TypingContext context, Type requiredType) {
141         if(context.isInPattern()) {
142             variable.setType(requiredType);
143             return this;
144         }
145         else
146             return context.subsume(this, requiredType);
147     }
148     
149     @Override
150     public boolean isEffectful() {
151         return false;
152     }
153     
154     @Override
155     public void setLocationDeep(long loc) {
156         if(location == Locations.NO_LOCATION)
157             location = loc;
158     }
159     
160     @Override
161     public void accept(ExpressionVisitor visitor) {
162         visitor.visit(this);
163     }
164     
165     @Override
166     public boolean isPattern(int arity) {
167         return arity == 0;
168     }
169     
170     @Override
171     public Expression accept(ExpressionTransformer transformer) {
172         return transformer.transform(this);
173     }
174     
175     @Override
176     public boolean equalsExpression(Expression expression) {
177         if(expression.getClass() != getClass())
178             return false;
179         EVariable other = (EVariable)expression;
180         return variable == other.variable;
181     }
182
183 }