]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java
65b3f9b2f74b4e971808d6fe93c6384dfa437f7e
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / ETransformation.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6
7 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
8 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
9 import org.simantics.scl.compiler.elaboration.query.Query;
10 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
11 import org.simantics.scl.compiler.errors.Locations;
12 import org.simantics.scl.compiler.internal.elaboration.transformations.TransformationBuilder;
13 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
14 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.Types;
17 import org.simantics.scl.compiler.types.exceptions.MatchException;
18
19 import gnu.trove.map.hash.TObjectIntHashMap;
20 import gnu.trove.set.hash.THashSet;
21 import gnu.trove.set.hash.TIntHashSet;
22
23 public class ETransformation extends SimplifiableExpression {
24     public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object();
25     
26     public final String name;
27     public Query seed;
28     
29     public ETransformation(String name, Query seed) {
30         this.name = name;
31         this.seed = seed;
32     }
33
34     @Override
35     public void collectRefs(TObjectIntHashMap<Object> allRefs,
36             TIntHashSet refs) {
37         {
38             int ref = allRefs.get(TRANSFORMATION_RULES_TYPECHECKED);
39             if(ref >= 0)
40                 refs.add(ref);
41         }
42         seed.collectRefs(allRefs, refs);
43     }
44
45     @Override
46     public void collectVars(TObjectIntHashMap<Variable> allVars,
47             TIntHashSet vars) {
48         seed.collectVars(allVars, vars);
49     }
50
51     @Override
52     protected void updateType() throws MatchException {
53         setType(Types.UNIT);
54     }
55
56     @Override
57     public void collectFreeVariables(THashSet<Variable> vars) {
58         seed.collectFreeVariables(vars);
59     }
60     
61     @Override
62     public Expression inferType(TypingContext context) {
63         context.declareEffect(location, Types.PROC);
64         seed.checkType(context);
65         return compile(context);
66     }
67
68     private Expression compile(TypingContext context) {
69         ArrayList<TransformationRule> rules = new ArrayList<TransformationRule>(); 
70         context.getEnvironment().collectRules(rules);
71         Collections.sort(rules, new Comparator<TransformationRule>() {
72             @Override
73             public int compare(TransformationRule o1, TransformationRule o2) {
74                 return Integer.compare(Locations.beginOf(o1.location), Locations.beginOf(o2.location));
75             }
76         });
77        
78         // Translation
79         TransformationBuilder tb = new TransformationBuilder(context.getErrorLog(), context);
80         tb.handleSeed(seed);
81         for(TransformationRule rule : rules)
82             if(!rule.isAbstract)
83                 tb.handleRule(rule);
84         Expression expression = tb.compileRules();
85         
86         if(SCLCompilerConfiguration.SHOW_COMPILED_RULES)
87             System.out.println(expression);
88         return expression;
89     }
90
91     @Override
92     public Expression resolve(TranslationContext context) {
93         seed = seed.resolve(context);
94         return this;
95     }
96
97     @Override
98     public void setLocationDeep(long loc) {
99         if(location == Locations.NO_LOCATION) {
100             location = loc;
101             seed.setLocationDeep(loc);
102         }
103     }
104
105     @Override
106     public Expression decorate(ExpressionDecorator decorator) {
107         return decorator.decorate(this);
108     }
109
110     @Override
111     public void collectEffects(THashSet<Type> effects) {
112         effects.add(Types.PROC);
113         //seed.collectEffects(Query.RW, effects); // FIXME
114     }
115
116     @Override
117     public void accept(ExpressionVisitor visitor) {
118         visitor.visit(this);
119     }
120
121     @Override
122     public void forVariables(VariableProcedure procedure) {
123         seed.forVariables(procedure);
124     }
125     
126     @Override
127     public Expression accept(ExpressionTransformer transformer) {
128         return transformer.transform(this);
129     }
130
131 }