1 package org.simantics.scl.compiler.internal.elaboration.constraints;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.constants.ClassConstant;
5 import org.simantics.scl.compiler.constants.StringConstant;
6 import org.simantics.scl.compiler.elaboration.expressions.EApply;
7 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
8 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
9 import org.simantics.scl.compiler.elaboration.java.Builtins;
10 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
11 import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
12 import org.simantics.scl.compiler.environment.Environment;
13 import org.simantics.scl.compiler.errors.Locations;
14 import org.simantics.scl.compiler.types.TApply;
15 import org.simantics.scl.compiler.types.TCon;
16 import org.simantics.scl.compiler.types.TFun;
17 import org.simantics.scl.compiler.types.TPred;
18 import org.simantics.scl.compiler.types.TUnion;
19 import org.simantics.scl.compiler.types.TVar;
20 import org.simantics.scl.compiler.types.Type;
21 import org.simantics.scl.compiler.types.Types;
23 import gnu.trove.map.hash.THashMap;
25 public class ConstraintEnvironment {
26 Environment environment;
28 public ConstraintEnvironment(Environment environment) {
29 this.environment = environment;
32 public Superconstraint[] getSuperconstraints(TPred constraint) {
33 TypeClass tc = environment.getTypeClass(constraint.typeClass);
35 throw new InternalCompilerError("Didn't find constraint " + constraint + ". Maybe Prelude is not loaded?");
37 if(tc.context.length == 0)
38 return Superconstraint.EMPTY_ARRAY;
39 Superconstraint[] result = new Superconstraint[tc.context.length];
40 for(int i=0;i<result.length;++i) {
41 result[i] = new Superconstraint(
42 (TPred)tc.context[i].replace(tc.parameters, constraint.parameters),
49 public Reduction reduce(TPred constraint) {
51 if(constraint.typeClass == Types.VEC_COMP) {
52 Type parameter = Types.canonical(constraint.parameters[0]);
53 if(parameter.isGround())
54 return new Reduction(new ELiteral(new ClassConstant(Types.pred(Types.VEC_COMP, parameter), parameter)),
55 Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
58 if(constraint.typeClass == Types.SERIALIZABLE)
59 return ReduceSerializable.reduceSerializable(constraint.parameters[0]);
62 else if(constraint.typeClass == Types.TYPEABLE) {
63 Type parameter = Types.canonical(constraint.parameters[0]);
64 if(parameter instanceof TCon) {
65 TCon con = (TCon)parameter;
67 new EApply(Locations.NO_LOCATION,
68 new EConstant(Builtins.INSTANCE.getValue("TCon")),
69 new ELiteral(new StringConstant(con.module)),
70 new ELiteral(new StringConstant(con.name))),
71 Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
73 else if(parameter instanceof TApply) {
74 TApply apply = (TApply)parameter;
76 new EConstant(Builtins.INSTANCE.getValue("TApply")),
77 Type.EMPTY_ARRAY, new TPred[] {
78 Types.pred(Types.TYPEABLE, apply.function),
79 Types.pred(Types.TYPEABLE, apply.parameter),
82 else if(parameter instanceof TFun) {
83 TFun fun = (TFun)parameter;
85 new EConstant(Builtins.INSTANCE.getValue("TFun")),
86 Type.EMPTY_ARRAY, new TPred[] {
87 Types.pred(Types.TYPEABLE, fun.domain),
88 Types.pred(Types.TYPEABLE, fun.effect),
89 Types.pred(Types.TYPEABLE, fun.range)
92 else if(parameter instanceof TUnion) {
93 TUnion union = (TUnion)parameter;
95 /*TPred[] demands = new TPred[union.effects.length];
96 for(int i=0;i<union.effects.length;++i)
97 demands[i] = Types.pred(Types.TYPEABLE, union.effects[i]);*/
98 if(union.effects.length == 0)
100 new EConstant(Builtins.INSTANCE.getValue("TPure")),
107 THashMap<TVar, Type> substitution = new THashMap<TVar, Type>();
108 for(TypeClassInstance inst : environment.getInstances(constraint.typeClass)) {
109 if(Types.match(inst.instance, constraint, substitution)) {
110 TPred[] demands = new TPred[inst.context.length];
111 for(int i=0;i<demands.length;++i) {
112 demands[i] = (TPred)inst.context[i].replace(substitution);
114 Type[] parameters = new Type[inst.generatorParameters.length];
115 for(int i=0;i<parameters.length;++i) {
116 Type parameter = substitution.get(inst.generatorParameters[i]);
117 if(parameter == null)
118 parameter = inst.generatorParameters[i]; // TODO Is this correct?
119 parameters[i] = parameter;
121 return new Reduction(new ELiteral(inst.generator), parameters, demands);
124 substitution.clear();