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.TypeConstructor;
13 import org.simantics.scl.compiler.environment.AmbiguousNameException;
14 import org.simantics.scl.compiler.environment.Environment;
15 import org.simantics.scl.compiler.environment.Environments;
16 import org.simantics.scl.compiler.errors.ErrorLog;
17 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
18 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
19 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
20 import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
21 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
22 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
23 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
24 import org.simantics.scl.compiler.types.TCon;
26 class OrdDeriver implements InstanceDeriver {
31 Environment environment,
32 ArrayList<ProcessedDInstanceAst> instancesAst,
33 DDerivingInstanceAst der) {
35 if(der.types.length != 1) {
36 errorLog.log(der.location, "Invalid number of parameters to " + der.name);
39 TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
40 if(headType == null) {
41 errorLog.log(der.types[0].location, "Cannot derive Ord instance for the type " + headType + ".");
46 con = Environments.getTypeConstructorName(environment, headType.name);
47 } catch (AmbiguousNameException e1) {
48 errorLog.log(headType.location, e1.getMessage());
52 errorLog.log(headType.location, "Couldn't resolve " + headType.name);
55 TypeConstructor tcon = environment.getTypeConstructor(con);
57 errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
61 errorLog.log(headType.location, "Cannot derive instance for open data types.");
66 DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
67 ValueRepository valueDefs = new ValueRepository();
68 int cCount = tcon.constructors.length;
69 for(int a=0;a<cCount;++a) {
70 Constructor consA = tcon.constructors[a];
71 int lA = consA.parameterTypes.length;
72 String[] parA = new String[lA];
73 for(int i=0;i<lA;++i) {
76 for(int b=0;b<cCount;++b) {
78 Constructor consB = tcon.constructors[b];
79 int lB = consB.parameterTypes.length;
80 String[] parB = new String[lB];
81 for(int i=0;i<lB;++i) {
84 Expression lhs = new EApply(
86 new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
87 new EApply(new EVar(consB.name.name), Expressions.vars(parB))
89 Expression value = new ELiteral(a < b ? IntegerConstant.MINUS_ONE : IntegerConstant.ONE);
91 DValueAst valueAst = new DValueAst(lhs, value);
92 valueAst.setLocationDeep(der.location);
93 valueDefs.add(valueAst);
94 /*valueDefs.addAnnotation("compare", new DAnnotationAst(new EVar("@private"),
95 Collections.<Expression>emptyList()));*/
96 } catch (NotPatternException e) {
97 errorLog.log(e.getExpression().location, "Not a pattern.");
101 String[] parB = new String[lA];
102 for(int i=0;i<lA;++i) {
105 Expression lhs = new EApply(
107 new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
108 new EApply(new EVar(consA.name.name), Expressions.vars(parB))
110 Expression value = new ELiteral(IntegerConstant.ZERO);
111 for(int i=lA-1;i>=0;--i)
120 DValueAst valueAst = new DValueAst(lhs, value);
121 valueAst.setLocationDeep(der.location);
122 valueDefs.add(valueAst);
123 /*valueDefs.addAnnotation("&<&", new DAnnotationAst(new EVar("@private"),
124 Collections.<Expression>emptyList()));*/
125 } catch (NotPatternException e) {
126 errorLog.log(e.getExpression().location, "Not a pattern.");
131 instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));