-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpiqic-python
executable file
·125 lines (87 loc) · 2.61 KB
/
piqic-python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python
import os
import sys
import json
import pprint
import piq
# variant item, tag, value
def vi(variant):
return variant.items()[0]
def vt(variant):
return vi(variant)[0]
def vv(variant):
return vi(variant)[1]
class Piqi(object):
typedef_list = []
index = {}
def __init__(self, piqi_json):
self.typedef_list = piqi_json.get('typedef', [])
self.index = {}
for x in self.typedef_list:
type_tag, typedef = vi(x)
name = typedef['name']
self.index[name] = (type_tag, typedef)
def print_iolist(l):
def print_iolist_item(x):
if isinstance(x, basestring):
sys.stdout.write(x)
elif isinstance(x, list):
print_iolist(x)
else:
assert False
for x in l:
print_iolist_item(x)
def gen_types_piqi(piqi):
return [gen_types_typedef(piqi, x) for x in piqi.typedef_list]
def gen_types_typedef(piqi, x):
tag, value = vi(x)
name = value['name']
# TODO: snake to CamelCase
pyname = gen_name(name)
# TODO, FIXME: unalias
piqi_class = 'Piqi.' + tag.capitalize()
return [
'class ', pyname, '(', piqi_class, '): pass\n'
]
def gen_parse_piqi(piqi):
return [gen_parse_typedef(piqi, x) for x in piqi.typedef_list]
def gen_parse_typedef(piqi, x):
tag, value = vi(x)
name = value['name']
pyname = gen_name(name)
return [
'def parse_', pyname, '(x, **kwargs):\n'
' return parse(x, "', name, '", **kwargs)\n'
]
def gen_name(x):
return x.replace('-', '_')
def parse_piqi_bundle(json_data):
return json_data
def main():
filename = sys.argv[1]
piqi_executable = os.environ.get('PIQI', 'piqi')
command = piqi_executable + ' compile -t json ' + filename
data = os.popen(command).read()
piqi_bundle_json = json.loads(data)
# TODO, XXX: support imported specs? potentially, via nested classes each
# corresponding to a piqi module
piqi_json = piqi_bundle_json['piqi'][0]
piqi = Piqi(piqi_json)
code = [
'import piqi\n',
'\n',
'typedef_index =\\\n', pprint.pformat(piqi.index), '\n'
'\n',
# TODO, XXX: do we actually need to type each parsed value to its own
# class? We can do it if necessary by including classes in the index
#
#gen_types_piqi(piqi),
#'\n',
'def parse(x, typename, format="piq"):\n',
' return piqi.parse(x, __name__, typename, format)\n',
'\n',
gen_parse_piqi(piqi),
]
print_iolist(code)
if __name__ == '__main__':
main()