package org.simantics.scl.compiler.internal.elaboration.constraints;
+import java.util.ArrayList;
+
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.compilation.CompilationContext;
import org.simantics.scl.compiler.constants.ClassConstant;
import org.simantics.scl.compiler.constants.StringConstant;
import org.simantics.scl.compiler.elaboration.expressions.EApply;
import gnu.trove.map.hash.THashMap;
public class ConstraintEnvironment {
+ CompilationContext compilationContext;
Environment environment;
- public ConstraintEnvironment(Environment environment) {
- this.environment = environment;
+ public ConstraintEnvironment(CompilationContext compilationContext) {
+ this.compilationContext = compilationContext;
+ this.environment = compilationContext.environment;
}
public Superconstraint[] getSuperconstraints(TPred constraint) {
return result;
}
- public Reduction reduce(TPred constraint) {
+ public Reduction reduce(long location, TPred constraint) {
// VecComp
if(constraint.typeClass == Types.VEC_COMP) {
Type parameter = Types.canonical(constraint.parameters[0]);
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])
+ });
+ }
+ else if(union.effects.length == 3) {
+ return new Reduction(
+ new EConstant(Builtins.INSTANCE.getValue("TUnion3")),
+ Type.EMPTY_ARRAY, new TPred[] {
+ Types.pred(Types.TYPEABLE, union.effects[0]),
+ Types.pred(Types.TYPEABLE, union.effects[1]),
+ Types.pred(Types.TYPEABLE, union.effects[2])
+ });
+ }
}
}
// 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));
+ }
+ substitution.clear();
+ }
+ //System.out.println(constraint.typeClass + " -> " + reductions.size());
+ if(reductions.size() == 1)
+ return reductions.get(0);
+ else if(reductions.size() > 1) {
+ StringBuilder b = new StringBuilder();
+ b.append("Found more than one matching instances for ").append(constraint.typeClass).append(": ");
+ boolean first = true;
+ for(Reduction reduction : reductions) {
+ if(first)
+ first = false;
+ else
+ b.append(", ");
+ b.append(reduction.generator);
}
- else
- substitution.clear();
+ compilationContext.errorLog.log(location, b.toString());
}
return null;
}