OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 """Translate parse tree to Mojom IR""" | |
7 | |
8 | |
9 import os | |
10 import sys | |
11 | |
12 | |
13 def MapTree(func, tree, name): | |
14 if not tree: | |
15 return [] | |
16 return [func(subtree) for subtree in tree if subtree[0] == name] | |
17 | |
18 def MapKind(kind): | |
19 map_to_kind = { 'bool': 'b', | |
20 'int8': 'i8', | |
21 'int16': 'i16', | |
22 'int32': 'i32', | |
23 'int64': 'i64', | |
24 'uint8': 'u8', | |
25 'uint16': 'u16', | |
26 'uint32': 'u32', | |
27 'uint64': 'u64', | |
28 'float': 'f', | |
29 'double': 'd', | |
30 'string': 's', | |
31 'handle': 'h', | |
32 'handle<data_pipe_consumer>': 'h:d:c', | |
33 'handle<data_pipe_producer>': 'h:d:p', | |
34 'handle<message_pipe>': 'h:m', | |
35 'handle<shared_buffer>': 'h:s'} | |
36 if kind.endswith('[]'): | |
37 return 'a:' + MapKind(kind[0:len(kind)-2]) | |
38 if kind in map_to_kind: | |
39 return map_to_kind[kind] | |
40 return 'x:' + kind | |
41 | |
42 def MapOrdinal(ordinal): | |
43 if ordinal == None: | |
44 return None | |
45 return int(ordinal[1:]) # Strip leading '@' | |
46 | |
47 def GetAttribute(attributes, name): | |
48 out = None | |
49 if attributes: | |
50 for attribute in attributes: | |
51 if attribute[0] == 'ATTRIBUTE' and attribute[1] == name: | |
52 out = attribute[2] | |
53 return out | |
54 | |
55 def MapField(tree): | |
56 return {'name': tree[2], | |
57 'kind': MapKind(tree[1]), | |
58 'ordinal': MapOrdinal(tree[3]), | |
59 'default': tree[4]} | |
60 | |
61 def MapParameter(tree): | |
62 return {'name': tree[2], | |
63 'kind': MapKind(tree[1]), | |
64 'ordinal': MapOrdinal(tree[3])} | |
65 | |
66 def MapMethod(tree): | |
67 method = {'name': tree[1], | |
68 'parameters': MapTree(MapParameter, tree[2], 'PARAM'), | |
69 'ordinal': MapOrdinal(tree[3])} | |
70 if tree[4] != None: | |
71 method['response_parameters'] = MapTree(MapParameter, tree[4], 'PARAM') | |
72 return method | |
73 | |
74 def MapEnumField(tree): | |
75 return {'name': tree[1], | |
76 'value': tree[2]} | |
77 | |
78 def MapStruct(tree): | |
79 struct = {} | |
80 struct['name'] = tree[1] | |
81 # TODO(darin): Add support for |attributes| | |
82 #struct['attributes'] = MapAttributes(tree[2]) | |
83 struct['fields'] = MapTree(MapField, tree[3], 'FIELD') | |
84 struct['enums'] = MapTree(MapEnum, tree[3], 'ENUM') | |
85 return struct | |
86 | |
87 def MapInterface(tree): | |
88 interface = {} | |
89 interface['name'] = tree[1] | |
90 interface['peer'] = GetAttribute(tree[2], 'Peer') | |
91 interface['methods'] = MapTree(MapMethod, tree[3], 'METHOD') | |
92 interface['enums'] = MapTree(MapEnum, tree[3], 'ENUM') | |
93 return interface | |
94 | |
95 def MapEnum(tree): | |
96 enum = {} | |
97 enum['name'] = tree[1] | |
98 enum['fields'] = MapTree(MapEnumField, tree[2], 'ENUM_FIELD') | |
99 return enum | |
100 | |
101 def MapModule(tree, name): | |
102 mojom = {} | |
103 mojom['name'] = name | |
104 mojom['namespace'] = tree[1] | |
105 mojom['structs'] = MapTree(MapStruct, tree[2], 'STRUCT') | |
106 mojom['interfaces'] = MapTree(MapInterface, tree[2], 'INTERFACE') | |
107 mojom['enums'] = MapTree(MapEnum, tree[2], 'ENUM') | |
108 return mojom | |
109 | |
110 def MapImport(tree): | |
111 import_item = {} | |
112 import_item['filename'] = tree[1] | |
113 return import_item | |
114 | |
115 | |
116 class MojomBuilder(): | |
117 def __init__(self): | |
118 self.mojom = {} | |
119 | |
120 def Build(self, tree, name): | |
121 modules = [MapModule(item, name) | |
122 for item in tree if item[0] == 'MODULE'] | |
123 if len(modules) != 1: | |
124 raise Exception('A mojom file must contain exactly 1 module.') | |
125 self.mojom = modules[0] | |
126 self.mojom['imports'] = MapTree(MapImport, tree, 'IMPORT') | |
127 return self.mojom | |
128 | |
129 | |
130 def Translate(tree, name): | |
131 return MojomBuilder().Build(tree, name) | |
132 | |
133 | |
134 def Main(): | |
135 if len(sys.argv) < 2: | |
136 print("usage: %s filename" % (sys.argv[0])) | |
137 sys.exit(1) | |
138 tree = eval(open(sys.argv[1]).read()) | |
139 name = os.path.splitext(os.path.basename(sys.argv[1]))[0] | |
140 result = Translate(tree, name) | |
141 print(result) | |
142 | |
143 | |
144 if __name__ == '__main__': | |
145 Main() | |
OLD | NEW |