-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplate.py
80 lines (60 loc) · 2.13 KB
/
template.py
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
# Rendering
from jinja2 import Environment, FileSystemLoader
import pathlib
env = Environment(
loader=FileSystemLoader(pathlib.Path(__file__).parent.absolute().__str__() + '/templates'),
autoescape=False,
trim_blocks=True,
lstrip_blocks=True,
)
hpptemplate = env.get_template('hpp.jinja')
cpptemplate = env.get_template('cpp.jinja')
def renderStructs(ast):
genStringTrees(ast)
return (hpptemplate.render(structs=ast['structs'], config=ast['config']),
cpptemplate.render(structs=ast['structs'], config=ast['config'], filename=ast['filename']))
def genStringTrees(ast):
for struct in ast['structs'].values():
struct['split'] = stringTree(struct['expose'])
class Bucket:
def __init__(self, mode, index):
self.mode = mode
self.index = index
self.buckets = {}
def insert(self, key, value):
if key not in self.buckets:
self.buckets[key] = []
self.buckets[key].append(value)
def singleton(self):
return len(self.buckets) < 2
def mbsize(self):
return max([len(sbucket) for sbucket in self.buckets.values()])
def stringTree(fields, key=None):
if len(fields) == 0:
return {'mode': 'empty'}
if len(fields) == 1:
return {'mode': 'singleton', 'key': key, 'value': fields[0]}
splits = []
letterSplits(fields, splits)
lengthSplits(fields, splits)
minSplit = min(splits, key=lambda bucket: bucket.mbsize())
return {
'mode': minSplit.mode,
'index': minSplit.index,
'key': key,
'buckets': [stringTree(bucket, key) for key, bucket in minSplit.buckets.items()],
}
def letterSplits(fields, splits):
length = min([len(value.name) for value in fields])
for i in range(length):
bucket = Bucket('letter', i)
for field in fields:
bucket.insert("'" + field.name[i] + "'", field)
if not bucket.singleton():
splits.append(bucket)
def lengthSplits(fields, splits):
bucket = Bucket('length', 0)
for field in fields:
bucket.insert(len(field.name), field)
if not bucket.singleton():
splits.append(bucket)