From cde82ba81327d5515fdca362f7f4c70f5103ae80 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Thu, 19 Jan 2017 13:05:19 +0200 Subject: [PATCH] Support for () type in CHR relations refs #6901 Change-Id: I95e8e71a30a5fee500a66c95a39ddc3ec9907692 --- .../scl/compiler/constants/NoRepConstant.java | 1 + .../elaboration/chr/plan/AccessFactOp.java | 2 +- .../chr/plan/IterateConstraintOp.java | 2 +- .../chr/relations/CHRConstraint.java | 42 +++++++++---- .../codegen/chr/CHRCodeGenerator.java | 62 +++++++++++++------ .../internal/codegen/utils/ClassBuilder.java | 11 ++++ .../codegen/utils/MethodBuilderBase.java | 10 +++ .../simantics/scl/compiler/tests/scl/CHR4.scl | 14 +++++ 8 files changed, 113 insertions(+), 31 deletions(-) diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/NoRepConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/NoRepConstant.java index c9cbb8153..abe5ea81f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/NoRepConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/NoRepConstant.java @@ -11,6 +11,7 @@ import org.simantics.scl.runtime.tuple.Tuple0; public class NoRepConstant extends Constant { public static final NoRepConstant PUNIT = new NoRepConstant(Types.PUNIT); + public static final NoRepConstant UNIT = new NoRepConstant(Types.UNIT); public NoRepConstant(Type type) { super(type); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java index 3ebbb03cf..d2379d7c0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java @@ -39,7 +39,7 @@ public class AccessFactOp extends PlanOp { public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) { IVal inputVal = inputFact.toVal(context.environment, w); for(int i=0;i>i)&1)==0) - variables[i].setVal(body.apply(location, constraint.accessComponent(i), fact)); + variables[i].setVal(constraint.accessComponent(location, body, fact, i)); Constant nextElement = constraint.nextElement(context, boundMask); planContext.partnerFacts.add(new PartnerFact(false, id, constraint, fact, constraint.mayBeRemoved(), killAfterMatch, nextElement, bodyContinuation, end.getContinuation())); planContext.nextOp(body); 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 7a0e27ba2..4a75a5604 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 @@ -6,9 +6,10 @@ 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.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; @@ -20,6 +21,7 @@ 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.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; @@ -91,15 +93,30 @@ public class CHRConstraint extends Symbol implements CHRRelation { Type[] constructorTypes = new Type[parameterTypes.length+1]; constructorTypes[0] = Types.INTEGER; - for(int i=0;i stackItems = new ArrayList(constructorTypes.length); + stackItems.add(new ParameterStackItem(0, Types.INTEGER)); + for(int i=0;i>i)&1)==1) { - mb.loadLocal(tempFactVar); - mb.loadLocal(mb.getParameter(parameterId++)); - mb.storeField(factClassName, "c"+i, parameterTypeDescs[i]); + TypeDesc typeDesc = parameterTypeDescs[i]; + if(!typeDesc.equals(TypeDesc.VOID)) { + mb.loadLocal(tempFactVar); + mb.loadLocal(mb.getParameter(parameterId)); + mb.storeField(factClassName, fieldName(i), typeDesc); + } + ++parameterId; } mb.loadThis(); @@ -521,20 +537,26 @@ public class CHRCodeGenerator { // this.c1 = c1; // } - TypeDesc[] constructorParameters = new TypeDesc[parameterTypeDescs.length+1]; - constructorParameters[0] = FACT_ID_TYPE; - for(int i=0;i constructorParameters = new ArrayList(parameterTypeDescs.length+1); + constructorParameters.add(FACT_ID_TYPE); + for(TypeDesc typeDesc : parameterTypeDescs) { + if(typeDesc.equals(TypeDesc.VOID)) + continue; + constructorParameters.add(typeDesc); + } + MethodBuilderBase mb = factClassBuilder.addConstructor(Opcodes.ACC_PUBLIC, constructorParameters.toArray(new TypeDesc[constructorParameters.size()])); mb.loadThis(); mb.invokeConstructor(factClassBuilder.getSuperClassName(), Constants.EMPTY_TYPEDESC_ARRAY); mb.loadThis(); mb.loadLocal(mb.getParameter(0)); mb.storeField(factClassName, "id", FACT_ID_TYPE); - for(int i=0;i", MethodDesc.forArguments(TypeDesc.VOID, params).getDescriptor(), false); } @@ -417,6 +420,7 @@ public class MethodBuilderBase { public void invokeStatic(String className, String methodName, TypeDesc ret, TypeDesc[] params) { checkClassName(className); + checkParameters(params); methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, className, methodName, MethodDesc.forArguments(ret, params).getDescriptor(), false); } @@ -606,4 +610,10 @@ public class MethodBuilderBase { else methodVisitor.visitLookupSwitchInsn(defaultLabel, values, labels); } + + private static void checkParameters(TypeDesc[] params) { + for(TypeDesc param : params) + if(param.equals(TypeDesc.VOID)) + throw new IllegalArgumentException(); + } } diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR4.scl index a2abc6eb5..dc0714973 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR4.scl +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR4.scl @@ -4,3 +4,17 @@ main = () then True -- 3:10-3:18: Cannot solve the query. +-- +import "Prelude" + +main = getRef r + where + r = ref 1 + + when True + then Foo () + + when Foo _ + then r := 2 +-- +2 -- 2.47.1