1 package org.simantics.graph.compiler.internal.translation;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.Collection;
\r
7 import org.antlr.runtime.tree.Tree;
\r
8 import org.simantics.databoard.Datatypes;
\r
9 import org.simantics.databoard.type.ArrayType;
\r
10 import org.simantics.databoard.type.ByteType;
\r
11 import org.simantics.databoard.type.Component;
\r
12 import org.simantics.databoard.type.Datatype;
\r
13 import org.simantics.databoard.type.DoubleType;
\r
14 import org.simantics.databoard.type.FloatType;
\r
15 import org.simantics.databoard.type.IntegerType;
\r
16 import org.simantics.databoard.type.LongType;
\r
17 import org.simantics.databoard.type.MapType;
\r
18 import org.simantics.databoard.type.OptionalType;
\r
19 import org.simantics.databoard.type.RecordType;
\r
20 import org.simantics.databoard.type.StringType;
\r
21 import org.simantics.databoard.type.UnionType;
\r
22 import org.simantics.graph.compiler.internal.parsing.GraphParser;
\r
23 import org.simantics.ltk.ISource;
\r
24 import org.simantics.ltk.Problem;
\r
25 import org.simantics.ltk.antlr.ANTLRUtils;
\r
27 public class DataTypeTranslator {
\r
30 Collection<Problem> problems;
\r
32 public DataTypeTranslator(ISource source, Collection<Problem> problems) {
\r
33 this.source = source;
\r
34 this.problems = problems;
\r
37 public Datatype translate(Tree tree) {
\r
38 switch(tree.getType()) {
\r
39 case GraphParser.RECORD_TYPE:
\r
40 return translateRecordType(tree);
\r
41 case GraphParser.UNION_TYPE:
\r
42 return translateUnionType(tree);
\r
43 case GraphParser.TUPLE_TYPE:
\r
44 return translateTupleType(tree);
\r
45 case GraphParser.ARRAY_TYPE:
\r
46 return translateArrayType(tree);
\r
47 case GraphParser.TYPE_REFERENCE:
\r
48 return translateTypeReference(tree);
\r
51 throw new IllegalArgumentException("The argument is not a data type AST");
\r
55 private Datatype translateArrayType(Tree tree) {
\r
56 return new ArrayType(translate(tree.getChild(0)));
\r
59 private Datatype translateTupleType(Tree tree) {
\r
60 int count = tree.getChildCount();
\r
62 return translate(tree.getChild(0));
\r
63 Component[] components = new Component[count];
\r
64 for(int i=0;i<count;++i) {
\r
65 components[i] = new Component(
\r
66 Integer.toString(i),
\r
67 translate(tree.getChild(i))
\r
70 return new RecordType(false, components);
\r
73 private static THashMap<String,String> getAnnotations(Tree tree) {
\r
74 THashMap<String,String> result = new THashMap<String,String>();
\r
75 for(int i=1;i<tree.getChildCount();++i) {
\r
76 Tree child = tree.getChild(i);
\r
77 if(child.getType() == GraphParser.TYPE_ANNOTATION) {
\r
79 child.getChild(0).getText(),
\r
80 convertValue(child.getChild(1))
\r
87 private static String convertValue(Tree value) {
\r
88 //System.out.println(GraphParser.tokenNames[value.getType()]);
\r
89 switch(value.getType()) {
\r
90 case GraphParser.STRING: {
\r
91 String str = value.getText();
\r
92 return str.substring(1, str.length()-1);
\r
94 case GraphParser.INT:
\r
95 case GraphParser.FLOAT:
\r
96 return value.getText();
\r
97 case GraphParser.RANGE:
\r
98 return value.getChild(0).getText() + value.getChild(1).getText() + value.getChild(2).getText();
\r
100 throw new IllegalArgumentException();
\r
104 private Datatype translateTypeReference(Tree tree) {
\r
105 String name = tree.getChild(0).getText();
\r
106 if(name.equals("Boolean"))
\r
107 return Datatypes.BOOLEAN;
\r
108 else if(name.equals("Byte")) {
\r
109 THashMap<String,String> annotations = getAnnotations(tree);
\r
110 return new ByteType(
\r
111 annotations.get("unit"),
\r
112 annotations.get("range")
\r
115 else if(name.equals("Integer")) {
\r
116 THashMap<String,String> annotations = getAnnotations(tree);
\r
117 return new IntegerType(
\r
118 annotations.get("unit"),
\r
119 annotations.get("range")
\r
122 else if(name.equals("Float")) {
\r
123 THashMap<String,String> annotations = getAnnotations(tree);
\r
124 return new FloatType(
\r
125 annotations.get("unit"),
\r
126 annotations.get("range")
\r
129 else if(name.equals("Double")) {
\r
130 THashMap<String,String> annotations = getAnnotations(tree);
\r
131 return new DoubleType(
\r
132 annotations.get("unit"),
\r
133 annotations.get("range")
\r
136 else if(name.equals("Long")) {
\r
137 THashMap<String,String> annotations = getAnnotations(tree);
\r
138 return new LongType(
\r
139 annotations.get("unit"),
\r
140 annotations.get("range")
\r
143 else if(name.equals("String")) {
\r
144 THashMap<String,String> annotations = getAnnotations(tree);
\r
145 return new StringType(
\r
146 annotations.get("pattern"),
\r
147 annotations.get("mimeType"),
\r
148 annotations.get("length")
\r
151 else if(name.equals("Variant"))
\r
152 return Datatypes.VARIANT;
\r
153 else if(name.equals("Optional"))
\r
154 return new OptionalType(translate(tree.getChild(1)));
\r
155 else if(name.equals("Map"))
\r
156 return new MapType(translate(tree.getChild(1)), translate(tree.getChild(2)));
\r
157 else if(name.equals("DataType"))
\r
158 return Datatypes.getDatatypeUnchecked(Datatype.class);
\r
160 error(tree, "Invalid data type " + name + ".");
\r
165 private Datatype translateUnionType(Tree tree) {
\r
166 Component[] components = new Component[tree.getChildCount()];
\r
167 for(int i=0;i<components.length;++i) {
\r
168 Tree c = tree.getChild(i);
\r
169 components[i] = new Component(
\r
170 c.getChild(0).getText(),
\r
171 c.getChildCount() > 1 ? translate(c.getChild(1)) : RecordType.VOID_TYPE
\r
174 return new UnionType(components);
\r
177 private Datatype translateRecordType(Tree tree) {
\r
178 Component[] components = new Component[tree.getChildCount()];
\r
179 for(int i=0;i<components.length;++i) {
\r
180 Tree c = tree.getChild(i);
\r
181 components[i] = new Component(
\r
182 c.getChild(0).getText(),
\r
183 translate(c.getChild(1))
\r
186 return new RecordType(false, components);
\r
189 public static void printTree(int indent, Tree tree) {
\r
190 for(int i=0;i<indent;++i)
\r
191 System.out.print(" ");
\r
192 System.out.println(tree.getText());
\r
193 for(int i=0;i<tree.getChildCount();++i)
\r
194 printTree(indent+1, tree.getChild(i));
\r
197 private void error(Tree tree, String description) {
\r
198 problems.add(new Problem(
\r
199 ANTLRUtils.location(source, tree),
\r