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