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