-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackend_generator.py
More file actions
122 lines (109 loc) · 4.29 KB
/
backend_generator.py
File metadata and controls
122 lines (109 loc) · 4.29 KB
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
import sys
import re
from itertools import chain
templ_c = """\
/* generated by {generated_by} */
#include "{name}_backend_generated.h"
const uint8_t m4_{name}_backend_code[{code_array_size}] = {{
{code_array_content}
}};
const uint8_t m4_{name}_backend_chore_a[{a_size}] = {{
{a_code} /* {a_src} */
}};
const uint8_t m4_{name}_backend_chore_b[{b_size}] = {{
{b_code} /* {b_src} */
}};
const uint8_t m4_{name}_backend_chore_y[{y_size}] = {{
{y_code} /* {y_src} */
}};
const uint8_t m4_{name}_backend_chore_z[{z_size}] = {{
{z_code} /* {z_src} */
}};
const m4_backend_table_entry_t m4_{name}_backend_table[{code_table_count}] = {{
{code_table_content}
}};
"""
templ_h = """\
/* generated by {generated_by} */
#include "mcp_forth.h"
extern const uint8_t m4_{name}_backend_chore_a[{a_size}];
extern const uint8_t m4_{name}_backend_chore_b[{b_size}];
extern const uint8_t m4_{name}_backend_chore_y[{y_size}];
extern const uint8_t m4_{name}_backend_chore_z[{z_size}];
extern const uint8_t m4_{name}_backend_code[{code_array_size}];
extern const m4_backend_table_entry_t m4_{name}_backend_table[{code_table_count}];
"""
def generate_builtins(backend_name, builtins, elidables, src_to_code_cb):
a_code = src_to_code_cb(elidables[0][0] + "\n")
b_code = src_to_code_cb(elidables[1][0] + "\n")
y_code = src_to_code_cb(elidables[2][0] + "\n")
z_code = src_to_code_cb(elidables[3][0] + "\n")
code_content = []
table_content = []
code_cumulative_len = 0
for word, flags, src in builtins:
src_lines = list(line for line in src.splitlines() if line.strip())
flag_a = len(src_lines) > 0 and re.fullmatch(elidables[0][1], src_lines[0]) is not None
flag_b = flag_a and len(src_lines) > 1 and re.fullmatch(elidables[1][1], src_lines[1]) is not None
flag_clob = flag_b and "clobber" in flags
if not flag_clob and "clobber" in flags:
print("warning: clobber flag given but criteria not met")
flag_z = len(src_lines) > 0 and re.fullmatch(elidables[3][1], src_lines[-1]) is not None
flag_y = flag_z and len(src_lines) > 1 and re.fullmatch(elidables[2][1], src_lines[-2]) is not None
if(flag_a): del src_lines[0]
if(flag_b): del src_lines[0]
if(flag_z): del src_lines[-1]
if(flag_y): del src_lines[-1]
src_reduced = "".join(line + '\n' for line in src_lines)
code = src_to_code_cb(src_reduced)
code_content.append(
f" /* {word} */ "
+ "".join(f"0x{b:02x}," for b in code)
)
pos_str = f"{code_cumulative_len},".ljust(7)
len_str = f"{len(code)},".ljust(6)
code_cumulative_len += len(code)
flags_str = " | ".join(chain.from_iterable((
("M4_BACKEND_FLAG_A",) if flag_a else (),
("M4_BACKEND_FLAG_B",) if flag_b else (),
("M4_BACKEND_FLAG_CLOB",) if flag_clob else (),
("M4_BACKEND_FLAG_Y",) if flag_y else (),
("M4_BACKEND_FLAG_Z",) if flag_z else (),
)))
table_content.append(
f" {{{pos_str}{len_str}{flags_str}}},"
)
c = templ_c.format(
generated_by = sys.argv[0],
name = backend_name,
code_array_size = code_cumulative_len,
code_array_content = "\n".join(code_content),
a_size = len(a_code),
a_code = ",".join(f"0x{b:02x}" for b in a_code),
a_src = elidables[0][0],
b_size = len(b_code),
b_code = ",".join(f"0x{b:02x}" for b in b_code),
b_src = elidables[1][0],
y_size = len(y_code),
y_code = ",".join(f"0x{b:02x}" for b in y_code),
y_src = elidables[2][0],
z_size = len(z_code),
z_code = ",".join(f"0x{b:02x}" for b in z_code),
z_src = elidables[3][0],
code_table_count = len(table_content),
code_table_content = "\n".join(table_content)
)
h = templ_h.format(
generated_by = sys.argv[0],
name = backend_name,
a_size = len(a_code),
b_size = len(b_code),
y_size = len(y_code),
z_size = len(z_code),
code_array_size = code_cumulative_len,
code_table_count = len(table_content)
)
with open(f"{backend_name}_backend_generated.c", "w") as f:
f.write(c)
with open(f"{backend_name}_backend_generated.h", "w") as f:
f.write(h)