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