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