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