1 package org.simantics.graph.compiler.internal.translation;
\r
3 import java.util.Collection;
\r
5 import org.antlr.runtime.tree.Tree;
\r
6 import org.simantics.databoard.Bindings;
\r
7 import org.simantics.databoard.binding.ArrayBinding;
\r
8 import org.simantics.databoard.binding.Binding;
\r
9 import org.simantics.databoard.binding.BooleanBinding;
\r
10 import org.simantics.databoard.binding.ByteBinding;
\r
11 import org.simantics.databoard.binding.DoubleBinding;
\r
12 import org.simantics.databoard.binding.FloatBinding;
\r
13 import org.simantics.databoard.binding.IntegerBinding;
\r
14 import org.simantics.databoard.binding.LongBinding;
\r
15 import org.simantics.databoard.binding.MapBinding;
\r
16 import org.simantics.databoard.binding.OptionalBinding;
\r
17 import org.simantics.databoard.binding.RecordBinding;
\r
18 import org.simantics.databoard.binding.StringBinding;
\r
19 import org.simantics.databoard.binding.UnionBinding;
\r
20 import org.simantics.databoard.binding.VariantBinding;
\r
21 import org.simantics.databoard.binding.error.BindingException;
\r
22 import org.simantics.databoard.type.Datatype;
\r
23 import org.simantics.graph.compiler.internal.parsing.GraphParser;
\r
24 import org.simantics.ltk.ISource;
\r
25 import org.simantics.ltk.Problem;
\r
26 import org.simantics.ltk.antlr.ANTLRUtils;
\r
28 public class DataValueTranslator {
\r
31 Collection<Problem> problems;
\r
33 public DataValueTranslator(ISource source, Collection<Problem> problems) {
\r
34 this.source = source;
\r
35 this.problems = problems;
\r
38 public Object translate(Tree _tree, Binding binding) {
\r
39 while(_tree.getType() == GraphParser.TUPLE &&
\r
40 _tree.getChildCount()==1)
\r
41 _tree = _tree.getChild(0);
\r
42 final Tree tree = _tree;
\r
43 return binding.accept(new Binding.Visitor<Object>() {
\r
46 public Object visit(ArrayBinding b) {
\r
47 if(tree.getType() == GraphParser.ARRAY) {
\r
48 int count = tree.getChildCount();
\r
49 Object[] components = new Object[count];
\r
50 Binding componentBinding = b.getComponentBinding();
\r
51 for(int i=0;i<count;++i)
\r
52 components[i] = translate(tree.getChild(i),
\r
55 return b.createUnchecked(components);
\r
58 return b.createDefaultUnchecked();
\r
62 public Object visit(BooleanBinding b) {
\r
63 if(tree.getType() == GraphParser.TRUE)
\r
64 return b.createUnchecked(true);
\r
65 else if(tree.getType() == GraphParser.FALSE)
\r
66 return b.createUnchecked(false);
\r
68 return b.createDefaultUnchecked();
\r
72 public Object visit(DoubleBinding b) {
\r
73 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
\r
74 return b.createUnchecked(tree.getText());
\r
76 return b.createDefaultUnchecked();
\r
80 public Object visit(FloatBinding b) {
\r
81 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
\r
82 return b.createUnchecked(tree.getText());
\r
84 return b.createDefaultUnchecked();
\r
88 public Object visit(IntegerBinding b) {
\r
89 if(tree.getType() == GraphParser.INT)
\r
90 return b.createUnchecked(tree.getText());
\r
92 return b.createDefaultUnchecked();
\r
96 public Object visit(ByteBinding b) {
\r
97 if(tree.getType() == GraphParser.INT)
\r
98 return b.createUnchecked(tree.getText());
\r
100 return b.createDefaultUnchecked();
\r
104 public Object visit(LongBinding b) {
\r
105 if(tree.getType() == GraphParser.INT)
\r
106 return b.createUnchecked(tree.getText());
\r
107 typeError(tree, b);
\r
108 return b.createDefaultUnchecked();
\r
112 public Object visit(OptionalBinding b) {
\r
113 if(tree.getType() == GraphParser.NO_VALUE)
\r
114 return b.createNoValueUnchecked();
\r
116 return b.createValueUnchecked(
\r
117 translate(tree, b.getComponentBinding())
\r
122 public Object visit(RecordBinding b) {
\r
123 boolean hadError = false;
\r
124 if(tree.getType() == GraphParser.RECORD) {
\r
125 int count = tree.getChildCount();
\r
126 Object[] components = new Object[b.componentBindings.length];
\r
127 boolean[] setValues = new boolean[b.componentBindings.length];
\r
128 for(int i=0;i<count;++i) {
\r
129 Tree assignment = tree.getChild(i);
\r
130 String field = assignment.getChild(0).getText();
\r
132 b.type().getComponentIndex(field);
\r
135 problems.add(new Problem(
\r
136 ANTLRUtils.location(source, tree),
\r
137 "Record type " + b.type() + " does not have a field " + field + "."
\r
141 components[comp] = translate(
\r
142 assignment.getChild(1),
\r
143 b.getComponentBinding(comp)
\r
145 setValues[comp] = true;
\r
149 for(int i=0;i<b.componentBindings.length;++i)
\r
150 if(!setValues[i]) {
\r
151 if(b.componentBindings[i] instanceof OptionalBinding)
\r
152 components[i] = b.componentBindings[i].createDefault();
\r
154 problems.add(new Problem(
\r
155 ANTLRUtils.location(source, tree),
\r
156 "Not all fields of the record are given."
\r
158 return b.createDefaultUnchecked();
\r
160 return b.create(components);
\r
161 } catch(BindingException e) {
\r
164 if(tree.getType() == GraphParser.TUPLE) {
\r
165 int count = tree.getChildCount();
\r
166 if(count == b.getComponentCount()) {
\r
167 Object[] components = new Object[count];
\r
168 for(int i=0;i<count;++i)
\r
170 translate(tree.getChild(i),
\r
171 b.getComponentBinding(i));
\r
172 return b.createUnchecked(components);
\r
176 typeError(tree, b);
\r
177 return b.createDefaultUnchecked();
\r
181 public Object visit(StringBinding b) {
\r
182 if(tree.getType() == GraphParser.STRING) {
\r
183 String str = tree.getText();
\r
184 if(str.charAt(1) == '"' && str.length() >= 6)
\r
185 return b.createUnchecked(str.substring(3, str.length()-3));
\r
187 return b.createUnchecked(str.substring(1, str.length()-1));
\r
189 typeError(tree, b);
\r
190 return b.createDefaultUnchecked();
\r
194 public Object visit(UnionBinding b) {
\r
195 if(tree.getType() == GraphParser.TAGGED_VALUE) {
\r
196 String tag = tree.getChild(0).getText();
\r
197 Integer comp = b.type().getComponentIndex(tag);
\r
199 if(tree.getChildCount() == 2)
\r
200 return b.createUnchecked(comp,
\r
203 b.getComponentBinding(comp)
\r
206 Binding binding = b.getComponentBinding(comp);
\r
207 if(binding instanceof RecordBinding &&
\r
208 ((RecordBinding)binding).getComponentCount() == 0)
\r
209 return b.createUnchecked(comp,
\r
210 ((RecordBinding)binding).createUnchecked());
\r
212 typeError(tree, binding);
\r
216 typeError(tree, b);
\r
217 return b.createDefaultUnchecked();
\r
221 public Object visit(VariantBinding b) {
\r
222 if(tree.getType() == GraphParser.VARIANT) {
\r
224 new DataTypeTranslator(source, problems).translate(tree.getChild(0));
\r
225 Binding binding = Bindings.getBinding(type);
\r
227 Object value = translate(tree.getChild(1), binding);
\r
228 return b.createUnchecked(binding, value);
\r
230 typeError(tree, b);
\r
231 return b.createDefaultUnchecked();
\r
235 public Object visit(MapBinding b) {
\r
236 if(tree.getType() == GraphParser.MAP) {
\r
237 int count = tree.getChildCount();
\r
238 Object[] keys = new Object[count];
\r
239 Object[] values = new Object[count];
\r
240 Binding keyBinding = b.getKeyBinding();
\r
241 Binding valueBinding = b.getValueBinding();
\r
242 for(int i=0;i<count;++i) {
\r
243 keys[i] = translate(tree.getChild(i).getChild(0), keyBinding);
\r
244 values[i] = translate(tree.getChild(i).getChild(1), valueBinding);
\r
246 return b.createUnchecked(keys, values);
\r
248 typeError(tree, b);
\r
249 return b.createDefaultUnchecked();
\r
254 private void typeError(Tree tree, Binding binding) {
\r
255 problems.add(new Problem(
\r
256 ANTLRUtils.location(source, tree),
\r
257 "Value does not correspond to the data type " + binding.type() + "."
\r