]> gerrit.simantics Code Review - simantics/platform.git/blob
afd2a4f8943dfe3d5aa711a611ac3a6827f7eae1
[simantics/platform.git] /
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.constants.StringConstant;
8 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
9 import org.simantics.scl.compiler.elaboration.expressions.EApply;
10 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
11 import org.simantics.scl.compiler.elaboration.expressions.EVar;
12 import org.simantics.scl.compiler.elaboration.expressions.Expression;
13 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
14 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
15 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
16 import org.simantics.scl.compiler.environment.AmbiguousNameException;
17 import org.simantics.scl.compiler.environment.Environment;
18 import org.simantics.scl.compiler.environment.Environments;
19 import org.simantics.scl.compiler.errors.ErrorLog;
20 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
21 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
22 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
23 import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
24 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
25 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
26 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
27 import org.simantics.scl.compiler.types.TCon;
28
29 class ShowDeriver implements InstanceDeriver {
30     
31     private static final IntegerConstant CONST_10 = new IntegerConstant(10);
32
33     @Override
34     public void derive(
35             ErrorLog errorLog,
36             Environment environment,
37             ArrayList<ProcessedDInstanceAst> instancesAst,
38             DDerivingInstanceAst der) {
39      // Analyze
40         if(der.types.length != 1) {
41             errorLog.log(der.location, "Invalid number of parameters to " + der.name);
42             return;
43         }
44         TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
45         if(headType == null) {
46             errorLog.log(der.types[0].location, "Cannot derive Show instance for the type " + headType + ".");
47             return;
48         }
49         TCon con;
50         try {
51             con = Environments.getTypeDescriptorName(environment, headType.name);
52         } catch (AmbiguousNameException e1) {
53             errorLog.log(headType.location, e1.getMessage());
54             return;
55         }
56         if(con == null) {
57             errorLog.log(headType.location, "Couldn't resolve " + headType.name);
58             return;
59         }
60         TypeDescriptor tdesc = environment.getTypeDescriptor(con);
61         if(tdesc == null) {
62             errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
63             return;
64         }
65         if(tdesc instanceof TypeAlias) {
66             errorLog.log(headType.location, "Cannot derive instance for a type alias.");
67             return;
68         }
69         TypeConstructor tcon = (TypeConstructor)tdesc;
70         if(tcon.isOpen) {
71             errorLog.log(headType.location, "Cannot derive instance for open data types.");
72             return;
73         }
74         
75         // Generate
76         DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
77         ValueRepository valueDefs = new ValueRepository();
78         for(Constructor constructor : tcon.constructors) {
79             int l = constructor.parameterTypes.length;
80             String[] par = new String[l];
81             for(int i=0;i<l;++i) {
82                 par[i] = "v" + i;
83             }
84             Expression lhs = new EApply(
85                     new EVar("<+"),
86                     new EVar("sb"),
87                     new EApply(new EVar(constructor.name.name), Expressions.vars(par))
88                     );
89             Expression value;
90             value = new EApply(new EVar("<<"), new EVar("sb"),
91                     new ELiteral(new StringConstant(constructor.name.name)));
92             for(int i=0;i<l;++i) {
93                 value = new EApply(new EVar("<<"),
94                         value,
95                         new ELiteral(new StringConstant(" "))
96                         );
97                 value = new EApply(new EVar("<+"),
98                         value,
99                         new EApply(new EVar("Par"), new ELiteral(CONST_10), new EVar("v" + i))
100                         );
101             }
102
103             try {
104                 DValueAst valueAst = new DValueAst(lhs, value);
105                 valueAst.setLocationDeep(der.location);
106                 valueDefs.add(valueAst);
107                 /*valueDefs.addAnnotation("<+", new DAnnotationAst(new EVar("@private"), 
108                         Collections.<Expression>emptyList()));*/
109             } catch (NotPatternException e) {
110                 errorLog.log(e.getExpression().location, "Not a pattern.");
111             }
112         }
113         instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));
114     }
115
116 }