]> gerrit.simantics Code Review - simantics/platform.git/blob
102d6465825a4cbee8d8bca1625598fae837c2df
[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 collectVars(TObjectIntHashMap<Variable> allVars,
36             TIntHashSet vars) {
37         head.collectVars(allVars, vars);
38         qualifier.collectVars(allVars, vars);
39     }
40     
41     @Override
42     public Expression checkBasicType(TypingContext context, Type requiredType) {
43         qualifier.checkType(context);
44         Type componentType;
45         try {
46             componentType = Types.unifyApply(Types.LIST, requiredType);
47         } catch (MatchException e) {
48             context.getErrorLog().log(location, "Expected a value with type " + requiredType + " but got a list.");
49             return new EError(location);
50         }
51         head = head.checkType(context, componentType);
52         return this;
53     }
54     
55     @Override
56     protected void updateType() throws MatchException {
57         setType(Types.list(head.getType()));
58     }
59
60     @Override
61     public void collectFreeVariables(THashSet<Variable> vars) {
62         head.collectFreeVariables(vars);
63         qualifier.collectFreeVariables(vars);
64     }
65
66     @Override
67     public Expression simplify(SimplificationContext context) {
68         context.pushLocation(location);
69         try {
70             CompiledQualifier cq = qualifier.compile(context);            
71             Expression exp = context.mapList(
72                     context.lambda(cq.pattern, head), 
73                     cq.value);
74             //System.out.println("simplified: " + exp);
75             /*try {
76                 exp.validateType(context.getEnvironment());
77             } catch (TypeValidationException e) {
78                 throw new InternalCompilerError(e);
79             }*/
80             exp = exp.simplify(context);
81             return exp;
82         } finally {
83             context.popLocation();
84         }
85     }
86
87     @Override
88     public Expression resolve(TranslationContext context) {
89         context.pushFrame();
90         qualifier.resolve(context);
91         head = head.resolve(context);
92         context.popFrame();
93         return this;
94     }
95
96     @Override
97     public void setLocationDeep(long loc) {
98         if(location == Locations.NO_LOCATION) {
99             location = loc;
100             head.setLocationDeep(loc);
101             qualifier.setLocationDeep(loc);
102         }
103     }
104     
105     @Override
106     public void accept(ExpressionVisitor visitor) {
107         visitor.visit(this);
108     }
109     
110     @Override
111     public Expression accept(ExpressionTransformer transformer) {
112         return transformer.transform(this);
113     }
114
115 }