-
Notifications
You must be signed in to change notification settings - Fork 0
/
load.py
143 lines (110 loc) · 3.43 KB
/
load.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
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Files
from os import path
import yaml
import math
def readMultiAST(paths, includeHeader):
return [readAST(path.replace('\\', '/'), includeHeader) for path in paths]
def readAST(configPath, includeHeader):
print("File: " + configPath)
file = open(configPath)
structs = yaml.load(file, Loader=yaml.FullLoader)
basepath, _ = path.splitext(configPath)
return prepareAST(structs, basepath, includeHeader)
# Prepare for generation
def popOr(dict, key, default):
if key in dict:
return dict.pop(key)
return default
def mustExist(dict, key, default):
if not key in dict:
dict[key] = default
def moveFlags(key, struct):
splitted = key.split('@')
for flag in splitted[1:]:
if not "_flags" in struct:
struct["_flags"] = []
struct["_flags"].append(flag.strip())
return splitted[0].strip()
def prepareAST(full, basepath, includeHeader):
config = popOr(full, 'config', {})
structs = {}
for key in full:
structName = moveFlags(key, full[key])
print(" " + structName)
structs[structName] = prepareStruct(full[key])
config['pragma_once'] = basepath.replace('.', '_').replace('/', '_').replace('\\', '_')
mustExist(config, 'fwd_decl', [])
mustExist(config, 'cpp_incl', [])
mustExist(config, 'hpp_incl', [])
config["hpp_incl"].append(includeHeader)
return {
'config': config,
'structs': structs,
'filename': path.basename(basepath),
}
def prepareStruct(struct):
if struct is None or type(struct) is str:
struct = {}
cpp_only = popOr(struct, '_cpp_only', {})
methods = popOr(struct, '_methods', [])
hash = popOr(struct, '_hash', None)
flags = popOr(struct, '_flags', [])
nr_of_vars = len(struct) + len(cpp_only)
dirty_flags_type = "uint"
if nr_of_vars > 8:
dirty_flags_type += str(2**(math.ceil(math.log(nr_of_vars, 2))))
else:
dirty_flags_type += "8"
return {
'flags': flagDict(flags),
'expose': prepareVars(struct),
'cpp_only': prepareVars(cpp_only),
'methods': methods,
'hash': hash,
'dirty_flags_type': dirty_flags_type
}
def flagDict(flags):
dict = {
'json_with_keys': False,
'not_a_component': False,
'dirtyable': False,
}
for flag in flags:
if not flag in dict:
raise Exception('Invalid flag: ' + flag)
dict[flag] = True
return dict
class Field:
def __init__(self, name, typ, default=None):
self.name = name
self.typ = typ
self.default = default
def __hash__(self):
return self.name.__hash__()
def __repr__(self):
return "Field {{name: '{}', typ: '{}', default: '{}'}}".format(self.name, self.typ, self.default)
def prepareVars(dict):
prepared = []
for key, value in dict.items():
if type(value) is list:
typ, default = value
prepared.append(
Field(key, fixTyp(typ), fixDefault(typ, default)))
else:
prepared.append(
Field(key, fixTyp(value)))
return prepared
def fixDefault(typ, str):
if typ == "string":
return '"{}"'.format(str)
if str is False:
return 'false'
if str is True:
return 'true'
if str is None:
return 'NULL'
return str
def fixTyp(typ):
if typ == "string":
return 'std::string'
return typ