1 package org.simantics.scl.compiler.internal.deriving;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.common.datatypes.Constructor;
6 import org.simantics.scl.compiler.constants.IntegerConstant;
7 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
8 import org.simantics.scl.compiler.elaboration.expressions.EApply;
9 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
10 import org.simantics.scl.compiler.elaboration.expressions.EVar;
11 import org.simantics.scl.compiler.elaboration.expressions.Expression;
12 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
13 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
14 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
15 import org.simantics.scl.compiler.environment.AmbiguousNameException;
16 import org.simantics.scl.compiler.environment.Environment;
17 import org.simantics.scl.compiler.environment.Environments;
18 import org.simantics.scl.compiler.errors.ErrorLog;
19 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
20 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
21 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
22 import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
23 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
24 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
25 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
26 import org.simantics.scl.compiler.types.TCon;
28 class OrdDeriver implements InstanceDeriver {
33 Environment environment,
34 ArrayList<ProcessedDInstanceAst> instancesAst,
35 DDerivingInstanceAst der) {
37 if(der.types.length != 1) {
38 errorLog.log(der.location, "Invalid number of parameters to " + der.name);
41 TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
42 if(headType == null) {
43 errorLog.log(der.types[0].location, "Cannot derive Ord instance for the type " + headType + ".");
48 con = Environments.getTypeDescriptorName(environment, headType.name);
49 } catch (AmbiguousNameException e1) {
50 errorLog.log(headType.location, e1.getMessage());
54 errorLog.log(headType.location, "Couldn't resolve " + headType.name);
57 TypeDescriptor tdesc = environment.getTypeDescriptor(con);
59 errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
62 if(tdesc instanceof TypeAlias) {
63 errorLog.log(headType.location, "Cannot derive instance for a type alias.");
66 TypeConstructor tcon = (TypeConstructor)tdesc;
68 errorLog.log(headType.location, "Cannot derive instance for open data types.");
73 DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
74 ValueRepository valueDefs = new ValueRepository();
75 int cCount = tcon.constructors.length;
76 for(int a=0;a<cCount;++a) {
77 Constructor consA = tcon.constructors[a];
78 int lA = consA.parameterTypes.length;
79 String[] parA = new String[lA];
80 for(int i=0;i<lA;++i) {
83 for(int b=0;b<cCount;++b) {
85 Constructor consB = tcon.constructors[b];
86 int lB = consB.parameterTypes.length;
87 String[] parB = new String[lB];
88 for(int i=0;i<lB;++i) {
91 Expression lhs = new EApply(
93 new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
94 new EApply(new EVar(consB.name.name), Expressions.vars(parB))
96 Expression value = new ELiteral(a < b ? IntegerConstant.MINUS_ONE : IntegerConstant.ONE);
98 DValueAst valueAst = new DValueAst(lhs, value);
99 valueAst.setLocationDeep(der.location);
100 valueDefs.add(valueAst);
101 /*valueDefs.addAnnotation("compare", new DAnnotationAst(new EVar("@private"),
102 Collections.<Expression>emptyList()));*/
103 } catch (NotPatternException e) {
104 errorLog.log(e.getExpression().location, "Not a pattern.");
108 String[] parB = new String[lA];
109 for(int i=0;i<lA;++i) {
112 Expression lhs = new EApply(
114 new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
115 new EApply(new EVar(consA.name.name), Expressions.vars(parB))
117 Expression value = new ELiteral(IntegerConstant.ZERO);
118 for(int i=lA-1;i>=0;--i)
127 DValueAst valueAst = new DValueAst(lhs, value);
128 valueAst.setLocationDeep(der.location);
129 valueDefs.add(valueAst);
130 /*valueDefs.addAnnotation("&<&", new DAnnotationAst(new EVar("@private"),
131 Collections.<Expression>emptyList()));*/
132 } catch (NotPatternException e) {
133 errorLog.log(e.getExpression().location, "Not a pattern.");
138 instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));