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 partnerFacts = new ArrayList(); 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, ruleset.readCurrentId, 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; } }