]> gerrit.simantics Code Review - simantics/platform.git/blob
860bc7f8cda677281df58b13baa01f18d8d96ebe
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
6 import org.simantics.scl.compiler.elaboration.expressions.list.CompiledQualifier;
7 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
8 import org.simantics.scl.compiler.errors.Locations;
9 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.exceptions.MatchException;
13
14 import gnu.trove.map.hash.TObjectIntHashMap;
15 import gnu.trove.set.hash.THashSet;
16 import gnu.trove.set.hash.TIntHashSet;
17
18 public class EListComprehension extends SimplifiableExpression {
19
20     public Expression head;
21     public ListQualifier qualifier;
22     
23     public EListComprehension(Expression head, ListQualifier qualifier) {
24         this.head = head;
25         this.qualifier = qualifier;
26     }
27
28     public EListComprehension(long loc, Expression head,
29             ListQualifier qualifier) {
30         super(loc);
31         this.head = head;
32         this.qualifier = qualifier;
33     }
34
35     @Override
36     public void collectRefs(TObjectIntHashMap<Object> allRefs,
37             TIntHashSet refs) {
38         head.collectRefs(allRefs, refs);
39         qualifier.collectRefs(allRefs, refs);
40     }
41
42     @Override
43     public void collectVars(TObjectIntHashMap<Variable> allVars,
44             TIntHashSet vars) {
45         head.collectVars(allVars, vars);
46         qualifier.collectVars(allVars, vars);
47     }
48     
49     @Override
50     public Expression checkBasicType(TypingContext context, Type requiredType) {
51         qualifier.checkType(context);
52         Type componentType;
53         try {
54             componentType = Types.unifyApply(Types.LIST, requiredType);
55         } catch (MatchException e) {
56             context.getErrorLog().log(location, "Expected a value with type " + requiredType + " but got a list.");
57             return new EError(location);
58         }
59         head = head.checkType(context, componentType);
60         return this;
61     }
62     
63     @Override
64     protected void updateType() throws MatchException {
65         setType(Types.list(head.getType()));
66     }
67
68     @Override
69     public void collectFreeVariables(THashSet<Variable> vars) {
70         head.collectFreeVariables(vars);
71         qualifier.collectFreeVariables(vars);
72     }
73
74     @Override
75     public Expression simplify(SimplificationContext context) {
76         context.pushLocation(location);
77         try {
78             CompiledQualifier cq = qualifier.compile(context);            
79             Expression exp = context.mapList(
80                     context.lambda(cq.pattern, head), 
81                     cq.value);
82             //System.out.println("simplified: " + exp);
83             /*try {
84                 exp.validateType(context.getEnvironment());
85             } catch (TypeValidationException e) {
86                 throw new InternalCompilerError(e);
87             }*/
88             exp = exp.simplify(context);
89             return exp;
90         } finally {
91             context.popLocation();
92         }
93     }
94
95     @Override
96     public Expression resolve(TranslationContext context) {
97         context.pushFrame();
98         qualifier.resolve(context);
99         head = head.resolve(context);
100         context.popFrame();
101         return this;
102     }
103
104     @Override
105     public Expression decorate(ExpressionDecorator decorator) {
106         head = head.decorate(decorator);
107         qualifier.decorate(decorator);
108         return decorator.decorate(this);
109     }
110
111     @Override
112     public void collectEffects(THashSet<Type> effects) {
113         head.collectEffects(effects);
114         qualifier.collectEffects(effects);
115     }
116
117     @Override
118     public void setLocationDeep(long loc) {
119         if(location == Locations.NO_LOCATION) {
120             location = loc;
121             head.setLocationDeep(loc);
122             qualifier.setLocationDeep(loc);
123         }
124     }
125     
126     @Override
127     public void accept(ExpressionVisitor visitor) {
128         visitor.visit(this);
129     }
130
131     @Override
132     public void forVariables(VariableProcedure procedure) {
133         head.forVariables(procedure);
134         qualifier.forVariables(procedure);
135     }
136     
137     @Override
138     public Expression accept(ExpressionTransformer transformer) {
139         return transformer.transform(this);
140     }
141
142 }