X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fchr%2FCHRRuleset.java;h=47d57dabca1efb45e9fc42e8648c7244a2603a64;hp=bb00f08850f8fa3cd6f21586a8b60a6e052ff640;hb=e12e3ad357853a07b24923b341c4732962a94623;hpb=fad36d463b75c3a9944d875fc627c3533f6da74d diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java index bb00f0885..47d57dabc 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java @@ -3,6 +3,7 @@ package org.simantics.scl.compiler.elaboration.chr; import java.util.ArrayList; import org.cojen.classfile.TypeDesc; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.constants.BooleanConstant; import org.simantics.scl.compiler.constants.Constant; @@ -12,6 +13,7 @@ import org.simantics.scl.compiler.constants.JavaMethod; import org.simantics.scl.compiler.constants.NoRepConstant; import org.simantics.scl.compiler.constants.generic.CallJava; import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef; +import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef; import org.simantics.scl.compiler.constants.generic.MethodRef.SetFieldRef; import org.simantics.scl.compiler.elaboration.chr.analysis.CHRConstraintGGInfo; import org.simantics.scl.compiler.elaboration.chr.analysis.UsageAnalysis; @@ -22,7 +24,6 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement; import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.errors.Locations; @@ -32,17 +33,16 @@ import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor; +import org.simantics.scl.compiler.internal.codegen.utils.Constants; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; -import org.simantics.scl.runtime.chr.CHRContext; import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public class CHRRuleset extends Symbol { @@ -67,8 +67,13 @@ public class CHRRuleset extends Symbol { public TCon runtimeRulesetType; public BoundVar runtimeRulesetVariable; public TypeDesc runtimeRulesetTypeDesc; - public Constant readCurrentId; - public Constant writeCurrentId; + + public static final Constant READ_CURRENT_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext}, + null, new FieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null); + public static final Constant WRITE_CURRENT_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext, Types.INTEGER}, + null, new SetFieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null); + public static final Constant GENERATE_ID = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext}, + null, new ObjectMethodRef(false, CHRCodeGenerationConstants.CHRContext_name, "generateId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE, Constants.EMPTY_TYPEDESC_ARRAY), null); // FIXME remove and change the parameter of Expression.toVal private CompilationContext cachedContext; @@ -80,7 +85,12 @@ public class CHRRuleset extends Symbol { public CHRRuleset() { initConstraint = new CHRConstraint(Locations.NO_LOCATION, INIT_CONSTRAINT, Type.EMPTY_ARRAY); - constraints.add(initConstraint); + addConstraint(initConstraint); + } + + public void addConstraint(CHRConstraint constraint) { + constraints.add(constraint); + constraint.setParent(this); } public void resolve(TranslationContext context) { @@ -117,13 +127,6 @@ public class CHRRuleset extends Symbol { }*/ } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(IncludeStatement include : includes) - include.value.collectRefs(allRefs, refs); - for(CHRRule rule : rules) - rule.collectRefs(allRefs, refs); - } - public void checkType(TypingContext context) { for(IncludeStatement include : includes) include.value = include.value.checkType(context, include.ruleset.runtimeRulesetType); @@ -138,20 +141,6 @@ public class CHRRuleset extends Symbol { rule.collectVars(allVars, vars); } - public void forVariables(VariableProcedure procedure) { - for(IncludeStatement include : includes) - include.value.forVariables(procedure); - for(CHRRule rule : rules) - rule.forVariables(procedure); - } - - public void collectFreeVariables(THashSet vars) { - for(IncludeStatement include : includes) - include.value.collectFreeVariables(vars); - for(CHRRule rule : rules) - rule.collectFreeVariables(vars); - } - public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { this.location = loc; @@ -179,33 +168,37 @@ public class CHRRuleset extends Symbol { } } - public void compile(SimplificationContext context) { - initializeCodeGeneration(context.getCompilationContext()); - if(extensible) - applyExtensibleDefaults(); - UsageAnalysis.analyzeUsage(this); - for(CHRRule rule : rules) { - rule.compile(context.getCompilationContext(), initConstraint); - for(CHRSearchPlan plan : rule.plans) { - CHRConstraint constraint = plan.constraint; - if(!activeConstraintGGInfo.containsKey(constraint)) { - activeConstraintGGInfo.put(constraint, new CHRConstraintGGInfo(rule.priority)); - IncludeStatement include = constraintSourceMap.get(constraint); - if(include != null) { - ArrayList list = inverseActiveConstraintSourceMap.get(include); - if(list == null) { - list = new ArrayList(4); - inverseActiveConstraintSourceMap.put(include, list); + private void compile(SimplificationContext context) { + try { + initializeCodeGeneration(context.getCompilationContext()); + if(extensible) + applyExtensibleDefaults(); + UsageAnalysis.analyzeUsage(this); + for(CHRRule rule : rules) { + rule.compile(context.getCompilationContext(), initConstraint); + for(CHRSearchPlan plan : rule.plans) { + CHRConstraint constraint = plan.constraint; + if(!activeConstraintGGInfo.containsKey(constraint)) { + activeConstraintGGInfo.put(constraint, new CHRConstraintGGInfo(rule.priority)); + IncludeStatement include = constraintSourceMap.get(constraint); + if(include != null) { + ArrayList list = inverseActiveConstraintSourceMap.get(include); + if(list == null) { + list = new ArrayList(4); + inverseActiveConstraintSourceMap.put(include, list); + } + list.add(constraint); } - list.add(constraint); } } } - } - // remove init constraint if it is not useful - if(getMinimumPriority(initConstraint) == Integer.MAX_VALUE) { - constraints.remove(0); - initConstraint = null; + // remove init constraint if it is not useful + if(getMinimumPriority(initConstraint) == Integer.MAX_VALUE) { + constraints.remove(0); + initConstraint = null; + } + } catch(Exception e) { + throw InternalCompilerError.injectLocation(location, e); } } @@ -223,13 +216,22 @@ public class CHRRuleset extends Symbol { } } - public void simplify(SimplificationContext context) { - for(IncludeStatement include : includes) + private void simplify(SimplificationContext context) { + for(IncludeStatement include : includes) { + //include.ruleset.simplifyAndCompileIfNeeded(context); include.value = include.value.simplify(context); + } for(CHRRule rule : rules) rule.simplify(context); } + public void simplifyAndCompileIfNeeded(SimplificationContext context) { + if(runtimeRulesetTypeDesc == null) { + simplify(context); + compile(context); + } + } + public void setRulesetType(TCon type, String className) { this.runtimeRulesetType = type; this.runtimeRulesetClassName = className; @@ -248,10 +250,6 @@ public class CHRRuleset extends Symbol { runtimeRulesetVariable = new BoundVar(runtimeRulesetType); for(CHRConstraint constraint : constraints) constraint.initializeCodeGeneration(context, this); - readCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {Types.CHRContext}, - null, new FieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null); - writeCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext, Types.INTEGER}, - null, new SetFieldRef(CHRCodeGenerationConstants.CHRContext_name, "currentId", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null); if(createTypeDesc && context.module != null) // for unit testing context.module.addTypeDescriptor(runtimeRulesetType.name, new StandardTypeConstructor(runtimeRulesetType, TVar.EMPTY_ARRAY, runtimeRulesetTypeDesc)); } @@ -261,7 +259,7 @@ public class CHRRuleset extends Symbol { public IVal generateCode(CodeWriter w) { for(IncludeStatement include : includes) { - include.storeVar = include.value.toVal(cachedContext.environment, w); + include.storeVar = include.value.toVal(cachedContext, w); initialPriorityNumber = Math.max(initialPriorityNumber, include.ruleset.initialPriorityNumber + include.ruleset.priorityCount); } CHRRulesetObject object = new CHRRulesetObject(runtimeRulesetVariable, this); @@ -278,10 +276,10 @@ public class CHRRuleset extends Symbol { PlanRealizer realizer = new PlanRealizer(cachedContext, this, runtimeRulesetVariable, implementationParameters[0], plan.ops); realizer.nextOp(methodWriter); if(methodWriter.isUnfinished()) - methodWriter.return_(BooleanConstant.TRUE); + methodWriter.return_(rule.location, BooleanConstant.TRUE); } } - if(!includes.isEmpty()) { + if(!includes.isEmpty() || extensible) { { CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext}); initializer = methodWriter.getFunction(); @@ -290,7 +288,11 @@ public class CHRRuleset extends Symbol { new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}), object.getTarget(), methodWriter.getParameters()[0], include.storeVar); } - methodWriter.return_(NoRepConstant.UNIT); + if(extensible) + methodWriter.apply(Locations.NO_LOCATION, + new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), + object.getTarget(), methodWriter.getParameters()[0]); + methodWriter.return_(location, NoRepConstant.UNIT); } { CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext}); @@ -300,7 +302,11 @@ public class CHRRuleset extends Symbol { new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}), object.getTarget(), methodWriter.getParameters()[0], include.storeVar); } - methodWriter.return_(NoRepConstant.UNIT); + if(extensible) + methodWriter.apply(Locations.NO_LOCATION, + new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), + object.getTarget(), methodWriter.getParameters()[0]); + methodWriter.return_(location, NoRepConstant.UNIT); } } if(initConstraint != null) { @@ -310,7 +316,7 @@ public class CHRRuleset extends Symbol { new JavaMethod(true, runtimeRulesetClassName, "initialize", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), object.getTarget(), chrContext); } - IVal initFact = w.apply(location, initConstraint.constructor, IntegerConstant.ZERO); + IVal initFact = w.apply(location, initConstraint.constructor, w.apply(location, GENERATE_ID, chrContext)); w.apply(location, initConstraint.addProcedure, runtimeRulesetVariable, chrContext, initFact); w.apply(location, ACTIVATE, chrContext, new IntegerConstant(Integer.MAX_VALUE)); if(deinitializer != null) { @@ -322,12 +328,8 @@ public class CHRRuleset extends Symbol { return runtimeRulesetVariable; } - public void collectEffects(THashSet effects) { - for(CHRRule rule : rules) { - for(CHRLiteral literal : rule.head.literals) - literal.collectQueryEffects(effects); - for(CHRLiteral literal : rule.head.literals) - literal.collectEnforceEffects(effects); - } + public void addRule(CHRRule rule) { + rules.add(rule); + rule.parentRuleset = this; } }