]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / rules / TransformationRule.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/rules/TransformationRule.java
new file mode 100644 (file)
index 0000000..d70bf78
--- /dev/null
@@ -0,0 +1,93 @@
+package org.simantics.scl.compiler.elaboration.rules;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.query.Query;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+public class TransformationRule extends Symbol {
+    public static final TransformationRule[] EMPTY_ARRAY = new TransformationRule[0];
+    
+    public final boolean isAbstract;
+    public final Name name;
+    public final TransformationRule[] extendsRules;
+    public final THashMap<SectionName, Query[]> sections;
+    public final Variable[] variables;
+    private Type effect;
+    
+    public TransformationRule(boolean isAbstract,
+            Name name,
+            TransformationRule[] extendsRules,
+            THashMap<SectionName, Query[]> sections,
+            Variable[] variables) {
+        this.isAbstract = isAbstract;
+        this.name = name;
+        this.extendsRules = extendsRules;
+        this.sections = sections;
+        this.variables = variables;
+    }
+
+    public void checkType(final TypingContext context) {
+        for(Variable variable : variables)
+            if(variable.getType() == null)
+                variable.setType(Types.metaVar(Kinds.STAR));
+        sections.forEachValue(new TObjectProcedure<Query[]>() {
+
+            @Override
+            public boolean execute(Query[] queries) {
+                for(Query query : queries)
+                    query.checkType(context);
+                return true;
+            }
+        });
+        /*System.out.println("-------------------------------");
+        System.out.println(this);
+        System.out.println("-------------------------------");*/
+    }
+
+    public void setEffect(Type effect) {
+        this.effect = effect;
+    }
+    
+    public Type getEffect() {
+        return effect;
+    }
+    
+    public boolean forEachSection(TObjectObjectProcedure<SectionName, Query[]> procedure) {
+        if(extendsRules.length == 0)
+            return sections.forEachEntry(procedure);
+        else {
+            THashSet<TransformationRule> visitedRules = new THashSet<TransformationRule>();
+            return forEachSection(procedure, visitedRules);
+        }
+    }
+
+    private boolean forEachSection(
+            TObjectObjectProcedure<SectionName, Query[]> procedure,
+            THashSet<TransformationRule> visitedRules) {
+        if(visitedRules.add(this)) {
+            for(TransformationRule rule : extendsRules)
+                if(!rule.forEachSection(procedure, visitedRules))
+                    return false;
+            return sections.forEachEntry(procedure);
+        }
+        return true;
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        new ExpressionToStringVisitor(b).visit(this);
+        return b.toString();
+    }
+}