]> gerrit.simantics Code Review - simantics/platform.git/blob
62b6bf616cf8525b49640c125bab53f87fad3553
[simantics/platform.git] /
1 package org.simantics.graph.compiler.internal.translation;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import java.util.Collection;
6
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;
26
27 public class DataTypeTranslator {
28
29         ISource source;
30         Collection<Problem> problems;
31                 
32         public DataTypeTranslator(ISource source, Collection<Problem> problems) {
33                 this.source = source;
34                 this.problems = problems;
35         }
36
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);
49                 default:
50                         printTree(0, tree);
51                         throw new IllegalArgumentException("The argument is not a data type AST");
52                 }
53         }
54
55         private Datatype translateArrayType(Tree tree) {
56                 return new ArrayType(translate(tree.getChild(0)));
57         }
58
59         private Datatype translateTupleType(Tree tree) {
60                 int count = tree.getChildCount(); 
61                 if(count == 1)
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(
66                                         Integer.toString(i),
67                                         translate(tree.getChild(i))
68                                 );
69                 }
70                 return new RecordType(false, components);               
71         }
72         
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) {
78                                 result.put(
79                                                 child.getChild(0).getText(),
80                                                 convertValue(child.getChild(1))
81                                 );
82                         }
83                 }
84                 return result;
85         }
86         
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);
93                 }
94                 case GraphParser.INT:
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();
99                 default:
100                         throw new IllegalArgumentException();
101                 }
102         }
103
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);
110                         return new ByteType(
111                                         annotations.get("unit"),
112                                         annotations.get("range")
113                         );
114                 }
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")
120                         );
121                 }
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")
127                         );
128                 }
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")
134                         );
135                 }
136                 else if(name.equals("Long")) {
137                         THashMap<String,String> annotations = getAnnotations(tree);
138                         return new LongType(
139                                         annotations.get("unit"),
140                                         annotations.get("range")
141                         );
142                 }
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")
149                         );
150                 }
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);
159                 else { 
160                         error(tree, "Invalid data type " + name + ".");
161                         return null;
162                 }
163         }
164
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
172                                 );
173                 }
174                 return new UnionType(components);
175         }
176
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))
184                                 );
185                 }
186                 return new RecordType(false, components);
187         }
188         
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));
195         }
196         
197         private void error(Tree tree, String description) { 
198                 problems.add(new Problem(
199                                 ANTLRUtils.location(source, tree), 
200                                 description
201                         ));
202         }
203 }