]> gerrit.simantics Code Review - simantics/platform.git/blob
7423ba913420875ad031f8438f1934e0c742af3f
[simantics/platform.git] /
1 package org.simantics.graph.compiler.internal.translation;
2
3 import java.util.Collection;
4
5 import org.antlr.runtime.tree.Tree;
6 import org.simantics.databoard.Bindings;
7 import org.simantics.databoard.binding.ArrayBinding;
8 import org.simantics.databoard.binding.Binding;
9 import org.simantics.databoard.binding.BooleanBinding;
10 import org.simantics.databoard.binding.ByteBinding;
11 import org.simantics.databoard.binding.DoubleBinding;
12 import org.simantics.databoard.binding.FloatBinding;
13 import org.simantics.databoard.binding.IntegerBinding;
14 import org.simantics.databoard.binding.LongBinding;
15 import org.simantics.databoard.binding.MapBinding;
16 import org.simantics.databoard.binding.OptionalBinding;
17 import org.simantics.databoard.binding.RecordBinding;
18 import org.simantics.databoard.binding.StringBinding;
19 import org.simantics.databoard.binding.UnionBinding;
20 import org.simantics.databoard.binding.VariantBinding;
21 import org.simantics.databoard.binding.error.BindingException;
22 import org.simantics.databoard.type.Datatype;
23 import org.simantics.graph.compiler.internal.parsing.GraphParser;
24 import org.simantics.ltk.ISource;
25 import org.simantics.ltk.Problem;
26 import org.simantics.ltk.antlr.ANTLRUtils;
27
28 public class DataValueTranslator {
29         
30         ISource source;
31         Collection<Problem> problems;
32         
33         public DataValueTranslator(ISource source, Collection<Problem> problems) {
34                 this.source = source;
35                 this.problems = problems;
36         }
37
38         public Object translate(Tree _tree, Binding binding) {
39                 while(_tree.getType() == GraphParser.TUPLE && 
40                                 _tree.getChildCount()==1)
41                         _tree = _tree.getChild(0);
42                 final Tree tree = _tree;
43                 return binding.accept(new Binding.Visitor<Object>() {
44
45                         @Override
46                         public Object visit(ArrayBinding b) {
47                                 if(tree.getType() == GraphParser.ARRAY) {
48                                         int count = tree.getChildCount();
49                                         Object[] components = new Object[count];
50                                         Binding componentBinding = b.getComponentBinding();
51                                         for(int i=0;i<count;++i)
52                                                 components[i] = translate(tree.getChild(i),
53                                                                 componentBinding
54                                                                 );
55                                         return b.createUnchecked(components);
56                                 }
57                                 typeError(tree, b);
58                                 return b.createDefaultUnchecked();
59                         }
60
61                         @Override
62                         public Object visit(BooleanBinding b) {
63                                 if(tree.getType() == GraphParser.TRUE)
64                                         return b.createUnchecked(true);
65                                 else if(tree.getType() == GraphParser.FALSE)
66                                         return b.createUnchecked(false);
67                                 typeError(tree, b);
68                                 return b.createDefaultUnchecked();
69                         }
70
71                         @Override
72                         public Object visit(DoubleBinding b) {
73                                 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
74                                         return b.createUnchecked(tree.getText());
75                                 typeError(tree, b);
76                                 return b.createDefaultUnchecked();
77                         }
78
79                         @Override
80                         public Object visit(FloatBinding b) {
81                                 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
82                                         return b.createUnchecked(tree.getText());
83                                 typeError(tree, b);
84                                 return b.createDefaultUnchecked();
85                         }
86
87                         @Override
88                         public Object visit(IntegerBinding b) {
89                                 if(tree.getType() == GraphParser.INT)
90                                         return b.createUnchecked(tree.getText());
91                                 typeError(tree, b);
92                                 return b.createDefaultUnchecked();
93                         }
94
95                         @Override
96                         public Object visit(ByteBinding b) {
97                                 if(tree.getType() == GraphParser.INT)
98                                         return b.createUnchecked(tree.getText());
99                                 typeError(tree, b);
100                                 return b.createDefaultUnchecked();
101                         }
102
103                         @Override
104                         public Object visit(LongBinding b) {
105                                 if(tree.getType() == GraphParser.INT)
106                                         return b.createUnchecked(tree.getText());
107                                 typeError(tree, b);
108                                 return b.createDefaultUnchecked();
109                         }
110
111                         @Override
112                         public Object visit(OptionalBinding b) {
113                                 if(tree.getType() == GraphParser.NO_VALUE) 
114                                         return b.createNoValueUnchecked();
115                                 else
116                                         return b.createValueUnchecked(
117                                                         translate(tree, b.getComponentBinding())
118                                                         );
119                         }
120
121                         @Override
122                         public Object visit(RecordBinding b) {
123                                 boolean hadError = false;
124                                 if(tree.getType() == GraphParser.RECORD) {
125                                         int count = tree.getChildCount();
126                                         Object[] components = new Object[b.componentBindings.length];
127                                         boolean[] setValues = new boolean[b.componentBindings.length];
128                                         for(int i=0;i<count;++i) {
129                                                 Tree assignment = tree.getChild(i);
130                                                 String field = assignment.getChild(0).getText();
131                                                 Integer comp = 
132                                                         b.type().getComponentIndex(field);
133                                                 if(comp == null) {
134                                                         hadError = true;
135                                                         problems.add(new Problem(
136                                                                         ANTLRUtils.location(source, tree), 
137                                                                         "Record type " + b.type() + " does not have a field " + field + "."
138                                                                 ));
139                                                 }
140                                                 else { 
141                                                         components[comp] = translate(
142                                                                         assignment.getChild(1),
143                                                                         b.getComponentBinding(comp)
144                                                                         );
145                                                         setValues[comp] = true;
146                                                 }
147                                         }
148                                         try {
149                                                 for(int i=0;i<b.componentBindings.length;++i)                                           
150                                                         if(!setValues[i]) {
151                                                                 if(b.componentBindings[i] instanceof OptionalBinding)
152                                                                         components[i] = b.componentBindings[i].createDefault();
153                                                                 else 
154                                                                         problems.add(new Problem(
155                                                                                         ANTLRUtils.location(source, tree), 
156                                                                                         "Not all fields of the record are given."
157                                                                                 ));
158                                                                 return b.createDefaultUnchecked();
159                                                         }
160                                                 return b.create(components);
161                                         } catch(BindingException e) {                                   
162                                         }
163                                 }
164                                 if(tree.getType() == GraphParser.TUPLE) {
165                                         int count = tree.getChildCount();
166                                         if(count == b.getComponentCount()) {                                            
167                                                 Object[] components = new Object[count];
168                                                 for(int i=0;i<count;++i)
169                                                         components[i] = 
170                                                                 translate(tree.getChild(i), 
171                                                                                 b.getComponentBinding(i));
172                                                 return b.createUnchecked(components);
173                                         }
174                                 }
175                                 if(!hadError)
176                                         typeError(tree, b);
177                                 return b.createDefaultUnchecked();
178                         }
179
180                         @Override
181                         public Object visit(StringBinding b) {
182                                 if(tree.getType() == GraphParser.STRING) {
183                                         String str = tree.getText();
184                                         if(str.charAt(1) == '"' && str.length() >= 6)
185                                                 return b.createUnchecked(str.substring(3, str.length()-3));
186                                         else
187                                                 return b.createUnchecked(str.substring(1, str.length()-1));
188                                 }
189                                 typeError(tree, b);
190                                 return b.createDefaultUnchecked();
191                         }
192
193                         @Override
194                         public Object visit(UnionBinding b) {
195                                 if(tree.getType() == GraphParser.TAGGED_VALUE) {
196                                         String tag = tree.getChild(0).getText();
197                                         Integer comp = b.type().getComponentIndex(tag);
198                                         if(comp != null) {
199                                                 if(tree.getChildCount() == 2)
200                                                         return b.createUnchecked(comp, 
201                                                                 translate(
202                                                                         tree.getChild(1), 
203                                                                         b.getComponentBinding(comp)
204                                                                         ));
205                                                 else {
206                                                         Binding binding = b.getComponentBinding(comp);
207                                                         if(binding instanceof RecordBinding &&
208                                                                         ((RecordBinding)binding).getComponentCount() == 0)
209                                                                 return b.createUnchecked(comp, 
210                                                                         ((RecordBinding)binding).createUnchecked());
211                                                         else
212                                                                 typeError(tree, binding);
213                                                 }
214                                         }
215                                 }
216                                 typeError(tree, b);
217                                 return b.createDefaultUnchecked();                              
218                         }
219
220                         @Override
221                         public Object visit(VariantBinding b) {
222                                 if(tree.getType() == GraphParser.VARIANT) {
223                                         Datatype type = 
224                                                 new DataTypeTranslator(source, problems).translate(tree.getChild(0));
225                                         Binding binding = Bindings.getBinding(type);
226                                         
227                                         Object value = translate(tree.getChild(1), binding);
228                                         return b.createUnchecked(binding, value);
229                                 }
230                                 typeError(tree, b);
231                                 return b.createDefaultUnchecked();
232                         }
233
234                         @Override
235                         public Object visit(MapBinding b) {
236                                 if(tree.getType() == GraphParser.MAP) {
237                                         int count = tree.getChildCount();
238                                         Object[] keys = new Object[count];
239                                         Object[] values = new Object[count];
240                                         Binding keyBinding = b.getKeyBinding();
241                                         Binding valueBinding = b.getValueBinding();
242                                         for(int i=0;i<count;++i) {
243                                                 keys[i] = translate(tree.getChild(i).getChild(0), keyBinding);
244                                                 values[i] = translate(tree.getChild(i).getChild(1), valueBinding);
245                                         }
246                                         return b.createUnchecked(keys, values);
247                                 }
248                                 typeError(tree, b);
249                                 return b.createDefaultUnchecked();
250                         }
251                 });
252         }
253         
254         private void typeError(Tree tree, Binding binding) { 
255                 problems.add(new Problem(
256                                 ANTLRUtils.location(source, tree), 
257                                 "Value does not correspond to the data type " + binding.type() + "."
258                         ));
259         }
260         
261 }