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%2Frelations%2FCHRConstraint.java;h=c0f43928877458cbb9a9241ad3e764481acd3ce5;hp=9c21f541bef61a50a06f8a890d61e4bd38ae68f9;hb=78f577368ba4c71ad6fb3d9f16c03c634585cf7b;hpb=1b4d8b692f40d946deb5db8280eb4ca5b36a75a7 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java index 9c21f541b..c0f439288 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java @@ -1,208 +1,232 @@ -package org.simantics.scl.compiler.elaboration.chr.relations; - -import java.util.ArrayList; -import java.util.Collection; - -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.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.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.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.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 gnu.trove.map.hash.TIntObjectHashMap; - -public class CHRConstraint extends Symbol implements CHRRelation { - public final String name; - public final Type[] parameterTypes; - - public boolean implicitlyDeclared; - - // Analysis - public int firstPriorityAdded; - public int lastPriorityAdded; - public int firstPriorityRemoved; - public int lastPriorityRemoved; - - // Transient info - public CHRRuleset parentRuleset; - public String factClassName; - public Type factType; - public TypeDesc factTypeDesc; - - public TCon typeConstructor; - public Constant constructor; - public Constant accessId; - public Constant[] accessors; - public Constant addProcedure; - public Constant removeProcedure; - public Constant isAlive; - - public TIntObjectHashMap indices; - - // Query plans - public ArrayList plans = new ArrayList(); - - public static class IndexInfo { - public final int indexMask; - public final String indexName; - public final Constant firstFact; - public final Constant nextFact; - - public IndexInfo(int indexMask, String indexName, Constant firstFact, Constant nextFact) { - this.indexMask = indexMask; - this.indexName = indexName; - this.firstFact = firstFact; - this.nextFact = nextFact; - } - } - - public CHRConstraint(long location, String name, Type[] parameterTypes) { - this.location = location; - this.name = name; - this.parameterTypes = parameterTypes; - } - - public void initializeCodeGeneration(CompilationContext context, CHRRuleset parentRuleset) { - JavaTypeTranslator jtt = context.javaTypeTranslator; - - this.parentRuleset = parentRuleset; - this.factClassName = parentRuleset.storeClassName + "$" + name; - TCon factTypeConstructor = Types.con(parentRuleset.storeType.module, parentRuleset.storeType.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(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)); - } - - @Override - public TVar[] getTypeVariables() { - return TVar.EMPTY_ARRAY; - } - - @Override - public Type[] getParameterTypes() { - return parameterTypes; - } - - @Override - public String toString() { - return name; - } - - public Collection getIndices() { - return indices.valueCollection(); - } - - public boolean mayBeRemoved() { - return removeProcedure != null; - } - - private IndexInfo createIndexInfo(CompilationContext context, int indexMask) { - ArrayList keyTypeList = new ArrayList(parameterTypes.length+1); - keyTypeList.add(parentRuleset.storeType); - for(int i=0;i>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); - } - else { - Type[] keyTypes = keyTypeList.toArray(new Type[keyTypeList.size()]); - accessIndex = new JavaMethod(true, parentRuleset.storeClassName, name + "$" + indexName, Types.PROC, factType, keyTypes); - } - return new IndexInfo( - indexMask, - indexName, - accessIndex, - new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {factType}, - null, new FieldRef(factClassName, indexName + "Next", factTypeDesc), null) - ); - } - - public Constant accessComponent(int i) { - return accessors[i]; - } - - public IVal fetchFromIndex(CompilationContext context, int boundMask) { - IndexInfo indexInfo = indices.get(boundMask); - if(indexInfo == null) { - indexInfo = createIndexInfo(context, boundMask); - indices.put(boundMask, indexInfo); - } - return indexInfo.firstFact; - } - - public Constant nextElement(CompilationContext context, int boundMask) { - IndexInfo indexInfo = indices.get(boundMask); - if(indexInfo == null) { - indexInfo = createIndexInfo(context, boundMask); - indices.put(boundMask, indexInfo); - } - return indexInfo.nextFact; - } - - - public static String nameOfIndex(int indexMask, int length) { - char[] chars = new char[length]; - for(int i=0;i>i)&1) == 1 ? 'b' : 'f'; - return new String(chars); - } - - 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}), - null); - isAlive = new JavaMethod(true, factClassName, "isAlive", Types.PROC, Types.BOOLEAN, factType); - } - } - - public int getMinimumPriority() { - return plans.get(0).priority; - } - - public boolean isPassive() { - return plans.isEmpty(); - } -} +package org.simantics.scl.compiler.elaboration.chr.relations; + +import java.util.ArrayList; +import java.util.Collection; + +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.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.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; + +public class CHRConstraint extends Symbol implements CHRRelation { + public final String name; + public final Type[] parameterTypes; + + public boolean implicitlyDeclared; + + // Analysis + //public int firstPriorityAdded; + public int lastPriorityAdded; + //public int firstPriorityRemoved; + public int lastPriorityRemoved; + + // Transient info + public CHRRuleset parentRuleset; + public String factClassName; + public Type factType; + public TypeDesc factTypeDesc; + + public TCon typeConstructor; + public Constant constructor; + public Constant accessId; + public Constant[] accessors; + public Constant addProcedure; + public Constant removeProcedure; + + public String nextContainerFieldName; + + public TIntObjectHashMap indices; + + public static class IndexInfo { + public final int indexMask; + public final String indexName; + public final Constant firstFact; + public final Constant nextFact; + + public IndexInfo(int indexMask, String indexName, Constant firstFact, Constant nextFact) { + this.indexMask = indexMask; + this.indexName = indexName; + this.firstFact = firstFact; + this.nextFact = nextFact; + } + } + + public CHRConstraint(long location, String name, Type[] parameterTypes) { + this.location = location; + this.name = name; + this.parameterTypes = parameterTypes; + } + + public void initializeCodeGeneration(CompilationContext context, CHRRuleset parentRuleset) { + JavaTypeTranslator jtt = context.javaTypeTranslator; + + this.parentRuleset = parentRuleset; + 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; + ArrayList stackItems = new ArrayList(constructorTypes.length); + stackItems.add(new ParameterStackItem(0, Types.INTEGER)); + for(int i=0;i(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 + public TVar[] getTypeVariables() { + return TVar.EMPTY_ARRAY; + } + + @Override + public Type[] getParameterTypes() { + return parameterTypes; + } + + @Override + public String toString() { + return name; + } + + public Collection getIndices() { + return indices.valueCollection(); + } + + public boolean mayBeRemoved() { + return removeProcedure != null; + } + + private IndexInfo createIndexInfo(CompilationContext context, int indexMask) { + ArrayList keyTypeList = new ArrayList(parameterTypes.length+1); + keyTypeList.add(parentRuleset.runtimeRulesetType); + for(int i=0;i>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.runtimeRulesetType}, + null, new FieldRef(parentRuleset.runtimeRulesetClassName, name + "$" + indexName, factTypeDesc), null); + } + else { + Type[] keyTypes = keyTypeList.toArray(new Type[keyTypeList.size()]); + accessIndex = new JavaMethod(true, parentRuleset.runtimeRulesetClassName, name + "$" + indexName, Types.PROC, factType, keyTypes); + } + return new IndexInfo( + indexMask, + indexName, + accessIndex, + new CallJava(TVar.EMPTY_ARRAY, Types.PROC, factType, new Type[] {factType}, + null, new FieldRef(factClassName, indexName + "Next", factTypeDesc), null) + ); + } + + 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; + } + + public IVal fetchFromIndex(CompilationContext context, int boundMask) { + return getOrCreateIndex(context, boundMask).firstFact; + } + + public Constant nextElement(CompilationContext context, int boundMask) { + IndexInfo indexInfo = indices.get(boundMask); + if(indexInfo == null) { + indexInfo = createIndexInfo(context, boundMask); + indices.put(boundMask, indexInfo); + } + return getOrCreateIndex(context, boundMask).nextFact; + } + + + public static String nameOfIndex(int indexMask, int length) { + char[] chars = new char[length]; + for(int i=0;i>i)&1) == 1 ? 'b' : 'f'; + return new String(chars); + } + + public void setMayBeRemoved() { + if(removeProcedure == null) { + 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); + } + } + + 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); + } +}