]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java
b1075a949af456d30caf21c2e95610d9f6456729
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EListLiteral.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
4 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
7 import org.simantics.scl.compiler.elaboration.java.Builtins;
8 import org.simantics.scl.compiler.elaboration.java.ListConstructor;
9 import org.simantics.scl.compiler.errors.Locations;
10 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
11 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
12 import org.simantics.scl.compiler.internal.interpreted.IExpression;
13 import org.simantics.scl.compiler.internal.interpreted.IListLiteral;
14 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.Types;
17 import org.simantics.scl.compiler.types.exceptions.MatchException;
18
19 import gnu.trove.map.hash.TObjectIntHashMap;
20 import gnu.trove.set.hash.THashSet;
21 import gnu.trove.set.hash.TIntHashSet;
22
23 public class EListLiteral extends SimplifiableExpression {
24
25     Expression[] components;
26     Type componentType;
27
28     public EListLiteral(Expression[] components) {
29         this.components = components;
30     }
31
32     private EListLiteral(Expression[] components, Type componentType) {
33         this.components = components;
34         this.componentType = componentType;
35     }
36
37     public Expression[] getComponents() {
38         return components;
39     }
40     
41     @Override
42     public void collectRefs(TObjectIntHashMap<Object> allRefs,
43             TIntHashSet refs) {
44         for(Expression component : components)
45             component.collectRefs(allRefs, refs);
46     }
47
48     @Override
49     public void collectVars(TObjectIntHashMap<Variable> allVars,
50             TIntHashSet vars) {
51         for(Expression component : components)
52             component.collectVars(allVars, vars);
53     }
54     
55     @Override
56     public void collectFreeVariables(THashSet<Variable> vars) {
57         for(Expression component : components)
58             component.collectFreeVariables(vars);
59     }
60     
61     @Override
62     public Expression simplify(SimplificationContext context) {
63         context.pushLocation(location);
64         try {
65             for(int i=0;i<components.length;++i)
66                 components[i] = components[i].simplify(context);
67             
68             if(components.length <= Constants.MAX_LIST_LITERAL_LENGTH) {
69                 Expression result = new EConstant(location, Builtins.LIST_CONSTRUCTORS[components.length], 
70                         componentType);
71                 if(components.length > 0)
72                     result = new EApply(location, result, components);
73                 return result;
74             }
75             else {
76                 Expression result = new EApplyType(new ELiteral(location, new ListConstructor(components.length)), componentType);
77                 result = new EApply(location, result, components);
78                 return result;
79             }
80         } finally {
81             context.popLocation();
82         }
83     }
84
85     @Override
86     public Expression resolve(TranslationContext context) {
87         for(int i=0;i<components.length;++i)
88             components[i] = components[i].resolve(context);
89         return this;
90     }
91     
92     @Override
93     public Expression resolveAsPattern(TranslationContext context) {
94         for(int i=0;i<components.length;++i)
95             components[i] = components[i].resolveAsPattern(context);
96         return this;
97     }
98     
99     @Override
100     protected void updateType() throws MatchException {
101         setType(Types.list(componentType));
102     }
103     
104     @Override
105     public Expression checkBasicType(TypingContext context, Type requiredType) {
106         try {
107             componentType = Types.unifyApply(Types.LIST, requiredType);
108         } catch (MatchException e) {
109             context.getErrorLog().log(location, "Expected a value with type " + requiredType + " but got a list.");
110             return new EError(location);
111         }
112         for(int i=0;i<components.length;++i)
113             components[i] = components[i].checkType(context, componentType);
114         return this;
115     }
116
117     @Override
118     public Expression decorate(ExpressionDecorator decorator) {
119         for(int i=0;i<components.length;++i)
120             components[i] = components[i].decorate(decorator);
121         return decorator.decorate(this);
122     }
123
124     @Override
125     public void collectEffects(THashSet<Type> effects) {
126         for(Expression component : components)
127             component.collectEffects(effects);
128     }
129
130     @Override
131     public void setLocationDeep(long loc) {
132         if(location == Locations.NO_LOCATION) {
133             location = loc;
134             for(Expression component : components)
135                 component.setLocationDeep(loc);
136         }
137     }
138     
139     @Override
140     public void accept(ExpressionVisitor visitor) {
141         visitor.visit(this);
142     }
143     
144     @Override
145     public IExpression toIExpression(ExpressionInterpretationContext target) {
146         IExpression[] componentExpressions = new IExpression[components.length];
147         for(int i=0;i<components.length;++i)
148             componentExpressions[i] = components[i].toIExpression(target);
149         return new IListLiteral(componentExpressions);
150     }
151
152     @Override
153     public void forVariables(VariableProcedure procedure) {
154         for(Expression component : components)
155             component.forVariables(procedure);
156     }
157     
158     @Override
159     public Expression replace(ReplaceContext context) {
160         Expression[] newComponents = new Expression[components.length];
161         for(int i=0;i<components.length;++i)
162             newComponents[i] = components[i].replace(context);
163         return new EListLiteral(newComponents, componentType.replace(context.tvarMap));
164     }
165     
166     @Override
167     public boolean isPattern(int arity) {
168         if(arity != 0)
169             return false;
170         for(Expression component : components)
171             if(!component.isPattern(0))
172                 return false;
173         return true;
174     }
175     
176     @Override
177     public Expression accept(ExpressionTransformer transformer) {
178         return transformer.transform(this);
179     }
180
181 }