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