]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java
(refs #7365) Fixed the bug in the test CHR11.scl
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRRuleset.java
index d5f61965454e80006631d98d76621fc56ba94e50..63a8344f220d93fdc63296eb05abcc6fe0b267d5 100644 (file)
@@ -12,6 +12,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;
@@ -32,13 +33,13 @@ 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;
@@ -67,8 +68,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;
@@ -215,6 +221,7 @@ public class CHRRuleset extends Symbol {
             int max = 1 << constraint.parameterTypes.length;
             for(int i=0;i<max;++i)
                 constraint.getOrCreateIndex(cachedContext, i);
+            constraint.setMayBeRemoved();
             /*
             constraint.getOrCreateIndex(cachedContext, 0);
             if(constraint.parameterTypes.length > 0)
@@ -247,10 +254,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));
     }
@@ -260,7 +263,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);
@@ -280,7 +283,7 @@ public class CHRRuleset extends Symbol {
                     methodWriter.return_(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();
@@ -289,6 +292,10 @@ 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);
                 }
+                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_(NoRepConstant.UNIT);
             }
             {
@@ -299,6 +306,10 @@ 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);
                 }
+                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_(NoRepConstant.UNIT);
             }
         }
@@ -309,7 +320,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) {
@@ -329,4 +340,9 @@ public class CHRRuleset extends Symbol {
                 literal.collectEnforceEffects(effects);
         }
     }
+
+    public void addRule(CHRRule rule) {
+        rules.add(rule);
+        rule.parentRuleset = this;
+    }
 }