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.ListElement; import org.simantics.scl.compiler.constants.singletons.ListLength; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; import org.simantics.scl.compiler.elaboration.expressions.Variable; 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 storeVar; public ArrayList partnerFacts = new ArrayList(); public IVal currentId; public PlanContext(CompilationContext context, CHRRuleset ruleset, IVal storeVar) { this.context = context; this.ruleset = ruleset; this.storeVar = storeVar; } public abstract void nextOp(CodeWriter w); public IVal generateNewId(long location, CodeWriter w) { if(currentId == null) currentId = w.apply(location, ruleset.readCurrentId, storeVar); 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 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); } }