]> gerrit.simantics Code Review - simantics/platform.git/blob
478d7b31195cf7deb793a0d7e1a7e7114aa16725
[simantics/platform.git] /
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 setLocationDeep(long loc) {
111         if(location == Locations.NO_LOCATION) {
112             location = loc;
113             for(Expression component : components)
114                 component.setLocationDeep(loc);
115         }
116     }
117     
118     @Override
119     public void accept(ExpressionVisitor visitor) {
120         visitor.visit(this);
121     }
122     
123     @Override
124     public IExpression toIExpression(ExpressionInterpretationContext target) {
125         IExpression[] componentExpressions = new IExpression[components.length];
126         for(int i=0;i<components.length;++i)
127             componentExpressions[i] = components[i].toIExpression(target);
128         return new IListLiteral(componentExpressions);
129     }
130     
131     @Override
132     public Expression replace(ReplaceContext context) {
133         Expression[] newComponents = new Expression[components.length];
134         for(int i=0;i<components.length;++i)
135             newComponents[i] = components[i].replace(context);
136         return new EListLiteral(newComponents, componentType.replace(context.tvarMap));
137     }
138     
139     @Override
140     public boolean isPattern(int arity) {
141         if(arity != 0)
142             return false;
143         for(Expression component : components)
144             if(!component.isPattern(0))
145                 return false;
146         return true;
147     }
148     
149     @Override
150     public Expression accept(ExpressionTransformer transformer) {
151         return transformer.transform(this);
152     }
153
154 }