]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/Constraint.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / elaboration / constraints / Constraint.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/Constraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/Constraint.java
new file mode 100644 (file)
index 0000000..fb19065
--- /dev/null
@@ -0,0 +1,115 @@
+package org.simantics.scl.compiler.internal.elaboration.constraints;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;\r
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
+import org.simantics.scl.compiler.types.TPred;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.util.Typed;\r
+import org.simantics.scl.runtime.tuple.Tuple0;\r
+\r
+public class Constraint implements Typed {\r
+    public static final Constraint[] EMPTY_ARRAY = new Constraint[0];\r
+    \r
+    public static final int STATE_UNSOLVED = 0;\r
+    public static final int STATE_HAS_INSTANCE = 1;\r
+    public static final int STATE_HAS_SUBCLASS = 2;\r
+    public static final int STATE_GIVEN = 3;\r
+    \r
+    public static final Expression GIVEN_GENERATOR = new ELiteral(new Constant(Types.UNIT) {\r
+        @Override\r
+        public Object realizeValue(TransientClassBuilder classBuilder) {\r
+            return Tuple0.INSTANCE;\r
+        }        \r
+    });\r
+    \r
+    public TPred constraint;\r
+    int state = STATE_UNSOLVED;\r
+    public final Variable evidence;\r
+    Expression generator;\r
+    Type[] generatorParameters;\r
+    Constraint[] dependsOn;\r
+    boolean handled;\r
+    long demandLocation;\r
+           \r
+    public Constraint(TPred constraint, Variable evidence, long demandLocation) {\r
+        if(SCLCompilerConfiguration.DEBUG) {\r
+            if(constraint == null || evidence == null)\r
+                throw new NullPointerException();\r
+        }\r
+        this.constraint = constraint;\r
+        this.evidence = evidence;\r
+        this.demandLocation = demandLocation;\r
+    }\r
+    \r
+    public void setGenerator(int newState, Expression generator, Type[] generatorParameters, Constraint ... dependsOn) {\r
+        if(SCLCompilerConfiguration.DEBUG) {\r
+            if(generator == null)\r
+                throw new NullPointerException();\r
+            for(Type generatorParameter : generatorParameters)\r
+                if(generatorParameter == null)\r
+                    throw new NullPointerException();\r
+        }\r
+        this.state = newState;\r
+        this.generator = generator;\r
+        this.dependsOn = dependsOn;\r
+        this.generatorParameters = generatorParameters;\r
+    }\r
+\r
+    public Expression generate(long loc) {\r
+        Expression result = generator;\r
+        for(Type p : generatorParameters)\r
+            result = new EApplyType(loc, result, p);\r
+        for(Constraint dep : dependsOn) {\r
+            result = new EApply(loc, result, new EVariable(loc, dep.evidence));\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    public void collect(ConstraintEnvironment environment, ArrayList<Constraint> unsolvedConstraints, ArrayList<Constraint> solvedConstraints) {\r
+        if(!handled) {\r
+            switch(state) {\r
+            case STATE_UNSOLVED:\r
+                unsolvedConstraints.add(this);\r
+                break;\r
+            case STATE_HAS_SUBCLASS:\r
+                // Try to find constant evidence and prefer that\r
+                // to subclass\r
+                {\r
+                    Reduction reduction = environment.reduce(constraint);\r
+                    if(reduction != null && reduction.demands.length == 0) {\r
+                        generator = reduction.generator;\r
+                        generatorParameters = reduction.parameters;\r
+                        dependsOn = Constraint.EMPTY_ARRAY;\r
+                        state = STATE_HAS_INSTANCE;\r
+                    }\r
+                }\r
+                // Intentionally no break\r
+            case STATE_HAS_INSTANCE:\r
+                for(Constraint dep : dependsOn)\r
+                    dep.collect(environment, unsolvedConstraints, solvedConstraints);\r
+                solvedConstraints.add(this);\r
+                break;\r
+            }\r
+            handled = true;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Type getType() {\r
+        return constraint;\r
+    }\r
+    \r
+    public long getDemandLocation() {\r
+        return demandLocation;\r
+    }\r
+}
\ No newline at end of file