package org.simantics.scl.compiler.internal.elaboration.constraints;
-import org.cojen.classfile.TypeDesc;
+import java.util.ArrayList;
+
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.ClassConstant;
-import org.simantics.scl.compiler.constants.JavaConstructor;
-import org.simantics.scl.compiler.constants.JavaStaticField;
-import org.simantics.scl.compiler.constants.JavaStaticMethod;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EConstant;
}
return result;
}
-
- private static final Type SERIALIZABLE_BOOLEAN = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN);
- private static final Type SERIALIZABLE_BYTE = Types.pred(Types.SERIALIZABLE, Types.BYTE);
- private static final Type SERIALIZABLE_SHORT = Types.pred(Types.SERIALIZABLE, Types.SHORT);
- private static final Type SERIALIZABLE_INTEGER = Types.pred(Types.SERIALIZABLE, Types.INTEGER);
- private static final Type SERIALIZABLE_LONG = Types.pred(Types.SERIALIZABLE, Types.LONG);
- private static final Type SERIALIZABLE_FLOAT = Types.pred(Types.SERIALIZABLE, Types.FLOAT);
- private static final Type SERIALIZABLE_DOUBLE = Types.pred(Types.SERIALIZABLE, Types.DOUBLE);
- private static final Type SERIALIZABLE_STRING = Types.pred(Types.SERIALIZABLE, Types.STRING);
-
- private static final Type SERIALIZABLE_BOOLEAN_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN_ARRAY);
- private static final Type SERIALIZABLE_BYTE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BYTE_ARRAY);
- private static final Type SERIALIZABLE_SHORT_ARRAY = Types.pred(Types.SERIALIZABLE, Types.SHORT_ARRAY);
- private static final Type SERIALIZABLE_INTEGER_ARRAY = Types.pred(Types.SERIALIZABLE, Types.INTEGER_ARRAY);
- private static final Type SERIALIZABLE_LONG_ARRAY = Types.pred(Types.SERIALIZABLE, Types.LONG_ARRAY);
- private static final Type SERIALIZABLE_FLOAT_ARRAY = Types.pred(Types.SERIALIZABLE, Types.FLOAT_ARRAY);
- private static final Type SERIALIZABLE_DOUBLE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.DOUBLE_ARRAY);
-
- private static final Type SERIALIZABLE_BOOLEAN_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BOOLEAN));
- private static final Type SERIALIZABLE_BYTE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BYTE));
- private static final Type SERIALIZABLE_SHORT_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.SHORT));
- private static final Type SERIALIZABLE_INTEGER_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.INTEGER));
- private static final Type SERIALIZABLE_LONG_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.LONG));
- private static final Type SERIALIZABLE_FLOAT_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.FLOAT));
- private static final Type SERIALIZABLE_DOUBLE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.DOUBLE));
-
- private static final Type SERIALIZABLE_TUPLE0 = Types.pred(Types.SERIALIZABLE, Types.tuple());
- private static final Type SERIALIZABLE_VARIANT = Types.pred(Types.SERIALIZABLE, Types.VARIANT);
-
+
public Reduction reduce(TPred constraint) {
// VecComp
if(constraint.typeClass == Types.VEC_COMP) {
Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
}
// Serializable
- if(constraint.typeClass == Types.SERIALIZABLE) {
- Type parameter = Types.canonical(constraint.parameters[0]);
- if(parameter instanceof TCon) {
- TCon con = (TCon)parameter;
- if(con == Types.DOUBLE)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/DoubleBinding"), SERIALIZABLE_DOUBLE, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.STRING)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "STRING", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/StringBinding"), SERIALIZABLE_STRING, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.INTEGER)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/IntegerBinding"), SERIALIZABLE_INTEGER, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.BOOLEAN)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/BooleanBinding"), SERIALIZABLE_BOOLEAN, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.BYTE)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BYTE", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ByteBinding"), SERIALIZABLE_BYTE, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.FLOAT)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/FloatBinding"), SERIALIZABLE_FLOAT, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.LONG)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "LONG", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/LongBinding"), SERIALIZABLE_LONG, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.tupleConstructor(0))
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "VOID", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/Binding"), SERIALIZABLE_TUPLE0, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.VARIANT)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "VARIANT", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/VariantBinding"), SERIALIZABLE_VARIANT, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.DOUBLE_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_DOUBLE_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.INTEGER_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_INTEGER_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.BOOLEAN_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BOOLEAN_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.BYTE_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BYTE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BYTE_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.FLOAT_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_FLOAT_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(con == Types.LONG_ARRAY)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "LONG_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_LONG_ARRAY, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- }
- else if(parameter instanceof TApply) {
- TApply apply1 = (TApply)parameter;
- Type f1 = Types.canonical(apply1.function);
- Type p1 = Types.canonical(apply1.parameter);
- if(f1 instanceof TCon) {
- TCon con = (TCon)f1;
- if(con == Types.LIST)
- return new Reduction(
- new ELiteral(new JavaConstructor("org/simantics/databoard/binding/impl/ArrayListBinding", Types.NO_EFFECTS,
- Types.pred(Types.SERIALIZABLE, Types.list(p1)), Types.pred(Types.SERIALIZABLE, p1))),
- Type.EMPTY_ARRAY, new TPred[] { Types.pred(Types.SERIALIZABLE, p1) });
- else if(con == Types.MAYBE)
- return new Reduction(
- new ELiteral(new JavaConstructor("org/simantics/databoard/binding/impl/OptionalBindingDefault", Types.NO_EFFECTS,
- Types.pred(Types.SERIALIZABLE, Types.apply(Types.MAYBE, p1)), Types.pred(Types.SERIALIZABLE, p1))),
- Type.EMPTY_ARRAY, new TPred[] { Types.pred(Types.SERIALIZABLE, p1) });
- else if(con == Types.VECTOR) {
- if (p1 == Types.DOUBLE)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_DOUBLE_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(p1 == Types.INTEGER)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_INTEGER_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(p1 == Types.BOOLEAN)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BOOLEAN_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(p1 == Types.BYTE)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "BYTE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BYTE_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(p1 == Types.FLOAT)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_FLOAT_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else if(p1 == Types.LONG)
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "LONG_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_LONG_VECTOR, -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- else
- return new Reduction(
- new ELiteral(new JavaStaticMethod("org/simantics/databoard/Bindings", "getArrayBinding", Types.NO_EFFECTS,
- Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, p1)), Types.pred(Types.SERIALIZABLE, p1))),
- Type.EMPTY_ARRAY, new TPred[] { Types.pred(Types.SERIALIZABLE, p1) });
- }
- }
- else if(f1 instanceof TApply) {
- TApply apply2 = (TApply)parameter;
- Type f2 = Types.canonical(apply2.function);
- Type p2 = Types.canonical(apply2.parameter);
- if(f2 instanceof TCon) {
- TCon con = (TCon)f2;
- /*if(con == Types.tupleConstructor(2)) {
- return new Reduction(
- new EConstant(Builtins.TUPLE_CONSTRUCTORS[2]new JavaConstructor("org/simantics/databoard/binding/impl/ArrayListBinding", Types.NO_EFFECTS,
- Types.pred(Types.SERIALIZABLE, p1), Types.pred(Types.SERIALIZABLE, Types.list(p1)))),
- Type.EMPTY_ARRAY,
- new TPred[] { Types.pred(Types.SERIALIZABLE, p2), Types.pred(Types.SERIALIZABLE, p1) });
- }*/
- }
- }
- }
-
- // Default to a binding as an ObjectVariantBinding
- // This can be applied only if the type is ground type (i.e. does not contain type variables),
- // because otherwise the Serializable instance could be provided as a parameter to the function
- if(parameter.isGround())
- return new Reduction(
- new ELiteral(new JavaStaticField("org/simantics/databoard/Bindings", "OBJECT", Types.NO_EFFECTS,
- TypeDesc.forClass("org/simantics/databoard/binding/VariantBinding"), Types.pred(Types.SERIALIZABLE, parameter), -1)),
- Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
- }
+ if(constraint.typeClass == Types.SERIALIZABLE)
+ return ReduceSerializable.reduceSerializable(constraint.parameters[0]);
// Typeable
else if(constraint.typeClass == Types.TYPEABLE) {
else if(parameter instanceof TUnion) {
TUnion union = (TUnion)parameter;
- /*TPred[] demands = new TPred[union.effects.length];
- for(int i=0;i<union.effects.length;++i)
- demands[i] = Types.pred(Types.TYPEABLE, union.effects[i]);*/
if(union.effects.length == 0)
- return new Reduction(
+ return new Reduction(
new EConstant(Builtins.INSTANCE.getValue("TPure")),
Type.EMPTY_ARRAY,
TPred.EMPTY_ARRAY);
+ else if(union.effects.length == 2) {
+ return new Reduction(
+ new EConstant(Builtins.INSTANCE.getValue("TUnion2")),
+ Type.EMPTY_ARRAY, new TPred[] {
+ Types.pred(Types.TYPEABLE, union.effects[0]),
+ Types.pred(Types.TYPEABLE, union.effects[1])
+ });
+ }
}
}
// Standard case
- THashMap<TVar, Type> substitution = new THashMap<TVar, Type>();
+ THashMap<TVar, Type> substitution = new THashMap<TVar, Type>();
+ ArrayList<Reduction> reductions = new ArrayList<Reduction>(1);
for(TypeClassInstance inst : environment.getInstances(constraint.typeClass)) {
if(Types.match(inst.instance, constraint, substitution)) {
TPred[] demands = new TPred[inst.context.length];
parameter = inst.generatorParameters[i]; // TODO Is this correct?
parameters[i] = parameter;
}
- return new Reduction(new ELiteral(inst.generator), parameters, demands);
+ reductions.add(new Reduction(new ELiteral(inst.generator), parameters, demands));
}
- else
- substitution.clear();
+ substitution.clear();
+ }
+ //System.out.println(constraint.typeClass + " -> " + reductions.size());
+ if(reductions.size() == 1)
+ return reductions.get(0);
+ else if(reductions.size() > 1) {
+ throw new InternalCompilerError("Found more than one matching instances for " + constraint.typeClass + ".");
}
return null;
}