]> gerrit.simantics Code Review - simantics/platform.git/blob
d70bf785e250622fbb2d7987fc65550cf97b804c
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.rules;
2
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.procedure.TObjectObjectProcedure;
5 import gnu.trove.procedure.TObjectProcedure;
6 import gnu.trove.set.hash.THashSet;
7
8 import org.simantics.scl.compiler.common.names.Name;
9 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
10 import org.simantics.scl.compiler.elaboration.expressions.Variable;
11 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
12 import org.simantics.scl.compiler.elaboration.query.Query;
13 import org.simantics.scl.compiler.internal.parsing.Symbol;
14 import org.simantics.scl.compiler.types.Type;
15 import org.simantics.scl.compiler.types.Types;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
17
18 public class TransformationRule extends Symbol {
19     public static final TransformationRule[] EMPTY_ARRAY = new TransformationRule[0];
20     
21     public final boolean isAbstract;
22     public final Name name;
23     public final TransformationRule[] extendsRules;
24     public final THashMap<SectionName, Query[]> sections;
25     public final Variable[] variables;
26     private Type effect;
27     
28     public TransformationRule(boolean isAbstract,
29             Name name,
30             TransformationRule[] extendsRules,
31             THashMap<SectionName, Query[]> sections,
32             Variable[] variables) {
33         this.isAbstract = isAbstract;
34         this.name = name;
35         this.extendsRules = extendsRules;
36         this.sections = sections;
37         this.variables = variables;
38     }
39
40     public void checkType(final TypingContext context) {
41         for(Variable variable : variables)
42             if(variable.getType() == null)
43                 variable.setType(Types.metaVar(Kinds.STAR));
44         sections.forEachValue(new TObjectProcedure<Query[]>() {
45
46             @Override
47             public boolean execute(Query[] queries) {
48                 for(Query query : queries)
49                     query.checkType(context);
50                 return true;
51             }
52         });
53         /*System.out.println("-------------------------------");
54         System.out.println(this);
55         System.out.println("-------------------------------");*/
56     }
57
58     public void setEffect(Type effect) {
59         this.effect = effect;
60     }
61     
62     public Type getEffect() {
63         return effect;
64     }
65     
66     public boolean forEachSection(TObjectObjectProcedure<SectionName, Query[]> procedure) {
67         if(extendsRules.length == 0)
68             return sections.forEachEntry(procedure);
69         else {
70             THashSet<TransformationRule> visitedRules = new THashSet<TransformationRule>();
71             return forEachSection(procedure, visitedRules);
72         }
73     }
74
75     private boolean forEachSection(
76             TObjectObjectProcedure<SectionName, Query[]> procedure,
77             THashSet<TransformationRule> visitedRules) {
78         if(visitedRules.add(this)) {
79             for(TransformationRule rule : extendsRules)
80                 if(!rule.forEachSection(procedure, visitedRules))
81                     return false;
82             return sections.forEachEntry(procedure);
83         }
84         return true;
85     }
86     
87     @Override
88     public String toString() {
89         StringBuilder b = new StringBuilder();
90         new ExpressionToStringVisitor(b).visit(this);
91         return b.toString();
92     }
93 }