]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java
Fixed a bug related to as-pattern in list comprehension.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EListComprehension.java
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 public class EListComprehension extends SimplifiableExpression {
14
15     public Expression head;
16     public ListQualifier qualifier;
17     
18     public EListComprehension(Expression head, ListQualifier qualifier) {
19         this.head = head;
20         this.qualifier = qualifier;
21     }
22
23     public EListComprehension(long loc, Expression head,
24             ListQualifier qualifier) {
25         super(loc);
26         this.head = head;
27         this.qualifier = qualifier;
28     }
29     
30     @Override
31     public Expression checkBasicType(TypingContext context, Type requiredType) {
32         qualifier.checkType(context);
33         Type componentType;
34         try {
35             componentType = Types.unifyApply(Types.LIST, requiredType);
36         } catch (MatchException e) {
37             context.getErrorLog().log(location, "Expected a value with type " + requiredType + " but got a list.");
38             return new EError(location);
39         }
40         head = head.checkType(context, componentType);
41         return this;
42     }
43     
44     @Override
45     protected void updateType() throws MatchException {
46         setType(Types.list(head.getType()));
47     }
48
49     @Override
50     public Expression simplify(SimplificationContext context) {
51         //System.out.println("--------");
52         context.pushLocation(location);
53         try {
54             CompiledQualifier cq = qualifier.compile(context);
55             /*
56             System.out.println("cq.pattern = " + cq.pattern);
57             System.out.println("cq.value   = " + cq.value);
58             System.out.println("head       = " + head);
59             */
60             Expression exp = context.mapList(
61                     context.lambda(cq.pattern, head), 
62                     cq.value);
63             //System.out.println("simplified = " + exp);
64             /*try {
65                 exp.validateType(context.getEnvironment());
66             } catch (TypeValidationException e) {
67                 throw new InternalCompilerError(e);
68             }*/
69             exp = exp.simplify(context);
70             return exp;
71         } finally {
72             context.popLocation();
73         }
74     }
75
76     @Override
77     public Expression resolve(TranslationContext context) {
78         context.pushFrame();
79         qualifier.resolve(context);
80         head = head.resolve(context);
81         context.popFrame();
82         return this;
83     }
84
85     @Override
86     public void setLocationDeep(long loc) {
87         if(location == Locations.NO_LOCATION) {
88             location = loc;
89             head.setLocationDeep(loc);
90             qualifier.setLocationDeep(loc);
91         }
92     }
93     
94     @Override
95     public void accept(ExpressionVisitor visitor) {
96         visitor.visit(this);
97     }
98     
99     @Override
100     public Expression accept(ExpressionTransformer transformer) {
101         return transformer.transform(this);
102     }
103
104 }