a4d8326ff904c332624e16e92178e8b764b9f68d
[fw/altos] / src / scheme / ao_scheme_make_builtin
1 #!/usr/bin/nickle
2
3 typedef struct {
4         string  feature;
5         string  type;
6         string  c_name;
7         string[*]       lisp_names;
8 } builtin_t;
9
10 string[string] type_map = {
11         "lambda" => "LAMBDA",
12         "nlambda" => "NLAMBDA",
13         "macro" => "MACRO",
14         "f_lambda" => "F_LAMBDA",
15         "atom" => "atom",
16         "feature" => "feature",
17 };
18
19 string[*]
20 make_lisp(string[*] tokens)
21 {
22         string[...] lisp = {};
23
24         if (dim(tokens) < 4)
25                 return (string[1]) { tokens[dim(tokens) - 1] };
26         return (string[dim(tokens)-3]) { [i] = tokens[i+3] };
27 }
28
29 builtin_t
30 read_builtin(file f) {
31         string  line = File::fgets(f);
32         string[*]       tokens = String::wordsplit(line, " \t");
33
34         return (builtin_t) {
35                 .feature = dim(tokens) > 0 ? tokens[0] : "#",
36                 .type = dim(tokens) > 1 ? type_map[tokens[1]] : "#",
37                 .c_name = dim(tokens) > 2 ? tokens[2] : "#",
38                 .lisp_names = make_lisp(tokens),
39         };
40 }
41
42 builtin_t[*]
43 read_builtins(file f) {
44         builtin_t[...] builtins = {};
45
46         while (!File::end(f)) {
47                 builtin_t       b = read_builtin(f);
48
49                 if (b.type[0] != '#')
50                         builtins[dim(builtins)] = b;
51         }
52         return builtins;
53 }
54
55 void
56 dump_ifdef(builtin_t builtin)
57 {
58         if (builtin.feature != "all")
59                 printf("#ifdef AO_SCHEME_FEATURE_%s\n", builtin.feature);
60 }
61
62 void
63 dump_endif(builtin_t builtin)
64 {
65         if (builtin.feature != "all")
66                 printf("#endif /* AO_SCHEME_FEATURE_%s */\n", builtin.feature);
67 }
68
69 bool is_atom(builtin_t b) = b.type == "atom";
70
71 bool is_func(builtin_t b) = b.type != "atom" && b.type != "feature";
72
73 bool is_feature(builtin_t b) = b.type == "feature";
74
75 void
76 dump_ids(builtin_t[*] builtins) {
77         printf("#ifdef AO_SCHEME_BUILTIN_ID\n");
78         printf("#undef AO_SCHEME_BUILTIN_ID\n");
79         printf("enum ao_scheme_builtin_id {\n");
80         for (int i = 0; i < dim(builtins); i++)
81                 if (is_func(builtins[i])) {
82                         dump_ifdef(builtins[i]);
83                         printf("\tbuiltin_%s,\n", builtins[i].c_name);
84                         dump_endif(builtins[i]);
85                 }
86         printf("\t_builtin_last\n");
87         printf("};\n");
88         printf("#endif /* AO_SCHEME_BUILTIN_ID */\n");
89 }
90
91 void
92 dump_casename(builtin_t[*] builtins) {
93         printf("#ifdef AO_SCHEME_BUILTIN_CASENAME\n");
94         printf("#undef AO_SCHEME_BUILTIN_CASENAME\n");
95         printf("static char *ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {\n");
96         printf("\tswitch(b) {\n");
97         for (int i = 0; i < dim(builtins); i++)
98                 if (is_func(builtins[i])) {
99                         dump_ifdef(builtins[i]);
100                         printf("\tcase builtin_%s: return ao_scheme_poly_atom(_atom(\"%s\"))->name;\n",
101                                builtins[i].c_name, builtins[i].lisp_names[0]);
102                         dump_endif(builtins[i]);
103                 }
104         printf("\tdefault: return (char *) \"???\";\n");
105         printf("\t}\n");
106         printf("}\n");
107         printf("#endif /* AO_SCHEME_BUILTIN_CASENAME */\n");
108 }
109
110 void
111 cify_lisp(string l) {
112         for (int j = 0; j < String::length(l); j++) {
113                 int c= l[j];
114                 if (Ctype::isalnum(c) || c == '_')
115                         printf("%c", c);
116                 else
117                         printf("%02x", c);
118         }
119 }
120
121 void
122 dump_arrayname(builtin_t[*] builtins) {
123         printf("#ifdef AO_SCHEME_BUILTIN_ARRAYNAME\n");
124         printf("#undef AO_SCHEME_BUILTIN_ARRAYNAME\n");
125         printf("static const ao_poly builtin_names[] = {\n");
126         for (int i = 0; i < dim(builtins); i++) {
127                 if (is_func(builtins[i])) {
128                         dump_ifdef(builtins[i]);
129                         printf("\t[builtin_%s] = _ao_scheme_atom_",
130                                builtins[i].c_name);
131                         cify_lisp(builtins[i].lisp_names[0]);
132                         printf(",\n");
133                         dump_endif(builtins[i]);
134                 }
135         }
136         printf("};\n");
137         printf("#endif /* AO_SCHEME_BUILTIN_ARRAYNAME */\n");
138 }
139
140 void
141 dump_funcs(builtin_t[*] builtins) {
142         printf("#ifdef AO_SCHEME_BUILTIN_FUNCS\n");
143         printf("#undef AO_SCHEME_BUILTIN_FUNCS\n");
144         printf("const ao_scheme_func_t ao_scheme_builtins[] = {\n");
145         for (int i = 0; i < dim(builtins); i++) {
146                 if (is_func(builtins[i])) {
147                         dump_ifdef(builtins[i]);
148                         printf("\t[builtin_%s] = ao_scheme_do_%s,\n",
149                                builtins[i].c_name,
150                                builtins[i].c_name);
151                         dump_endif(builtins[i]);
152                 }
153         }
154         printf("};\n");
155         printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
156 }
157
158 void
159 dump_decls(builtin_t[*] builtins) {
160         printf("#ifdef AO_SCHEME_BUILTIN_DECLS\n");
161         printf("#undef AO_SCHEME_BUILTIN_DECLS\n");
162         for (int i = 0; i < dim(builtins); i++) {
163                 if (is_func(builtins[i])) {
164                         dump_ifdef(builtins[i]);
165                         printf("ao_poly\n");
166                         printf("ao_scheme_do_%s(struct ao_scheme_cons *cons);\n",
167                                builtins[i].c_name);
168                         dump_endif(builtins[i]);
169                 }
170         }
171         printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
172 }
173
174 void
175 dump_consts(builtin_t[*] builtins) {
176         printf("#ifdef AO_SCHEME_BUILTIN_CONSTS\n");
177         printf("#undef AO_SCHEME_BUILTIN_CONSTS\n");
178         printf("struct builtin_func funcs[] = {\n");
179         for (int i = 0; i < dim(builtins); i++) {
180                 if (is_func(builtins[i])) {
181                         dump_ifdef(builtins[i]);
182                         for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
183                                 printf ("\t{ .feature = \"%s\", .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
184                                         builtins[i].feature,
185                                         builtins[i].lisp_names[j],
186                                         builtins[i].type,
187                                         builtins[i].c_name);
188                         }
189                         dump_endif(builtins[i]);
190                 }
191         }
192         printf("};\n");
193         printf("#endif /* AO_SCHEME_BUILTIN_CONSTS */\n");
194 }
195
196 void
197 dump_atoms(builtin_t[*] builtins) {
198         printf("#ifdef AO_SCHEME_BUILTIN_ATOMS\n");
199         printf("#undef AO_SCHEME_BUILTIN_ATOMS\n");
200         for (int i = 0; i < dim(builtins); i++) {
201                 if (!is_feature(builtins[i])) {
202                         for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
203                                 printf("#define _ao_scheme_atom_");
204                                 cify_lisp(builtins[i].lisp_names[j]);
205                                 printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j]);
206                         }
207                 }
208         }
209         printf("#endif /* AO_SCHEME_BUILTIN_ATOMS */\n");
210 }
211
212 void
213 dump_atom_names(builtin_t[*] builtins) {
214         printf("#ifdef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
215         printf("#undef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
216         printf("static struct builtin_atom atoms[] = {\n");
217         for (int i = 0; i < dim(builtins); i++) {
218                 if (is_atom(builtins[i])) {
219                         for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
220                                 printf("\t{ .feature = \"%s\", .name = \"%s\" },\n",
221                                        builtins[i].feature,
222                                        builtins[i].lisp_names[j]);
223                         }
224                 }
225         }
226         printf("};\n");
227         printf("#endif /* AO_SCHEME_BUILTIN_ATOM_NAMES */\n");
228 }
229
230 bool
231 has_feature(string[*] features, string feature)
232 {
233         for (int i = 0; i < dim(features); i++)
234                 if (features[i] == feature)
235                         return true;
236         return false;
237 }
238
239 void
240 dump_features(builtin_t[*] builtins) {
241         string[...] features = {};
242         printf("#ifdef AO_SCHEME_BUILTIN_FEATURES\n");
243         for (int i = 0; i < dim(builtins); i++) {
244                 if (builtins[i].feature != "all") {
245                         string feature = builtins[i].feature;
246                         if (!has_feature(features, feature)) {
247                                 features[dim(features)] = feature;
248                                 printf("#define AO_SCHEME_FEATURE_%s\n", feature);
249                         }
250                 }
251         }
252         printf("#endif /* AO_SCHEME_BUILTIN_FEATURES */\n");
253 }
254
255 void main() {
256         if (dim(argv) < 2) {
257                 File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
258                 exit(1);
259         }
260         twixt(file f = File::open(argv[1], "r"); File::close(f)) {
261                 builtin_t[*]    builtins = read_builtins(f);
262
263                 printf("/* %d builtins */\n", dim(builtins));
264                 dump_ids(builtins);
265                 dump_casename(builtins);
266                 dump_arrayname(builtins);
267                 dump_funcs(builtins);
268                 dump_decls(builtins);
269                 dump_consts(builtins);
270                 dump_atoms(builtins);
271                 dump_atom_names(builtins);
272                 dump_features(builtins);
273         }
274 }
275
276 main();