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