|
1 | | -import sys |
2 | | -import os.path |
3 | | -import glob |
4 | | -import re |
5 | | -import json |
6 | | - |
7 | | -BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") |
8 | | -END_TEMPLATE = re.compile(r"^\*/\s*$") |
9 | | - |
10 | | -def expand_template_params(args, param_arg_map): |
11 | | - '''Given a list of template arguments that may reference template parameters |
12 | | - of the current template, return a new list of template arguments with each |
13 | | - parameter use replaced with the appropriate fully-qualified argument for |
14 | | - that parameter.''' |
15 | | - result = [] |
16 | | - for arg in args: |
17 | | - if arg in param_arg_map: |
18 | | - result.append(param_arg_map[arg]) |
19 | | - else: |
20 | | - result.append(arg) |
21 | | - |
22 | | - return result |
23 | | - |
24 | | -def find_instantiation(module, args, templates): |
25 | | - '''Given a template module and a set of template arguments, find the module |
26 | | - name of the instantiation of that module with those arguments.''' |
27 | | - template = templates[module] |
28 | | - for instantiation in template["template_def"]["instantiations"]: |
29 | | - if instantiation["args"] == args: |
30 | | - return instantiation["name"] |
31 | | - return None |
32 | | - |
33 | | -def instantiate_template(template, instantiation, root, templates): |
34 | | - '''Create a single instantiation of a template.''' |
35 | | - template_def = template["template_def"] |
36 | | - output_components = instantiation["name"].split(".") |
37 | | - output_path = root |
38 | | - for component in output_components: |
39 | | - output_path = os.path.join(output_path, component) |
40 | | - output_path = output_path + ".qll" |
41 | | - with open(output_path, "w") as output: |
42 | | - output.write( |
43 | | -""" |
44 | | -/* |
45 | | - * THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. |
46 | | - * DO NOT EDIT MANUALLY. |
47 | | - */ |
48 | | -
|
49 | | -""" % (template["name"].replace(".", "/") + ".qllt") |
50 | | - ) |
51 | | - param_arg_map = {} |
52 | | - for param_index in range(len(template_def["params"])): |
53 | | - param = template_def["params"][param_index] |
54 | | - arg = instantiation["args"][param_index] |
55 | | - output.write("private import %s as %s // Template parameter\n" % (arg, param)) |
56 | | - param_arg_map[param] = arg |
57 | | - for import_record in template_def["imports"]: |
58 | | - if "access" in import_record: |
59 | | - output.write(import_record["access"] + " ") |
60 | | - imported_module = find_instantiation(import_record["module"], |
61 | | - expand_template_params(import_record["args"], param_arg_map), templates) |
62 | | - output.write("import %s // %s<%s>\n" % |
63 | | - ( |
64 | | - imported_module, |
65 | | - import_record["module"], |
66 | | - ", ".join(import_record["args"]) |
67 | | - ) |
68 | | - ) |
69 | | - |
70 | | - output.writelines(template_def["body_lines"]) |
71 | | - |
72 | | -def generate_instantiations(template, root, templates): |
73 | | - '''Create a .qll source file for each instantiation of the specified template.''' |
74 | | - template_def = template["template_def"] |
75 | | - if "instantiations" in template_def: |
76 | | - for instantiation in template_def["instantiations"]: |
77 | | - instantiate_template(template, instantiation, root, templates) |
78 | | - |
79 | | -def read_template(template_path, module_name): |
80 | | - '''Read a .qllt template file from template_path, using module_name as the |
81 | | - fully qualified name of the module.''' |
82 | | - with open(template_path) as input: |
83 | | - in_template = False |
84 | | - template_text = "" |
85 | | - template_def = None |
86 | | - body_lines = [] |
87 | | - for line in iter(input): |
88 | | - if in_template: |
89 | | - if END_TEMPLATE.match(line): |
90 | | - template_def = json.loads(template_text) |
91 | | - in_template = False |
92 | | - else: |
93 | | - template_text += line |
94 | | - else: |
95 | | - if BEGIN_TEMPLATE.match(line) and not template_def: |
96 | | - in_template = True |
97 | | - else: |
98 | | - body_lines.append(line) |
99 | | - |
100 | | - if template_def: |
101 | | - template_def["body_lines"] = body_lines |
102 | | - |
103 | | - result = { "name": module_name } |
104 | | - if template_def: |
105 | | - result["template_def"] = template_def |
106 | | - return result |
107 | | - |
108 | | -def module_name_from_path_impl(path): |
109 | | - (head, tail) = os.path.split(path) |
110 | | - if head == "": |
111 | | - return tail |
112 | | - else: |
113 | | - return module_name_from_path(head) + "." + tail |
114 | | - |
115 | | -def module_name_from_path(path): |
116 | | - '''Compute the fully qualified name of a module from the path of its .qll[t] |
117 | | - file. The path should be relative to the library root.''' |
118 | | - (module_root, ext) = os.path.splitext(path) |
119 | | - return module_name_from_path_impl(module_root) |
120 | | - |
121 | | -def main(): |
122 | | - templates = {} |
123 | | - |
124 | | - root = sys.argv[1] |
125 | | - for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): |
126 | | - print(template_path) |
127 | | - module_name = module_name_from_path(os.path.relpath(template_path, root)) |
128 | | - print(module_name) |
129 | | - template = read_template(template_path, module_name) |
130 | | - templates[template["name"]] = template |
131 | | - |
132 | | - for name, template in templates.items(): |
133 | | - if "template_def" in template: |
134 | | - generate_instantiations(template, root, templates) |
135 | | - |
136 | | -if __name__ == "__main__": |
137 | | - main() |
| 1 | +import sys |
| 2 | +import os.path |
| 3 | +import glob |
| 4 | +import re |
| 5 | +import json |
| 6 | + |
| 7 | +BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") |
| 8 | +END_TEMPLATE = re.compile(r"^\*/\s*$") |
| 9 | + |
| 10 | +def expand_template_params(args, param_arg_map): |
| 11 | + '''Given a list of template arguments that may reference template parameters |
| 12 | + of the current template, return a new list of template arguments with each |
| 13 | + parameter use replaced with the appropriate fully-qualified argument for |
| 14 | + that parameter.''' |
| 15 | + result = [] |
| 16 | + for arg in args: |
| 17 | + if arg in param_arg_map: |
| 18 | + result.append(param_arg_map[arg]) |
| 19 | + else: |
| 20 | + result.append(arg) |
| 21 | + |
| 22 | + return result |
| 23 | + |
| 24 | +def find_instantiation(module, args, templates): |
| 25 | + '''Given a template module and a set of template arguments, find the module |
| 26 | + name of the instantiation of that module with those arguments.''' |
| 27 | + template = templates[module] |
| 28 | + for instantiation in template["template_def"]["instantiations"]: |
| 29 | + if instantiation["args"] == args: |
| 30 | + return instantiation["name"] |
| 31 | + return None |
| 32 | + |
| 33 | +def instantiate_template(template, instantiation, root, templates): |
| 34 | + '''Create a single instantiation of a template.''' |
| 35 | + template_def = template["template_def"] |
| 36 | + output_components = instantiation["name"].split(".") |
| 37 | + output_path = root |
| 38 | + for component in output_components: |
| 39 | + output_path = os.path.join(output_path, component) |
| 40 | + output_path = output_path + ".qll" |
| 41 | + with open(output_path, "w") as output: |
| 42 | + output.write( |
| 43 | +""" |
| 44 | +/* |
| 45 | + * THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. |
| 46 | + * DO NOT EDIT MANUALLY. |
| 47 | + */ |
| 48 | +
|
| 49 | +""" % (template["name"].replace(".", "/") + ".qllt") |
| 50 | + ) |
| 51 | + param_arg_map = {} |
| 52 | + for param_index in range(len(template_def["params"])): |
| 53 | + param = template_def["params"][param_index] |
| 54 | + arg = instantiation["args"][param_index] |
| 55 | + output.write("private import %s as %s // Template parameter\n" % (arg, param)) |
| 56 | + param_arg_map[param] = arg |
| 57 | + for import_record in template_def["imports"]: |
| 58 | + if "access" in import_record: |
| 59 | + output.write(import_record["access"] + " ") |
| 60 | + imported_module = find_instantiation(import_record["module"], |
| 61 | + expand_template_params(import_record["args"], param_arg_map), templates) |
| 62 | + output.write("import %s // %s<%s>\n" % |
| 63 | + ( |
| 64 | + imported_module, |
| 65 | + import_record["module"], |
| 66 | + ", ".join(import_record["args"]) |
| 67 | + ) |
| 68 | + ) |
| 69 | + |
| 70 | + output.writelines(template_def["body_lines"]) |
| 71 | + |
| 72 | +def generate_instantiations(template, root, templates): |
| 73 | + '''Create a .qll source file for each instantiation of the specified template.''' |
| 74 | + template_def = template["template_def"] |
| 75 | + if "instantiations" in template_def: |
| 76 | + for instantiation in template_def["instantiations"]: |
| 77 | + instantiate_template(template, instantiation, root, templates) |
| 78 | + |
| 79 | +def read_template(template_path, module_name): |
| 80 | + '''Read a .qllt template file from template_path, using module_name as the |
| 81 | + fully qualified name of the module.''' |
| 82 | + with open(template_path) as input: |
| 83 | + in_template = False |
| 84 | + template_text = "" |
| 85 | + template_def = None |
| 86 | + body_lines = [] |
| 87 | + for line in iter(input): |
| 88 | + if in_template: |
| 89 | + if END_TEMPLATE.match(line): |
| 90 | + template_def = json.loads(template_text) |
| 91 | + in_template = False |
| 92 | + else: |
| 93 | + template_text += line |
| 94 | + else: |
| 95 | + if BEGIN_TEMPLATE.match(line) and not template_def: |
| 96 | + in_template = True |
| 97 | + else: |
| 98 | + body_lines.append(line) |
| 99 | + |
| 100 | + if template_def: |
| 101 | + template_def["body_lines"] = body_lines |
| 102 | + |
| 103 | + result = { "name": module_name } |
| 104 | + if template_def: |
| 105 | + result["template_def"] = template_def |
| 106 | + return result |
| 107 | + |
| 108 | +def module_name_from_path_impl(path): |
| 109 | + (head, tail) = os.path.split(path) |
| 110 | + if head == "": |
| 111 | + return tail |
| 112 | + else: |
| 113 | + return module_name_from_path(head) + "." + tail |
| 114 | + |
| 115 | +def module_name_from_path(path): |
| 116 | + '''Compute the fully qualified name of a module from the path of its .qll[t] |
| 117 | + file. The path should be relative to the library root.''' |
| 118 | + (module_root, ext) = os.path.splitext(path) |
| 119 | + return module_name_from_path_impl(module_root) |
| 120 | + |
| 121 | +def main(): |
| 122 | + templates = {} |
| 123 | + |
| 124 | + root = sys.argv[1] |
| 125 | + for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): |
| 126 | + print(template_path) |
| 127 | + module_name = module_name_from_path(os.path.relpath(template_path, root)) |
| 128 | + print(module_name) |
| 129 | + template = read_template(template_path, module_name) |
| 130 | + templates[template["name"]] = template |
| 131 | + |
| 132 | + for name, template in templates.items(): |
| 133 | + if "template_def" in template: |
| 134 | + generate_instantiations(template, root, templates) |
| 135 | + |
| 136 | +if __name__ == "__main__": |
| 137 | + main() |
0 commit comments