From: Hannu Niemistö Date: Fri, 2 Jun 2017 13:39:28 +0000 (+0300) Subject: (refs #7250) Merging master, minor CHR bugfixes X-Git-Tag: v1.31.0~339^2~3 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=fad36d463b75c3a9944d875fc627c3533f6da74d;hp=-c (refs #7250) Merging master, minor CHR bugfixes Change-Id: I11c76beee0e73ff78370f72bbfb88fdbdf6c7616 --- fad36d463b75c3a9944d875fc627c3533f6da74d diff --combined bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java index a8dca8c11,cc883c0ea..5d258dd9e --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java @@@ -17,6 -17,7 +17,7 @@@ import org.simantics.scl.compiler.const import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule; + import org.simantics.scl.compiler.elaboration.modules.DerivedProperty; import org.simantics.scl.compiler.elaboration.modules.InlineProperty; import org.simantics.scl.compiler.elaboration.modules.MethodImplementation; import org.simantics.scl.compiler.elaboration.modules.PrivateProperty; @@@ -124,13 -125,18 +125,18 @@@ public class CodeGeneration decomposed.typeParameters, decomposed.returnType, decomposed.parameterTypes));*/ + boolean isDerived = false; for(SCLValueProperty prop : value.getProperties()) { if(prop instanceof InlineProperty) { InlineProperty inlineProperty = (InlineProperty)prop; constant.setInlineArity(inlineProperty.arity, inlineProperty.phaseMask); } else if(prop == PrivateProperty.INSTANCE) - constant.setPrivate(true); + constant.setPrivate(!isDerived); + else if(prop == DerivedProperty.INSTANCE) { + constant.setPrivate(false); + isDerived = true; + } } } // This is quite hackish optimization that can be possibly removed when @@@ -183,7 -189,7 +189,7 @@@ } public void optimizeSSA() { - if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION) { + if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION && SCLCompilerConfiguration.debugFilter(module.getName())) { System.out.println("=== SSA before optimization ===================================="); System.out.println(ssaModule); } @@@ -199,7 -205,7 +205,7 @@@ if(phase == 0) ssaModule.saveInlinableDefinitions(); } - if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING) { + if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING && SCLCompilerConfiguration.debugFilter(module.getName())) { System.out.println("=== SSA before lambda lifting =================================="); System.out.println(ssaModule); } @@@ -211,7 -217,7 +217,7 @@@ } public void generateCode() { - if(SCLCompilerConfiguration.SHOW_FINAL_SSA) { + if(SCLCompilerConfiguration.SHOW_FINAL_SSA && SCLCompilerConfiguration.debugFilter(module.getName())) { System.out.println("=== Final SSA =================================================="); System.out.println(ssaModule); } diff --combined bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java index 6499ab4fe,7887ed717..359448e1d --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java @@@ -6,7 -6,6 +6,7 @@@ import java.util.List import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.datatypes.Constructor; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor; @@@ -32,7 -31,6 +32,7 @@@ import org.simantics.scl.compiler.elabo import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral; import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EPreCHRRulesetConstructor; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; @@@ -41,6 -39,7 +41,7 @@@ import org.simantics.scl.compiler.elabo import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration; import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule; import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty; + import org.simantics.scl.compiler.elaboration.modules.DerivedProperty; import org.simantics.scl.compiler.elaboration.modules.InlineProperty; import org.simantics.scl.compiler.elaboration.modules.MethodImplementation; import org.simantics.scl.compiler.elaboration.modules.PrivateProperty; @@@ -49,7 -48,6 +50,7 @@@ import org.simantics.scl.compiler.elabo import org.simantics.scl.compiler.elaboration.modules.TypeClass; import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance; import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod; +import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation; @@@ -87,7 -85,6 +88,7 @@@ import org.simantics.scl.compiler.inter import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst; import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst; +import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst; import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst; @@@ -215,8 -212,7 +216,8 @@@ public class Elaboration public void addTypesToEnvironment( ArrayList dataTypesAst, ArrayList typeAliasesAst, - ArrayList effectsAst) { + ArrayList effectsAst, + ArrayList rulesetsAst) { for(DDataAst dataType : dataTypesAst) { dataType.parameterKinds = new Kind[dataType.parameters.length]; Kind constructorKind = Kinds.STAR; @@@ -231,7 -227,8 +232,7 @@@ NameExistenceChecks.checkIfTypeExists(errorLog, dataType.location, importedEnvironment, dataType.name); - if(module.addTypeDescriptor(dataType.name, typeConstructor)) - errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module."); + addTypeDescriptor(dataType.location, dataType.name, typeConstructor); dataType.typeConstructor = typeConstructor; } @@@ -239,7 -236,9 +240,7 @@@ TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length); NameExistenceChecks.checkIfTypeExists(errorLog, typeAlias.location, importedEnvironment, typeAlias.name); - if(module.addTypeDescriptor(typeAlias.name, alias)) { - errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module."); - } + addTypeDescriptor(typeAlias.location, typeAlias.name, alias); } for(DEffectAst effect : effectsAst) { @@@ -250,24 -249,11 +251,24 @@@ TypeDesc.forClass(effect.threadLocalType) )); if(module.addEffectConstructor(effect.name, effectConstructor)) - errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module."); - } + errorLog.log(effect.location, "Effect "+effect.name+" has already been defined in this module."); + } + for(DRulesetAst ruleset : rulesetsAst) { + ruleset.type = Types.con(moduleName, ruleset.name); + ruleset.className = compilationContext.namingPolicy.getDataTypeClassName(ruleset.name); + StandardTypeConstructor typeConstructor = new StandardTypeConstructor(ruleset.type, Kinds.STAR, + TypeDesc.forClass(ruleset.className), ruleset.documentation == null ? null : ruleset.documentation.documentation); + typeConstructor.external = true; + addTypeDescriptor(ruleset.location, ruleset.name, typeConstructor); + } javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment); compilationContext.javaTypeTranslator = javaTypeTranslator; } + + private void addTypeDescriptor(long location, String name, TypeDescriptor typeDescriptor) { + if(module.addTypeDescriptor(name, typeDescriptor)) + errorLog.log(location, "Type "+name+" has already been defined in this module."); + } private static final int[] EMPTY_INT_ARRAY = new int[0]; @@@ -602,6 -588,7 +603,7 @@@ String fullName = instancePrefix + valueName; long loc = valueDefs.getDefinition(valueName).get(0).location; valueDefinitionsAst.addFrom(valueDefs, valueName, fullName); + valueDefinitionsAst.setDerived(fullName); /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"), Collections.emptyList()));*/ TypeClassMethod method = typeClass.methods.get(valueName); @@@ -717,18 -704,6 +719,18 @@@ } } + public void processRulesets(ArrayList rulesetsAst) { + for(DRulesetAst ruleset : rulesetsAst) { + String constructorName = "create" + ruleset.name; + supplementedTypeAnnotations.add(new SupplementedValueType(ruleset.location, constructorName, Types.functionE(Types.PUNIT, Types.PROC, ruleset.type))); + try { + valueDefinitionsAst.add(new DValueAst(new EVar(constructorName), new EPreCHRRulesetConstructor(ruleset))); + } catch (NotPatternException e) { + throw new InternalCompilerError(ruleset.location, e); + } + } + } + /** * Convert a java class method into a {@link CallJava} instance. * Compilation errors are logged for failures in finding the named class or in accessing the method. @@@ -1171,6 -1146,8 +1173,8 @@@ value.definitionLocation = location; if(module.addValue(value)) errorLog.log(location, "Value " + name + " is already defined."); + if(valueDefinitionsAst.isDerived(name)) + value.addProperty(DerivedProperty.INSTANCE); } for(DValueTypeAst valueTypeAst : typeAnnotationsAst) for(EVar name : valueTypeAst.names) { diff --combined bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java index d5f619654,bb5491ad1..bb00f0885 --- 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 @@@ -7,30 -7,23 +7,30 @@@ import org.simantics.scl.compiler.compi import org.simantics.scl.compiler.constants.BooleanConstant; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.IntegerConstant; +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.FieldRef; 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; +import org.simantics.scl.compiler.elaboration.chr.plan.CHRSearchPlan; import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer; -import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; 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; -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.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.writer.CodeWriter; import org.simantics.scl.compiler.internal.parsing.Symbol; @@@ -38,9 -31,7 +38,9 @@@ import org.simantics.scl.compiler.types 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; @@@ -51,22 -42,15 +51,22 @@@ public class CHRRuleset extends Symbol public ArrayList constraints = new ArrayList(); public ArrayList rules = new ArrayList(); + public ArrayList includes = new ArrayList(); + public THashMap constraintSourceMap = new THashMap(); + public THashMap activeConstraintGGInfo = new THashMap(); // contains also imported constraints + public THashMap> inverseActiveConstraintSourceMap = new THashMap>(); + + public boolean extensible; public CHRConstraint initConstraint; public int priorityCount; - public String storeClassName; - public TCon storeType; - public BoundVar storeVariable; - public TypeDesc storeTypeDesc; - public Constant activateProcedure; + public int initialPriorityNumber = 0; + + public String runtimeRulesetClassName; + public TCon runtimeRulesetType; + public BoundVar runtimeRulesetVariable; + public TypeDesc runtimeRulesetTypeDesc; public Constant readCurrentId; public Constant writeCurrentId; @@@ -74,9 -58,9 +74,9 @@@ private CompilationContext cachedContext; // For code generation - public BoundVar this_; - public BoundVar[] parameters; - public TypeDesc[] parameterTypeDescs; + public CHRRulesetObject rulesetObject; + public SSAFunction initializer; + public SSAFunction deinitializer; public CHRRuleset() { initConstraint = new CHRConstraint(Locations.NO_LOCATION, INIT_CONSTRAINT, Type.EMPTY_ARRAY); @@@ -84,27 -68,6 +84,27 @@@ } public void resolve(TranslationContext context) { + boolean failedIncludes = false; + for(IncludeStatement include : includes) { + try { + include.ruleset = context.resolveRuleset(include.name.text); + if(include.ruleset == null) { + failedIncludes = true; + context.getErrorLog().log(include.name.location, "Couldn't resolve ruleset " + include.name + "."); + continue; + } + include.value = include.value.resolve(context); + for(CHRConstraint constraint : include.ruleset.constraints) { + context.newCHRConstraint(constraint.name, constraint); + constraintSourceMap.put(constraint, include); + } + } catch (AmbiguousNameException e) { + failedIncludes = true; + context.getErrorLog().log(include.name.location, e.getMessage()); + } + } + if(failedIncludes) + return; for(CHRConstraint constraint : constraints) context.newCHRConstraint(constraint.name, constraint); priorityCount = 0; @@@ -118,36 -81,26 +118,36 @@@ } 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); for(CHRRule rule : rules) rule.checkType(context); } public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { + for(IncludeStatement include : includes) + include.value.collectVars(allVars, vars); for(CHRRule rule : rules) 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); } @@@ -159,166 -112,77 +159,167 @@@ rule.setLocationDeep(loc); } } + + public int getMinimumPriority(CHRConstraint constraint) { + CHRConstraintGGInfo info = activeConstraintGGInfo.get(constraint); + if(info == null) + return Integer.MAX_VALUE; + else + return info.minimumPriority; + } + + public int getAndUpdateNextPriority(CHRConstraint constraint, int nextPriority) { + CHRConstraintGGInfo info = activeConstraintGGInfo.get(constraint); + if(info == null) + return Integer.MAX_VALUE; + else { + int result = info.nextPriority; + info.nextPriority = nextPriority; + return result; + } + } public void compile(SimplificationContext context) { initializeCodeGeneration(context.getCompilationContext()); + if(extensible) + applyExtensibleDefaults(); UsageAnalysis.analyzeUsage(this); - for(CHRRule rule : rules) + 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); + } + } + } + } // remove init constraint if it is not useful - if(initConstraint.plans.isEmpty()) { + if(getMinimumPriority(initConstraint) == Integer.MAX_VALUE) { constraints.remove(0); initConstraint = null; } + } + + private void applyExtensibleDefaults() { for(CHRConstraint constraint : constraints) { - constraint.plans.sort((PrioritizedPlan a, PrioritizedPlan b) -> { - return Integer.compare(a.priority, b.priority); - }); - /*System.out.println(constraint.name); - for(PrioritizedPlan plan : constraint.plans) { - System.out.println(" priority " + plan.priority); - for(PlanOp op : plan.ops) - System.out.println(" " + op); - }*/ + // FIXME Too much indexing!!! + int max = 1 << constraint.parameterTypes.length; + for(int i=0;i 0) + constraint.getOrCreateIndex(cachedContext, 1);*/ } } public void simplify(SimplificationContext context) { + for(IncludeStatement include : includes) + include.value = include.value.simplify(context); for(CHRRule rule : rules) rule.simplify(context); } + public void setRulesetType(TCon type, String className) { + this.runtimeRulesetType = type; + this.runtimeRulesetClassName = className; + } + public void initializeCodeGeneration(CompilationContext context) { cachedContext = context; // FIXME remove - String suffix = context.namingPolicy.getFreshClosureClassNameSuffix(); - storeType = Types.con(context.namingPolicy.getModuleName(), "CHR" + suffix); - storeClassName = context.namingPolicy.getModuleClassName() + suffix; - storeTypeDesc = TypeDesc.forClass(storeClassName); - storeVariable = new BoundVar(storeType); + boolean createTypeDesc = false; + if(runtimeRulesetType == null) { + String suffix = context.namingPolicy.getFreshClosureClassNameSuffix(); + setRulesetType(Types.con(context.namingPolicy.getModuleName(), "CHR" + suffix), context.namingPolicy.getModuleClassName() + suffix); + createTypeDesc = true; + } + runtimeRulesetTypeDesc = TypeDesc.forClass(runtimeRulesetClassName); + runtimeRulesetVariable = new BoundVar(runtimeRulesetType); for(CHRConstraint constraint : constraints) constraint.initializeCodeGeneration(context, this); - activateProcedure = new JavaMethod(true, storeClassName, "activate", Types.PROC, Types.UNIT, storeType, Types.INTEGER); - readCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.INTEGER, new Type[] {storeType}, - null, new FieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null); - writeCurrentId = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {storeType, Types.INTEGER}, - null, new SetFieldRef(storeClassName, "currentId", CHRCodeGenerator.FACT_ID_TYPE), null); - if(context.module != null) // for unit testing - context.module.addTypeDescriptor(storeType.name, new StandardTypeConstructor(storeType, TVar.EMPTY_ARRAY, storeTypeDesc)); + 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)); } + + public static final Constant ACTIVATE = new JavaMethod(true, CHRCodeGenerationConstants.CHRContext_name, "activate", Types.PROC, Types.UNIT, Types.CHRContext, Types.INTEGER); + private static final Constant CREATE_CHR_CONTEXT = new JavaConstructor("org/simantics/scl/runtime/chr/CHRContext", Types.PROC, Types.CHRContext); - public void generateCode(CodeWriter w) { - CHRRulesetObject object = new CHRRulesetObject(storeVariable, this); + public IVal generateCode(CodeWriter w) { + for(IncludeStatement include : includes) { + include.storeVar = include.value.toVal(cachedContext.environment, w); + initialPriorityNumber = Math.max(initialPriorityNumber, include.ruleset.initialPriorityNumber + include.ruleset.priorityCount); + } + CHRRulesetObject object = new CHRRulesetObject(runtimeRulesetVariable, this); w.defineObject(object); - for(CHRConstraint constraint : constraints) { - //System.out.println(constraint); - for(PrioritizedPlan plan : constraint.plans) { + for(CHRRule rule : rules) { + for(CHRSearchPlan plan : rule.plans) { /*System.out.println(" plan " + plan.priority); for(PlanOp planOp : plan.ops) System.out.println(" " + planOp);*/ - PlanRealizer realizer = new PlanRealizer(cachedContext, this, storeVariable, plan.ops); - CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.BOOLEAN, new Type[] {constraint.factType}); + CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.BOOLEAN, new Type[] {Types.CHRContext, plan.constraint.factType}); plan.implementation = methodWriter.getFunction(); - plan.activeFact.setVal(methodWriter.getParameters()[0]); + IVal[] implementationParameters = methodWriter.getParameters(); + plan.activeFact.setVal(implementationParameters[1]); + PlanRealizer realizer = new PlanRealizer(cachedContext, this, runtimeRulesetVariable, implementationParameters[0], plan.ops); realizer.nextOp(methodWriter); if(methodWriter.isUnfinished()) methodWriter.return_(BooleanConstant.TRUE); } } + if(!includes.isEmpty()) { + { + CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext}); + initializer = methodWriter.getFunction(); + for(IncludeStatement include : includes) { + methodWriter.apply(include.location, + 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); + } + { + CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext}); + deinitializer = methodWriter.getFunction(); + for(IncludeStatement include : includes) { + methodWriter.apply(include.location, + 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(initConstraint != null) { + IVal chrContext = w.apply(location, CREATE_CHR_CONTEXT); + if(initializer != null) { + w.apply(location, + 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); - w.apply(location, initConstraint.addProcedure, storeVariable, initFact); - w.apply(location, activateProcedure, storeVariable, new IntegerConstant(Integer.MAX_VALUE)); + w.apply(location, initConstraint.addProcedure, runtimeRulesetVariable, chrContext, initFact); + w.apply(location, ACTIVATE, chrContext, new IntegerConstant(Integer.MAX_VALUE)); + if(deinitializer != null) { + w.apply(location, + new JavaMethod(true, runtimeRulesetClassName, "deinitialize", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), + object.getTarget(), chrContext); + } } + return runtimeRulesetVariable; } public void collectEffects(THashSet effects) { diff --combined bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAFunction.java index ab643f9a1,ab643f9a1..b9e8bfbb3 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAFunction.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAFunction.java @@@ -359,6 -359,6 +359,8 @@@ public final class SSAFunction extends } public void mergeBlocks(SSAFunction function) { ++ if(this == function) ++ throw new InternalCompilerError(); SSABlock block = function.firstBlock; while(block != null) { SSABlock next = block.next; diff --combined bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java index 6d139a4d6,b8b7def59..400cb6e4e --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java @@@ -77,7 -77,7 +77,7 @@@ public class LetApply extends LetStatem @Override public void toString(PrintingContext context) { - if(determineGenerateOnFly()) + if(/*target.getLabel() == null &&*/ determineGenerateOnFly()) context.addInlineExpression(target, this); else toStringAux(context); @@@ -399,7 -399,7 +399,7 @@@ tailBlock.setExit(headBlock.getExit()); // Merge blocks -- thisFunction.mergeBlocks(function); ++ thisFunction.mergeBlocks(function); headBlock.setExit(new Jump(function.getFirstBlock().createOccurrence(), parameters)); diff --combined bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/info/SCLInfo.java index 33b5fc7e9,63b2338f4..c37a9421f --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/info/SCLInfo.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/info/SCLInfo.java @@@ -3,8 -3,6 +3,8 @@@ package org.simantics.scl.ui.info public class SCLInfo { public static String[] RESERVED_WORDS = new String[] { + "module", + "data", "type", "effect", @@@ -35,7 -33,6 +35,8 @@@ "as", "forall", "rule", + "ruleset", ++ "constraint", "extends", "by", "select", diff --combined tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java index 1c0100425,5bd0c85d7..769a1bde9 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java @@@ -26,8 -26,6 +26,8 @@@ public class ModuleRegressionTests exte @Test public void CHR2() { test(); } @Test public void CHR3() { test(); } @Test public void CHR4() { test(); } + @Test public void CHR5() { test(); } + @Test public void CHR6() { test(); } @Test public void ClosureRecursion() { test(); } @Test public void Collaz() { test(); } @Test public void Compose() { test(); } @@@ -140,6 -138,7 +140,7 @@@ @Test public void LocalDefinitions4() { test(); } @Test public void LocalDefinitions5() { test(); } @Test public void Logger() { test(); } + @Test public void LP() { test(); } @Test public void Macros1() { test(); } @Test public void Macros2() { test(); } @Test public void Macros4() { test(); } @@@ -223,6 -222,7 +224,7 @@@ @Test public void SinConst1() { test(); } @Test public void Sort() { test(); } @Test public void Sort2() { test(); } + @Test public void SpecConstr1() { test(); } @Test public void SSATypingBug() { test(); } @Test public void StreamFusion() { test(); } @Test public void StringEscape() { test(); }