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