]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java
c7f89ba7678e86fadec291186f7f3173d3978260
[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 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.Case;
7 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
8 import org.simantics.scl.compiler.elaboration.expressions.Expression;
9 import org.simantics.scl.compiler.elaboration.expressions.Variable;
10 import org.simantics.scl.compiler.errors.Locations;
11 import org.simantics.scl.compiler.types.TMetaVar;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.kinds.Kinds;
15
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.THashSet;
18 import gnu.trove.set.hash.TIntHashSet;
19
20 public class ListGenerator extends ListQualifier {
21     public Expression pattern;
22     public Expression value;
23     
24     public ListGenerator(Expression pattern, Expression value) {
25         this.pattern = pattern;
26         this.value = value;
27     }
28     
29     @Override
30     public void checkType(TypingContext context) {
31         TMetaVar componentType = Types.metaVar(Kinds.STAR);
32         value.checkType(context, Types.apply(Types.LIST, componentType));
33         pattern.checkTypeAsPattern(context, componentType);
34     }
35
36     @Override
37     public void collectRefs(TObjectIntHashMap<Object> allRefs,
38             TIntHashSet refs) {
39         value.collectRefs(allRefs, refs);
40     }
41
42     @Override
43     public void collectVars(TObjectIntHashMap<Variable> allVars,
44             TIntHashSet vars) {
45         value.collectVars(allVars, vars);
46     }
47
48     @Override
49     public void collectFreeVariables(THashSet<Variable> vars) {
50         value.collectFreeVariables(vars);
51         pattern.collectFreeVariables(vars);
52     }
53
54     @Override
55     public CompiledQualifier compile(SimplificationContext context) {
56         if(pattern instanceof EVariable)
57             return new CompiledQualifier(value, pattern);
58         else {
59             THashSet<Variable> variables = pattern.getFreeVariables();
60             Variable[] variableArray = variables.toArray(new Variable[variables.size()]);
61             Expression[] variableExps = new Expression[variableArray.length];
62             for(int i=0;i<variableArray.length;++i)
63                 variableExps[i] = new EVariable(variableArray[i]);
64             Expression newPattern = context.tuple(variableExps);
65             
66             EVariable blank = context.blank();
67             blank.getVariable().setType(pattern.getType());
68             
69             return new CompiledQualifier(
70                     context.concatMap(
71                             context.lambda(
72                                     new Case(pattern, context.singletonList(newPattern.copy())),
73                                     new Case(blank, context.emptyList(newPattern.getType()))
74                                     ), 
75                             value
76                             ), 
77                     newPattern);
78         }
79     }
80
81     @Override
82     public void resolve(TranslationContext context) {
83         value = value.resolve(context);
84         pattern = pattern.resolveAsPattern(context);
85     }
86     
87     @Override
88     public void collectEffects(THashSet<Type> effects) {
89         pattern.collectEffects(effects);
90         value.collectEffects(effects);
91     }
92     
93     @Override
94     public void setLocationDeep(long loc) {
95         if(location == Locations.NO_LOCATION) {
96             location = loc;
97             pattern.setLocationDeep(loc);
98             value.setLocationDeep(loc);
99         }
100     }
101     
102     @Override
103     public void accept(ListQualifierVisitor visitor) {
104         visitor.visit(this);
105     }
106     
107     @Override
108     public ListQualifier accept(ListQualifierTransformer transformer) {
109         return transformer.transform(this);
110     }
111 }