1 package org.simantics.scl.compiler.elaboration.expressions;
3 import java.util.ArrayList;
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.interpreted.IExpression;
15 import org.simantics.scl.compiler.internal.interpreted.IVariable;
16 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.exceptions.MatchException;
20 import org.simantics.scl.compiler.types.kinds.Kinds;
21 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
23 import gnu.trove.map.hash.TObjectIntHashMap;
24 import gnu.trove.set.hash.THashSet;
25 import gnu.trove.set.hash.TIntHashSet;
27 public class EVariable extends Expression {
28 public static final EVariable[] EMPTY_ARRAY = new EVariable[0];
30 public Variable variable;
32 public EVariable(Variable variable) {
33 this.variable = variable;
36 public EVariable(long loc, Variable variable) {
38 this.variable = variable;
41 public Variable getVariable() {
45 public void setVariable(Variable variable) {
46 this.variable = variable;
50 public void collectVars(TObjectIntHashMap<Variable> allVars,
52 int id = allVars.get(variable);
57 public void toString(StringBuilder b, TypeUnparsingContext tuc) {
58 b.append(variable == null ? "???" : variable.toString());
62 protected void updateType() throws MatchException {
63 setType(variable.getType());
67 public IVal toVal(CompilationContext context, CodeWriter w) {
68 return variable.getVal();
72 public void collectFreeVariables(THashSet<Variable> vars) {
77 public Expression simplify(SimplificationContext context) {
78 Expression expression = context.getInlinedValue(variable);
79 if(expression != null)
80 return expression.copy();
86 public Expression resolve(TranslationContext context) {
91 public void getParameters(TranslationContext translationContext,
92 ArrayList<Expression> parameters) {
96 public void removeFreeVariables(THashSet<Variable> vars) {
97 vars.remove(variable);
101 public Expression resolveAsPattern(TranslationContext context) {
106 public Expression replace(ReplaceContext context) {
107 if(context.inPattern) {
108 Type type = variable.getType().replace(context.tvarMap);
110 Variable newVariable = new Variable(variable.name);
111 newVariable.setType(type);
112 EVariable result = new EVariable(newVariable);
113 context.varMap.put(variable, result);
117 if(variable == null) {
118 EVariable newVariable = new EVariable(location, null);
119 newVariable.setType(getType().replace(context.tvarMap));
120 if(context.typingContext == null)
121 throw new InternalCompilerError(location, "Encountered unresolved variable but not in type checking phase.");
122 context.typingContext.addConstraintDemand(newVariable);
126 Expression expression = context.varMap.get(variable);
127 if(expression != null)
128 return expression.copy(context.typingContext);
130 return new EVariable(variable);
137 public IExpression toIExpression(ExpressionInterpretationContext target) {
138 return new IVariable(target.getVariableId(variable));
142 public Expression inferType(TypingContext context) {
143 if(context.isInPattern()) {
144 variable.setType(Types.metaVar(Kinds.STAR));
148 return applyPUnit(context);
152 public Expression checkBasicType(TypingContext context, Type requiredType) {
153 if(context.isInPattern()) {
154 variable.setType(requiredType);
158 return context.subsume(this, requiredType);
162 public boolean isEffectful() {
167 public void setLocationDeep(long loc) {
168 if(location == Locations.NO_LOCATION)
173 public void accept(ExpressionVisitor visitor) {
178 public boolean isPattern(int arity) {
183 public Expression accept(ExpressionTransformer transformer) {
184 return transformer.transform(this);
188 public boolean equalsExpression(Expression expression) {
189 if(expression.getClass() != getClass())
191 EVariable other = (EVariable)expression;
192 return variable == other.variable;