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