1 package org.simantics.graph.compiler.internal.translation;
3 import java.util.Collection;
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;
28 public class DataValueTranslator {
31 Collection<Problem> problems;
33 public DataValueTranslator(ISource source, Collection<Problem> problems) {
35 this.problems = problems;
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>() {
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),
55 return b.createUnchecked(components);
58 return b.createDefaultUnchecked();
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);
68 return b.createDefaultUnchecked();
72 public Object visit(DoubleBinding b) {
73 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
74 return b.createUnchecked(tree.getText());
76 return b.createDefaultUnchecked();
80 public Object visit(FloatBinding b) {
81 if(tree.getType() == GraphParser.INT || tree.getType() == GraphParser.FLOAT)
82 return b.createUnchecked(tree.getText());
84 return b.createDefaultUnchecked();
88 public Object visit(IntegerBinding b) {
89 if(tree.getType() == GraphParser.INT)
90 return b.createUnchecked(tree.getText());
92 return b.createDefaultUnchecked();
96 public Object visit(ByteBinding b) {
97 if(tree.getType() == GraphParser.INT)
98 return b.createUnchecked(tree.getText());
100 return b.createDefaultUnchecked();
104 public Object visit(LongBinding b) {
105 if(tree.getType() == GraphParser.INT)
106 return b.createUnchecked(tree.getText());
108 return b.createDefaultUnchecked();
112 public Object visit(OptionalBinding b) {
113 if(tree.getType() == GraphParser.NO_VALUE)
114 return b.createNoValueUnchecked();
116 return b.createValueUnchecked(
117 translate(tree, b.getComponentBinding())
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();
132 b.type().getComponentIndex(field);
135 problems.add(new Problem(
136 ANTLRUtils.location(source, tree),
137 "Record type " + b.type() + " does not have a field " + field + "."
141 components[comp] = translate(
142 assignment.getChild(1),
143 b.getComponentBinding(comp)
145 setValues[comp] = true;
149 for(int i=0;i<b.componentBindings.length;++i)
151 if(b.componentBindings[i] instanceof OptionalBinding)
152 components[i] = b.componentBindings[i].createDefault();
154 problems.add(new Problem(
155 ANTLRUtils.location(source, tree),
156 "Not all fields of the record are given."
158 return b.createDefaultUnchecked();
160 return b.create(components);
161 } catch(BindingException e) {
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)
170 translate(tree.getChild(i),
171 b.getComponentBinding(i));
172 return b.createUnchecked(components);
177 return b.createDefaultUnchecked();
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));
187 return b.createUnchecked(str.substring(1, str.length()-1));
190 return b.createDefaultUnchecked();
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);
199 if(tree.getChildCount() == 2)
200 return b.createUnchecked(comp,
203 b.getComponentBinding(comp)
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());
212 typeError(tree, binding);
217 return b.createDefaultUnchecked();
221 public Object visit(VariantBinding b) {
222 if(tree.getType() == GraphParser.VARIANT) {
224 new DataTypeTranslator(source, problems).translate(tree.getChild(0));
225 Binding binding = Bindings.getBinding(type);
227 Object value = translate(tree.getChild(1), binding);
228 return b.createUnchecked(binding, value);
231 return b.createDefaultUnchecked();
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);
246 return b.createUnchecked(keys, values);
249 return b.createDefaultUnchecked();
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() + "."