]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/OrdDeriver.java
Added info on backup location to documentation backup.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / deriving / OrdDeriver.java
1 package org.simantics.scl.compiler.internal.deriving;
2
3 import java.util.ArrayList;
4
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;
25
26 class OrdDeriver implements InstanceDeriver {
27
28     @Override
29     public void derive(
30             ErrorLog errorLog,
31             Environment environment,
32             ArrayList<ProcessedDInstanceAst> instancesAst,
33             DDerivingInstanceAst der) {
34      // Analyze
35         if(der.types.length != 1) {
36             errorLog.log(der.location, "Invalid number of parameters to " + der.name);
37             return;
38         }
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 + ".");
42             return;
43         }
44         TCon con;
45         try {
46             con = Environments.getTypeConstructorName(environment, headType.name);
47         } catch (AmbiguousNameException e1) {
48             errorLog.log(headType.location, e1.getMessage());
49             return;
50         }
51         if(con == null) {
52             errorLog.log(headType.location, "Couldn't resolve " + headType.name);
53             return;
54         }
55         TypeConstructor tcon = environment.getTypeConstructor(con);
56         if(tcon == null) {
57             errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
58             return;
59         }
60         if(tcon.isOpen) {
61             errorLog.log(headType.location, "Cannot derive instance for open data types.");
62             return;
63         }
64         
65         // Generate
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) {
74                 parA[i] = "a" + i;
75             }
76             for(int b=0;b<cCount;++b) {
77                 if(a != 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) {
82                         parB[i] = "b" + i;
83                     }
84                     Expression lhs = new EApply(
85                             new EVar("compare"),
86                             new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
87                             new EApply(new EVar(consB.name.name), Expressions.vars(parB))
88                             );
89                     Expression value = new ELiteral(a < b ? IntegerConstant.MINUS_ONE : IntegerConstant.ONE);
90                     try {
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.");
98                     }
99                 }
100                 else {
101                     String[] parB = new String[lA];            
102                     for(int i=0;i<lA;++i) {
103                         parB[i] = "b" + i;
104                     }
105                     Expression lhs = new EApply(
106                             new EVar("compare"),
107                             new EApply(new EVar(consA.name.name), Expressions.vars(parA)),
108                             new EApply(new EVar(consA.name.name), Expressions.vars(parB))
109                             );
110                     Expression value = new ELiteral(IntegerConstant.ZERO);
111                     for(int i=lA-1;i>=0;--i)
112                         value = new EApply(
113                                 new EVar("&<&"),
114                                 new EApply(
115                                         new EVar("compare"), 
116                                         new EVar(parA[i]), 
117                                         new EVar(parB[i])),
118                                 value);
119                     try {
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.");
127                     }
128                 }
129             }
130         }
131         instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));
132     }
133
134 }