-package org.simantics.scl.compiler.elaboration.chr.plan;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.compilation.CompilationContext;\r
-import org.simantics.scl.compiler.constants.IntegerConstant;\r
-import org.simantics.scl.compiler.constants.JavaComparisonOperation;\r
-import org.simantics.scl.compiler.constants.singletons.IncreaseByOne;\r
-import org.simantics.scl.compiler.constants.singletons.ListElement;\r
-import org.simantics.scl.compiler.constants.singletons.ListLength;\r
-import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;\r
-import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-\r
-public abstract class PlanContext {\r
- public CompilationContext context;\r
- public CHRRuleset ruleset;\r
- public IVal storeVar;\r
- public ArrayList<PartnerFact> partnerFacts = new ArrayList<PartnerFact>();\r
- public IVal currentId;\r
- \r
- public PlanContext(CompilationContext context, CHRRuleset ruleset, IVal storeVar) {\r
- this.context = context;\r
- this.ruleset = ruleset;\r
- this.storeVar = storeVar;\r
- }\r
-\r
- public abstract void nextOp(CodeWriter w);\r
-\r
- public IVal generateNewId(long location, CodeWriter w) {\r
- if(currentId == null)\r
- currentId = w.apply(location, ruleset.readCurrentId, storeVar);\r
- IVal result = currentId;\r
- currentId = w.apply(location, IncreaseByOne.INSTANCE, currentId);\r
- return result;\r
- }\r
- \r
- public void iterateList(long location, CodeWriter w, Variable variable, IVal listValue) {\r
- Type componentType = variable.getType();\r
- IVal listLength = w.apply(location, ListLength.INSTANCE.createSpecialization(componentType), listValue);\r
- \r
- CodeWriter body = w.createBlock(Types.INTEGER);\r
- ICont bodyContinuation = body.getContinuation();\r
- CodeWriter end = w.createBlock();\r
- \r
- w.jump(body.getContinuation(), IntegerConstant.ZERO);\r
- \r
- IVal index = body.getParameters()[0];\r
- body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, index, listLength),\r
- end.getContinuation());\r
- variable.setVal(body.apply(location, ListElement.INSTANCE.createSpecialization(componentType), listValue, index));\r
- nextOp(body);\r
- if(body.isUnfinished())\r
- body.jump(bodyContinuation, body.apply(location, IncreaseByOne.INSTANCE, index));\r
- \r
- w.continueAs(end);\r
- }\r
-\r
- public void check(long location, CodeWriter w, IVal booleanValue) {\r
- CodeWriter end = w.createBlock();\r
- w.branchAwayUnless(booleanValue, end.getContinuation());\r
- nextOp(w);\r
- if(w.isUnfinished())\r
- w.jump(end.getContinuation());\r
- w.continueAs(end);\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.chr.plan;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.constants.IntegerConstant;
+import org.simantics.scl.compiler.constants.JavaComparisonOperation;
+import org.simantics.scl.compiler.constants.singletons.IncreaseByOne;
+import org.simantics.scl.compiler.constants.singletons.JustConstant;
+import org.simantics.scl.compiler.constants.singletons.ListElement;
+import org.simantics.scl.compiler.constants.singletons.ListLength;
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
+import org.simantics.scl.compiler.elaboration.java.EqualsFunction;
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public abstract class PlanContext {
+ public CompilationContext context;
+ public CHRRuleset ruleset;
+ public IVal mainStoreVar;
+ public IVal contextVar;
+ public ArrayList<PartnerFact> partnerFacts = new ArrayList<PartnerFact>();
+ public IVal currentId;
+
+ public PlanContext(CompilationContext context, CHRRuleset ruleset, IVal mainStoreVar, IVal contextVar) {
+ this.context = context;
+ this.ruleset = ruleset;
+ this.mainStoreVar = mainStoreVar;
+ this.contextVar = contextVar;
+ }
+
+ public abstract void nextOp(CodeWriter w);
+
+ public IVal generateNewId(long location, CodeWriter w) {
+ if(currentId == null)
+ currentId = w.apply(location, CHRRuleset.READ_CURRENT_ID, contextVar);
+ IVal result = currentId;
+ currentId = w.apply(location, IncreaseByOne.INSTANCE, currentId);
+ return result;
+ }
+
+ public void iterateList(long location, CodeWriter w, Variable variable, IVal listValue) {
+ Type componentType = variable.getType();
+ IVal listLength = w.apply(location, ListLength.INSTANCE.createSpecialization(componentType), listValue);
+
+ CodeWriter body = w.createBlock(Types.INTEGER);
+ ICont bodyContinuation = body.getContinuation();
+ CodeWriter end = w.createBlock();
+
+ w.jump(body.getContinuation(), IntegerConstant.ZERO);
+
+ IVal index = body.getParameters()[0];
+ body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, index, listLength),
+ end.getContinuation());
+ variable.setVal(body.apply(location, ListElement.INSTANCE.createSpecialization(componentType), listValue, index));
+ nextOp(body);
+ if(body.isUnfinished())
+ body.jump(bodyContinuation, body.apply(location, IncreaseByOne.INSTANCE, index));
+
+ w.continueAs(end);
+ }
+
+ public void iterateMaybe(long location, CodeWriter w, Variable variable, IVal maybeValue) {
+ Type componentType = variable.getType();
+
+ CodeWriter end = w.createBlock();
+ CodeWriter body = w.createBlock(componentType);
+ w.switch_(maybeValue, new Branch[] {
+ new Branch(JustConstant.INSTANCE, body.getContinuation()),
+ new Branch(null, end.getContinuation())
+ });
+
+ variable.setVal(body.getParameters()[0]);
+ nextOp(body);
+ if(body.isUnfinished())
+ body.jump(end.getContinuation());
+
+ w.continueAs(end);
+ }
+
+ public void check(long location, CodeWriter w, IVal booleanValue) {
+ CodeWriter end = w.createBlock();
+ w.branchAwayUnless(booleanValue, end.getContinuation());
+ nextOp(w);
+ if(w.isUnfinished())
+ w.jump(end.getContinuation());
+ w.continueAs(end);
+ }
+
+ public void checkEquals(long location, CodeWriter w, IVal a, IVal b) {
+ check(location, w, w.apply(location,
+ EqualsFunction.INSTANCE.createSpecialization(a.getType()),
+ a, b));
+ }
+
+ public void checkEqualsJust(long location, CodeWriter w, IVal value, IVal maybeValue) {
+ Type componentType = value.getType();
+
+ CodeWriter end = w.createBlock();
+ CodeWriter body = w.createBlock(componentType);
+ w.switch_(maybeValue, new Branch[] {
+ new Branch(JustConstant.INSTANCE, body.getContinuation()),
+ new Branch(null, end.getContinuation())
+ });
+ body.branchAwayUnless(body.apply(location,
+ EqualsFunction.INSTANCE.createSpecialization(componentType),
+ value, body.getParameters()[0]), end.getContinuation());
+ nextOp(body);
+ if(body.isUnfinished())
+ body.jump(end.getContinuation());
+
+ w.continueAs(end);
+ }
+
+ public IVal getStoreVar(CHRConstraint constraint) {
+ IncludeStatement includeStatement = ruleset.constraintSourceMap.get(constraint);
+ if(includeStatement != null)
+ return includeStatement.storeVar;
+ else
+ return mainStoreVar;
+ }
+}