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