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