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.common.names.Names;
7 import org.simantics.scl.compiler.constants.ByteConstant;
8 import org.simantics.scl.compiler.constants.IntegerConstant;
9 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
10 import org.simantics.scl.compiler.elaboration.expressions.Case;
11 import org.simantics.scl.compiler.elaboration.expressions.EApply;
12 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
13 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
14 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
15 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
16 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
17 import org.simantics.scl.compiler.elaboration.expressions.EVar;
18 import org.simantics.scl.compiler.elaboration.expressions.Expression;
19 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
20 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
21 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
22 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
23 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
24 import org.simantics.scl.compiler.environment.AmbiguousNameException;
25 import org.simantics.scl.compiler.environment.Environment;
26 import org.simantics.scl.compiler.environment.Environments;
27 import org.simantics.scl.compiler.errors.ErrorLog;
28 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
29 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
30 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
31 import org.simantics.scl.compiler.internal.parsing.expressions.Expressions;
32 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
33 import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository;
34 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
35 import org.simantics.scl.compiler.types.TCon;
37 class IODeriver implements InstanceDeriver {
42 Environment environment,
43 ArrayList<ProcessedDInstanceAst> instancesAst,
44 DDerivingInstanceAst der) {
46 if(der.types.length != 1) {
47 errorLog.log(der.location, "Invalid number of parameters to " + der.name);
50 TVarAst headType = DerivingUtils.getHeadType(der.types[0]);
51 if(headType == null) {
52 errorLog.log(der.types[0].location, "Cannot derive IO instance for the type " + headType + ".");
57 con = Environments.getTypeDescriptorName(environment, headType.name);
58 } catch (AmbiguousNameException e1) {
59 errorLog.log(headType.location, e1.getMessage());
63 errorLog.log(headType.location, "Couldn't resolve " + headType.name);
66 TypeDescriptor tdesc = environment.getTypeDescriptor(con);
68 errorLog.log(headType.location, "Didn't find type constructor for " + headType.name);
71 if(tdesc instanceof TypeAlias) {
72 errorLog.log(headType.location, "Cannot derive instance for a type alias.");
75 TypeConstructor tcon = (TypeConstructor)tdesc;
77 errorLog.log(headType.location, "Cannot derive instance for open data types.");
81 DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types);
82 ValueRepository valueDefs = new ValueRepository();
84 SCLValue write = environment.getValue(Names.Serialization_write);
85 SCLValue read = environment.getValue(Names.Serialization_read);
86 SCLValue ioSize = environment.getValue(Names.Serialization_ioSize);
89 for(int id=0;id<tcon.constructors.length;++id) {
90 Constructor constructor = tcon.constructors[id];
91 int l = constructor.parameterTypes.length;
92 String[] par = new String[l];
93 for(int i=0;i<l;++i) {
96 Expression lhs = new EApply(
99 new EApply(new EVar(constructor.name.name), Expressions.vars(par))
101 ArrayList<Expression> statements = new ArrayList<Expression>();
103 new EApply(new EConstant(write), new EVar("s"),
104 new ELiteral(new ByteConstant((byte)id))));
106 statements.add(new EApply(new EConstant(write), new EVar("s"), new EVar(par[i])));
108 Expression rhs = EBlock.create(statements);
110 DValueAst valueAst = new DValueAst(lhs, rhs);
111 valueAst.setLocationDeep(der.location);
112 valueDefs.add(valueAst);
113 /*valueDefs.addAnnotation("write", new DAnnotationAst(new EVar("@private"),
114 Collections.<Expression>emptyList()));*/
115 } catch (NotPatternException e) {
116 errorLog.log(e.getExpression().location, "Not a pattern.");
122 Expression lhs = new EApply(
126 Case[] cases = new Case[tcon.constructors.length];
127 for(int id=0;id<tcon.constructors.length;++id) {
128 Constructor constructor = tcon.constructors[id];
129 int l = constructor.parameterTypes.length;
130 String[] par = new String[l];
131 for(int i=0;i<l;++i) {
134 ArrayList<LetStatement> assignments = new ArrayList<LetStatement>(l);
136 assignments.add(new LetStatement(new EVar(par[i]),
137 new EApply(new EConstant(read), new EVar("s"))));
138 Expression in = new EApply(
139 new EVar(constructor.name.name),
140 Expressions.vars(par));
141 cases[id] = new Case(new ELiteral(new ByteConstant((byte)id)),
142 new EPreLet(assignments, in));
145 new EMatch(new EApply(new EConstant(read), new EVar("s")),
148 DValueAst valueAst = new DValueAst(lhs, rhs);
149 valueAst.setLocationDeep(der.location);
150 valueDefs.add(valueAst);
151 /*valueDefs.addAnnotation("read=", new DAnnotationAst(new EVar("@private"),
152 Collections.<Expression>emptyList()));*/
153 } catch (NotPatternException e) {
154 errorLog.log(e.getExpression().location, "Not a pattern.");
159 for(int id=0;id<tcon.constructors.length;++id) {
160 Constructor constructor = tcon.constructors[id];
161 int l = constructor.parameterTypes.length;
162 String[] par = new String[l];
163 for(int i=0;i<l;++i) {
166 Expression lhs = new EApply(
168 new EApply(new EVar(constructor.name.name), Expressions.vars(par))
170 Expression rhs = new ELiteral(new IntegerConstant(1));
172 rhs = new EApply(new EVar("+"),
174 new EApply(new EConstant(ioSize), new EVar(par[i]))
177 DValueAst valueAst = new DValueAst(lhs, rhs);
178 valueAst.setLocationDeep(der.location);
179 valueDefs.add(valueAst);
180 /*valueDefs.addAnnotation("ioSize", new DAnnotationAst(new EVar("@private"),
181 Collections.<Expression>emptyList()));*/
182 } catch (NotPatternException e) {
183 errorLog.log(e.getExpression().location, "Not a pattern.");
187 instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs));