--- /dev/null
+package org.simantics.graph.compiler.internal.translation;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+import java.util.Collection;\r
+\r
+import org.antlr.runtime.tree.Tree;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.ByteType;\r
+import org.simantics.databoard.type.Component;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.DoubleType;\r
+import org.simantics.databoard.type.FloatType;\r
+import org.simantics.databoard.type.IntegerType;\r
+import org.simantics.databoard.type.LongType;\r
+import org.simantics.databoard.type.MapType;\r
+import org.simantics.databoard.type.OptionalType;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.databoard.type.StringType;\r
+import org.simantics.databoard.type.UnionType;\r
+import org.simantics.graph.compiler.internal.parsing.GraphParser;\r
+import org.simantics.ltk.ISource;\r
+import org.simantics.ltk.Problem;\r
+import org.simantics.ltk.antlr.ANTLRUtils;\r
+\r
+public class DataTypeTranslator {\r
+\r
+ ISource source;\r
+ Collection<Problem> problems;\r
+ \r
+ public DataTypeTranslator(ISource source, Collection<Problem> problems) {\r
+ this.source = source;\r
+ this.problems = problems;\r
+ }\r
+\r
+ public Datatype translate(Tree tree) { \r
+ switch(tree.getType()) {\r
+ case GraphParser.RECORD_TYPE:\r
+ return translateRecordType(tree);\r
+ case GraphParser.UNION_TYPE:\r
+ return translateUnionType(tree);\r
+ case GraphParser.TUPLE_TYPE:\r
+ return translateTupleType(tree);\r
+ case GraphParser.ARRAY_TYPE:\r
+ return translateArrayType(tree);\r
+ case GraphParser.TYPE_REFERENCE:\r
+ return translateTypeReference(tree);\r
+ default:\r
+ printTree(0, tree);\r
+ throw new IllegalArgumentException("The argument is not a data type AST");\r
+ }\r
+ }\r
+\r
+ private Datatype translateArrayType(Tree tree) {\r
+ return new ArrayType(translate(tree.getChild(0)));\r
+ }\r
+\r
+ private Datatype translateTupleType(Tree tree) {\r
+ int count = tree.getChildCount(); \r
+ if(count == 1)\r
+ return translate(tree.getChild(0));\r
+ Component[] components = new Component[count];\r
+ for(int i=0;i<count;++i) {\r
+ components[i] = new Component(\r
+ Integer.toString(i),\r
+ translate(tree.getChild(i))\r
+ );\r
+ }\r
+ return new RecordType(false, components); \r
+ }\r
+ \r
+ private static THashMap<String,String> getAnnotations(Tree tree) {\r
+ THashMap<String,String> result = new THashMap<String,String>(); \r
+ for(int i=1;i<tree.getChildCount();++i) {\r
+ Tree child = tree.getChild(i);\r
+ if(child.getType() == GraphParser.TYPE_ANNOTATION) {\r
+ result.put(\r
+ child.getChild(0).getText(),\r
+ convertValue(child.getChild(1))\r
+ );\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ private static String convertValue(Tree value) {\r
+ //System.out.println(GraphParser.tokenNames[value.getType()]);\r
+ switch(value.getType()) {\r
+ case GraphParser.STRING: {\r
+ String str = value.getText();\r
+ return str.substring(1, str.length()-1);\r
+ }\r
+ case GraphParser.INT:\r
+ case GraphParser.FLOAT:\r
+ return value.getText();\r
+ case GraphParser.RANGE:\r
+ return value.getChild(0).getText() + value.getChild(1).getText() + value.getChild(2).getText();\r
+ default:\r
+ throw new IllegalArgumentException();\r
+ }\r
+ }\r
+\r
+ private Datatype translateTypeReference(Tree tree) {\r
+ String name = tree.getChild(0).getText();\r
+ if(name.equals("Boolean"))\r
+ return Datatypes.BOOLEAN;\r
+ else if(name.equals("Byte")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new ByteType(\r
+ annotations.get("unit"),\r
+ annotations.get("range")\r
+ );\r
+ }\r
+ else if(name.equals("Integer")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new IntegerType(\r
+ annotations.get("unit"),\r
+ annotations.get("range")\r
+ );\r
+ }\r
+ else if(name.equals("Float")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new FloatType(\r
+ annotations.get("unit"),\r
+ annotations.get("range")\r
+ );\r
+ }\r
+ else if(name.equals("Double")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new DoubleType(\r
+ annotations.get("unit"),\r
+ annotations.get("range")\r
+ );\r
+ }\r
+ else if(name.equals("Long")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new LongType(\r
+ annotations.get("unit"),\r
+ annotations.get("range")\r
+ );\r
+ }\r
+ else if(name.equals("String")) {\r
+ THashMap<String,String> annotations = getAnnotations(tree);\r
+ return new StringType(\r
+ annotations.get("pattern"),\r
+ annotations.get("mimeType"),\r
+ annotations.get("length")\r
+ );\r
+ }\r
+ else if(name.equals("Variant"))\r
+ return Datatypes.VARIANT;\r
+ else if(name.equals("Optional"))\r
+ return new OptionalType(translate(tree.getChild(1)));\r
+ else if(name.equals("Map"))\r
+ return new MapType(translate(tree.getChild(1)), translate(tree.getChild(2)));\r
+ else if(name.equals("DataType"))\r
+ return Datatypes.getDatatypeUnchecked(Datatype.class);\r
+ else { \r
+ error(tree, "Invalid data type " + name + ".");\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private Datatype translateUnionType(Tree tree) {\r
+ Component[] components = new Component[tree.getChildCount()];\r
+ for(int i=0;i<components.length;++i) {\r
+ Tree c = tree.getChild(i);\r
+ components[i] = new Component(\r
+ c.getChild(0).getText(), \r
+ c.getChildCount() > 1 ? translate(c.getChild(1)) : RecordType.VOID_TYPE\r
+ );\r
+ }\r
+ return new UnionType(components);\r
+ }\r
+\r
+ private Datatype translateRecordType(Tree tree) {\r
+ Component[] components = new Component[tree.getChildCount()];\r
+ for(int i=0;i<components.length;++i) {\r
+ Tree c = tree.getChild(i);\r
+ components[i] = new Component(\r
+ c.getChild(0).getText(), \r
+ translate(c.getChild(1))\r
+ );\r
+ }\r
+ return new RecordType(false, components);\r
+ }\r
+ \r
+ public static void printTree(int indent, Tree tree) {\r
+ for(int i=0;i<indent;++i)\r
+ System.out.print(" ");\r
+ System.out.println(tree.getText());\r
+ for(int i=0;i<tree.getChildCount();++i)\r
+ printTree(indent+1, tree.getChild(i));\r
+ }\r
+ \r
+ private void error(Tree tree, String description) { \r
+ problems.add(new Problem(\r
+ ANTLRUtils.location(source, tree), \r
+ description\r
+ ));\r
+ }\r
+}\r