import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.Constant;
-import org.simantics.scl.compiler.constants.JavaConstructor;
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.ConstructorRef;
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.ParameterStackItem;
import org.simantics.scl.compiler.constants.generic.StackItem;
import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
-import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;
-import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator;
+import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerationConstants;
+import org.simantics.scl.compiler.internal.codegen.chr.CHRRuntimeRulesetCodeGenerator;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
+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.TPred;
import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.hash.THashSet;
public class CHRConstraint extends Symbol implements CHRRelation {
public final String name;
public final Type[] parameterTypes;
+ public String[] fieldNames;
public boolean implicitlyDeclared;
// Analysis
- public int firstPriorityAdded;
+ //public int firstPriorityAdded;
public int lastPriorityAdded;
- public int firstPriorityRemoved;
+ //public int firstPriorityRemoved;
public int lastPriorityRemoved;
// Transient info
public Constant[] accessors;
public Constant addProcedure;
public Constant removeProcedure;
- public Constant isAlive;
- public TIntObjectHashMap<IndexInfo> indices;
+ public String nextContainerFieldName;
- // Query plans
- public ArrayList<PrioritizedPlan> plans = new ArrayList<PrioritizedPlan>();
+ public TIntObjectHashMap<IndexInfo> indices;
public static class IndexInfo {
public final int indexMask;
JavaTypeTranslator jtt = context.javaTypeTranslator;
this.parentRuleset = parentRuleset;
- this.factClassName = parentRuleset.storeClassName + "$" + name;
- TCon factTypeConstructor = Types.con(parentRuleset.storeType.module, parentRuleset.storeType.name + "$" + name);
+ this.factClassName = parentRuleset.runtimeRulesetClassName + "$" + name;
+ TCon factTypeConstructor = Types.con(parentRuleset.runtimeRulesetType.module, parentRuleset.runtimeRulesetType.name + "$" + name);
this.factType = Types.apply(factTypeConstructor, TVar.EMPTY_ARRAY);
this.factTypeDesc = TypeDesc.forClass(factClassName);
Type[] constructorTypes = new Type[parameterTypes.length+1];
constructorTypes[0] = Types.INTEGER;
- for(int i=0;i<parameterTypes.length;++i)
- constructorTypes[i+1] = parameterTypes[i];
- this.constructor = new JavaConstructor(factClassName, Types.PROC, factType, constructorTypes);
+ ArrayList<StackItem> stackItems = new ArrayList<StackItem>(constructorTypes.length);
+ stackItems.add(new ParameterStackItem(0, Types.INTEGER));
+ for(int i=0;i<parameterTypes.length;++i) {
+ Type parameterType = parameterTypes[i];
+ constructorTypes[i+1] = parameterType;
+ if(!parameterType.equals(Types.UNIT))
+ stackItems.add(new ParameterStackItem(stackItems.size(), parameterType));
+ }
+ TypeDesc[] constructorTypeDescs = JavaTypeTranslator.filterVoid(jtt.toTypeDescs(constructorTypes));
+ this.constructor = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, constructorTypes,
+ stackItems.toArray(new StackItem[stackItems.size()]),
+ new ConstructorRef(factClassName, constructorTypeDescs),
+ null);
+ //this.constructor = new JavaConstructor(factClassName, Types.PROC, factType, constructorTypes);
this.accessId = new CallJava(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, Types.INTEGER, new Type[] {factType},
- null, new FieldRef(factClassName, "id", CHRCodeGenerator.FACT_ID_TYPE), null);
+ null, new FieldRef(CHRCodeGenerationConstants.CHRFact_name, "id", CHRRuntimeRulesetCodeGenerator.FACT_ID_TYPE), null);
this.accessors = new Constant[parameterTypes.length];
- for(int i=0;i<parameterTypes.length;++i)
+ for(int i=0;i<parameterTypes.length;++i) {
+ TypeDesc typeDesc = jtt.toTypeDesc(parameterTypes[i]);
+ if(typeDesc.equals(TypeDesc.VOID))
+ continue;
this.accessors[i] = new CallJava(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, parameterTypes[i], new Type[] {factType},
- null, new FieldRef(factClassName, "c" + i, jtt.toTypeDesc(parameterTypes[i])), null);
- this.addProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.storeType, factType},
- new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.storeType)},
- new ObjectMethodRef(false, factClassName, "add", TypeDesc.VOID, new TypeDesc[] {parentRuleset.storeTypeDesc}),
+ null, new FieldRef(factClassName, CHRCodeGenerationConstants.fieldName(i), jtt.toTypeDesc(parameterTypes[i])), null);
+ }
+ this.addProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.runtimeRulesetType, Types.CHRContext, factType},
+ new StackItem[] {new ParameterStackItem(2, factType), new ParameterStackItem(0, parentRuleset.runtimeRulesetType), new ParameterStackItem(1, Types.CHRContext)},
+ new ObjectMethodRef(false, factClassName, "add", TypeDesc.VOID, new TypeDesc[] {parentRuleset.runtimeRulesetTypeDesc, CHRCodeGenerationConstants.CHRContext}),
null);
this.indices = new TIntObjectHashMap<IndexInfo>(Math.min(10, 1 << parameterTypes.length));
if(context.module != null) // for unit testing
context.module.addTypeDescriptor(factTypeConstructor.name, new StandardTypeConstructor(factTypeConstructor, TVar.EMPTY_ARRAY, factTypeDesc));
+
+ // next container
+ if(parentRuleset.extensible) {
+ nextContainerFieldName = CHRCodeGenerationConstants.nextContainerName(name);
+ }
}
@Override
private IndexInfo createIndexInfo(CompilationContext context, int indexMask) {
ArrayList<Type> keyTypeList = new ArrayList<Type>(parameterTypes.length+1);
- keyTypeList.add(parentRuleset.storeType);
+ keyTypeList.add(parentRuleset.runtimeRulesetType);
for(int i=0;i<parameterTypes.length;++i)
if(((indexMask>>i)&1)==1)
keyTypeList.add(parameterTypes[i]);
String indexName = nameOfIndex(indexMask, parameterTypes.length);
Constant accessIndex;
if(indexMask == 0) {
- accessIndex = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {parentRuleset.storeType},
- null, new FieldRef(parentRuleset.storeClassName, name + "$" + indexName, factTypeDesc), null);
+ accessIndex = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {parentRuleset.runtimeRulesetType},
+ null, new FieldRef(parentRuleset.runtimeRulesetClassName, name + "$" + indexName, factTypeDesc), null);
}
else {
Type[] keyTypes = keyTypeList.toArray(new Type[keyTypeList.size()]);
- accessIndex = new JavaMethod(true, parentRuleset.storeClassName, name + "$" + indexName, Types.PROC, factType, keyTypes);
+ accessIndex = new JavaMethod(true, parentRuleset.runtimeRulesetClassName, name + "$" + indexName, Types.PROC, factType, keyTypes);
}
return new IndexInfo(
indexMask,
null, new FieldRef(factClassName, indexName + "Next", factTypeDesc), null)
);
}
-
- public Constant accessComponent(int i) {
- return accessors[i];
- }
- public IVal fetchFromIndex(CompilationContext context, int boundMask) {
+ public IndexInfo getOrCreateIndex(CompilationContext context, int boundMask) {
IndexInfo indexInfo = indices.get(boundMask);
if(indexInfo == null) {
indexInfo = createIndexInfo(context, boundMask);
indices.put(boundMask, indexInfo);
}
- return indexInfo.firstFact;
+ return indexInfo;
+ }
+
+ public IVal fetchFromIndex(CompilationContext context, int boundMask) {
+ return getOrCreateIndex(context, boundMask).firstFact;
}
public Constant nextElement(CompilationContext context, int boundMask) {
indexInfo = createIndexInfo(context, boundMask);
indices.put(boundMask, indexInfo);
}
- return indexInfo.nextFact;
+ return getOrCreateIndex(context, boundMask).nextFact;
}
public void setMayBeRemoved() {
if(removeProcedure == null) {
- removeProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.storeType, factType},
- new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.storeType)},
- new ObjectMethodRef(false, factClassName, "remove", TypeDesc.VOID, new TypeDesc[] {parentRuleset.storeTypeDesc}),
+ removeProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.runtimeRulesetType, factType},
+ new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.runtimeRulesetType)},
+ new ObjectMethodRef(false, factClassName, "remove", TypeDesc.VOID, new TypeDesc[] {parentRuleset.runtimeRulesetTypeDesc}),
null);
- isAlive = new JavaMethod(true, factClassName, "isAlive", Types.PROC, Types.BOOLEAN, factType);
}
}
- public int getMinimumPriority() {
- return plans.get(0).priority;
+ public TPred[] getTypeConstraints() {
+ return TPred.EMPTY_ARRAY;
+ }
+
+ public IVal accessComponent(long location, CodeWriter w, IVal fact, int i) {
+ Constant accessor = accessors[i];
+ if(accessor == null)
+ return NoRepConstant.UNIT;
+ else
+ return w.apply(location, accessor, fact);
}
- public boolean isPassive() {
- return plans.isEmpty();
+ @Override
+ public String[] getFieldNames() {
+ return fieldNames;
+ }
+
+ @Override
+ public void collectEnforceEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
+ }
+
+ @Override
+ public void collectQueryEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
}
}