]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java
(refs #7614) Assign type-checked expression back to list comprehension
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / list / ListGenerator.java
1 package org.simantics.scl.compiler.elaboration.expressions.list;
2
3 import java.util.Set;
4
5 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
7 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
8 import org.simantics.scl.compiler.elaboration.expressions.Case;
9 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;
12 import org.simantics.scl.compiler.errors.Locations;
13 import org.simantics.scl.compiler.types.TMetaVar;
14 import org.simantics.scl.compiler.types.Types;
15 import org.simantics.scl.compiler.types.kinds.Kinds;
16
17 public class ListGenerator extends ListQualifier {
18     public Expression pattern;
19     public Expression value;
20     
21     public ListGenerator(Expression pattern, Expression value) {
22         this.pattern = pattern;
23         this.value = value;
24     }
25     
26     @Override
27     public void checkType(TypingContext context) {
28         TMetaVar componentType = Types.metaVar(Kinds.STAR);
29         value = value.checkType(context, Types.apply(Types.LIST, componentType));
30         pattern = pattern.checkTypeAsPattern(context, componentType);
31     }
32
33     @Override
34     public CompiledQualifier compile(SimplificationContext context) {
35         if(pattern instanceof EVariable)
36             return new CompiledQualifier(value, pattern);
37         else {
38             Set<Variable> variables = pattern.getFreeVariables();
39             Variable[] variableArray = variables.toArray(new Variable[variables.size()]);
40             Expression[] variableExps = new Expression[variableArray.length];
41             for(int i=0;i<variableArray.length;++i)
42                 variableExps[i] = new EVariable(variableArray[i]);
43             Expression newPattern = context.tuple(variableExps);
44             
45             EVariable blank = context.blank();
46             blank.getVariable().setType(pattern.getType());
47             
48             return new CompiledQualifier(
49                     context.concatMap(
50                             context.lambda(
51                                     new Case(pattern, context.singletonList(newPattern.copy())),
52                                     new Case(blank, context.emptyList(newPattern.getType()))
53                                     ), 
54                             value
55                             ), 
56                     newPattern);
57         }
58     }
59
60     @Override
61     public void resolve(TranslationContext context) {
62         value = value.resolve(context);
63         pattern = pattern.resolveAsPattern(context);
64     }
65
66     @Override
67     public void setLocationDeep(long loc) {
68         if(location == Locations.NO_LOCATION) {
69             location = loc;
70             pattern.setLocationDeep(loc);
71             value.setLocationDeep(loc);
72         }
73     }
74     
75     @Override
76     public void accept(ListQualifierVisitor visitor) {
77         visitor.visit(this);
78     }
79     
80     @Override
81     public ListQualifier accept(ListQualifierTransformer transformer) {
82         return transformer.transform(this);
83     }
84 }