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);
public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
IVal inputVal = inputFact.toVal(context.environment, w);
for(int i=0;i<variables.length;++i)
- variables[i].setVal(w.apply(location, constraint.accessComponent(i), inputVal));
+ variables[i].setVal(constraint.accessComponent(location, w, inputVal, i));
IVal activeId = w.apply(location, constraint.accessId, inputVal);
CodeWriter end = constraint.mayBeRemoved() ? w.createBlock() : null;
planContext.partnerFacts.add(new PartnerFact(true, activeId, constraint, inputVal, constraint.mayBeRemoved(), killAfterMatch, null, null, end == null ? null : end.getContinuation()));
for(int i=0;i<variables.length;++i)
if(((boundMask>>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);
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.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;
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);
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);
+ null, new FieldRef(factClassName, CHRCodeGenerator.fieldName(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, indexName + "Next", factTypeDesc), null)
);
}
-
- public Constant accessComponent(int i) {
- return accessors[i];
- }
public IVal fetchFromIndex(CompilationContext context, int boundMask) {
IndexInfo indexInfo = indices.get(boundMask);
public boolean isPassive() {
return plans.isEmpty();
}
-
+
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);
+ }
}
generateFact(storeClassBuilder, constraint, hashIndexInitializations);
// Fields
- for(int i=0;i<ruleset.parameterTypeDescs.length;++i)
- storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "p" + i, ruleset.parameterTypeDescs[i]);
+ for(int i=0;i<ruleset.parameterTypeDescs.length;++i) {
+ TypeDesc typeDesc = ruleset.parameterTypeDescs[i];
+ if(typeDesc.equals(TypeDesc.VOID))
+ continue;
+ storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "p" + i, typeDesc);
+ }
storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE);
for(StoreInitialization ini : hashIndexInitializations)
storeClassBuilder.addField(ini.access, ini.fieldName, ini.fieldType);
mb.loadThis();
mb.invokeConstructor(storeClassBuilder.getSuperClassName(), Constants.EMPTY_TYPEDESC_ARRAY);
for(int i=0;i<ruleset.parameterTypeDescs.length;++i) {
+ TypeDesc typeDesc = ruleset.parameterTypeDescs[i];
+ if(typeDesc.equals(TypeDesc.VOID))
+ continue;
mb.loadThis();
mb.loadLocal(mb.getParameter(i));
mb.storeField(ruleset.storeClassName, "p" + i, ruleset.parameterTypeDescs[i]);
*/
TypeDesc[] parameterTypeDescs = jtt.toTypeDescs(constraint.parameterTypes);
factClassBuilder.addField(Opcodes.ACC_PUBLIC, "id", FACT_ID_TYPE);
- for(int i=0;i<constraint.parameterTypes.length;++i)
- factClassBuilder.addField(Opcodes.ACC_PUBLIC, "c" + i, parameterTypeDescs[i]);
+ for(int i=0;i<constraint.parameterTypes.length;++i) {
+ TypeDesc typeDesc = parameterTypeDescs[i];
+ if(typeDesc.equals(TypeDesc.VOID))
+ continue;
+ if(parameterTypeDescs[i] != TypeDesc.VOID)
+ factClassBuilder.addField(Opcodes.ACC_PUBLIC, fieldName(i), typeDesc);
+ }
for(IndexInfo indexInfo : constraint.getIndices()) {
if(supportsRemoval)
int parameterId=0;
for(int i=0;i<constraint.parameterTypes.length;++i)
if(((indexInfo.indexMask>>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();
// this.c1 = c1;
// }
- TypeDesc[] constructorParameters = new TypeDesc[parameterTypeDescs.length+1];
- constructorParameters[0] = FACT_ID_TYPE;
- for(int i=0;i<parameterTypeDescs.length;++i)
- constructorParameters[i+1] = parameterTypeDescs[i];
- MethodBuilderBase mb = factClassBuilder.addConstructor(Opcodes.ACC_PUBLIC, constructorParameters);
+ ArrayList<TypeDesc> constructorParameters = new ArrayList<TypeDesc>(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<constraint.parameterTypes.length;++i) {
+ for(int i=0,parameterId=1;i<constraint.parameterTypes.length;++i) {
+ TypeDesc typeDesc = parameterTypeDescs[i];
+ if(typeDesc.equals(TypeDesc.VOID))
+ continue;
mb.loadThis();
- mb.loadLocal(mb.getParameter(i+1));
- mb.storeField(factClassName, "c" + i, parameterTypeDescs[i]);
+ mb.loadLocal(mb.getParameter(parameterId++));
+ mb.storeField(factClassName, fieldName(i), typeDesc);
}
mb.returnVoid();
mb.finish();
if(fieldTypeDesc.equals(TypeDesc.VOID))
continue;
mb.loadLocal(aVar);
- mb.loadField(factClassName, "c"+i, fieldTypeDesc);
+ mb.loadField(factClassName, fieldName(i), fieldTypeDesc);
mb.loadLocal(bVar);
- mb.loadField(factClassName, "c"+i, fieldTypeDesc);
+ mb.loadField(factClassName, fieldName(i), fieldTypeDesc);
CodeBuilderUtils.equals(mb, fieldTypeDesc, failure);
}
if(fieldTypeDesc.equals(TypeDesc.VOID))
continue;
mb.loadLocal(factVar);
- mb.loadField(factClassName, "c"+i, fieldTypeDesc);
+ mb.loadField(factClassName, fieldName(i), fieldTypeDesc);
CodeBuilderUtils.hashCode(mb, fieldTypeDesc);
mb.math(Opcodes.IXOR);
mb.loadConstant(16777619);
return hashIndexClassBuilder;
}
+
+ public static String fieldName(int id) {
+ return "c" + id;
+ }
}
String methodName,
TypeDesc ret,
TypeDesc[] params) {
+ for(TypeDesc param : params)
+ if(param.equals(TypeDesc.VOID))
+ throw new IllegalArgumentException();
MethodVisitor methodVisitor = classVisitor.visitMethod(access, methodName,
MethodDesc.forArguments(ret, params).getDescriptor(),
null, null);
String methodName,
TypeDesc ret,
TypeDesc[] params) {
+ for(TypeDesc param : params)
+ if(param.equals(TypeDesc.VOID))
+ throw new IllegalArgumentException();
MethodVisitor methodVisitor = classVisitor.visitMethod(access, methodName,
MethodDesc.forArguments(ret, params).getDescriptor(),
null, null);
String methodName,
TypeDesc ret,
TypeDesc[] params) {
+ for(TypeDesc param : params)
+ if(param.equals(TypeDesc.VOID))
+ throw new IllegalArgumentException();
MethodVisitor methodVisitor = classVisitor.visitMethod(access, methodName,
MethodDesc.forArguments(ret, params).getDescriptor(),
null, null);
public void addField(int access, String fieldName,
TypeDesc type) {
+ if(type.equals(TypeDesc.VOID))
+ throw new IllegalArgumentException();
FieldVisitor fieldVisitor = classVisitor.visitField(access, fieldName, type.getDescriptor(), null, null);
fieldVisitor.visitEnd();
}
public void invokeInterface(String className, String methodName,
TypeDesc ret, TypeDesc[] params) {
checkClassName(className);
+ checkParameters(params);
methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, className, methodName,
MethodDesc.forArguments(ret, params).getDescriptor(), true);
}
public void invokeVirtual(String className, String methodName,
TypeDesc ret, TypeDesc[] params) {
checkClassName(className);
+ checkParameters(params);
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, methodName,
MethodDesc.forArguments(ret, params).getDescriptor(), false);
}
public void invokeConstructor(String className, TypeDesc[] params) {
checkClassName(className);
+ checkParameters(params);
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>",
MethodDesc.forArguments(TypeDesc.VOID, params).getDescriptor(), false);
}
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);
}
else
methodVisitor.visitLookupSwitchInsn(defaultLabel, values, labels);
}
+
+ private static void checkParameters(TypeDesc[] params) {
+ for(TypeDesc param : params)
+ if(param.equals(TypeDesc.VOID))
+ throw new IllegalArgumentException();
+ }
}
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