12 lisp_name_t[*] lisp_names;
15 string[string] type_map = {
17 "nlambda" => "NLAMBDA",
19 "f_lambda" => "F_LAMBDA",
21 "feature" => "feature",
25 make_one_lisp(string token)
27 string[*] bits = String::split(token, "@");
28 string name = bits[0];
29 string feature = "all";
33 return (lisp_name_t) {.name = name, .feature = feature };
37 make_lisp(string[*] tokens)
39 lisp_name_t[...] lisp = {};
42 return (lisp_name_t[1]) { make_one_lisp(tokens[dim(tokens) - 1]) };
43 return (lisp_name_t[dim(tokens)-3]) { [i] = make_one_lisp(tokens[i+3]) };
47 read_builtin(file f) {
48 string line = File::fgets(f);
49 string[*] tokens = String::wordsplit(line, " \t");
52 .feature = dim(tokens) > 0 ? tokens[0] : "#",
53 .type = dim(tokens) > 1 ? type_map[tokens[1]] : "#",
54 .c_name = dim(tokens) > 2 ? tokens[2] : "#",
55 .lisp_names = make_lisp(tokens),
60 read_builtins(file f) {
61 builtin_t[...] builtins = {};
63 while (!File::end(f)) {
64 builtin_t b = read_builtin(f);
67 builtins[dim(builtins)] = b;
73 dump_ifdef(builtin_t builtin)
75 if (builtin.feature != "all")
76 printf("#ifdef AO_SCHEME_FEATURE_%s\n", builtin.feature);
80 dump_endif(builtin_t builtin)
82 if (builtin.feature != "all")
83 printf("#endif /* AO_SCHEME_FEATURE_%s */\n", builtin.feature);
86 bool is_atom(builtin_t b) = b.type == "atom";
88 bool is_func(builtin_t b) = b.type != "atom" && b.type != "feature";
90 bool is_feature(builtin_t b) = b.type == "feature";
93 dump_ids(builtin_t[*] builtins) {
94 printf("#ifdef AO_SCHEME_BUILTIN_ID\n");
95 printf("#undef AO_SCHEME_BUILTIN_ID\n");
96 printf("enum ao_scheme_builtin_id {\n");
97 for (int i = 0; i < dim(builtins); i++)
98 if (is_func(builtins[i])) {
99 dump_ifdef(builtins[i]);
100 printf("\tbuiltin_%s,\n", builtins[i].c_name);
101 dump_endif(builtins[i]);
103 printf("\t_builtin_last\n");
105 printf("#endif /* AO_SCHEME_BUILTIN_ID */\n");
109 dump_casename(builtin_t[*] builtins) {
110 printf("#ifdef AO_SCHEME_BUILTIN_CASENAME\n");
111 printf("#undef AO_SCHEME_BUILTIN_CASENAME\n");
112 printf("static char *ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {\n");
113 printf("\tswitch(b) {\n");
114 for (int i = 0; i < dim(builtins); i++)
115 if (is_func(builtins[i])) {
116 dump_ifdef(builtins[i]);
117 printf("\tcase builtin_%s: return ao_scheme_poly_atom(_atom(\"%s\"))->name;\n",
118 builtins[i].c_name, builtins[i].lisp_names[0].name);
119 dump_endif(builtins[i]);
121 printf("\tdefault: return (char *) \"???\";\n");
124 printf("#endif /* AO_SCHEME_BUILTIN_CASENAME */\n");
128 cify_lisp(string l) {
129 for (int j = 0; j < String::length(l); j++) {
131 if (Ctype::isalnum(c) || c == '_')
139 dump_arrayname(builtin_t[*] builtins) {
140 printf("#ifdef AO_SCHEME_BUILTIN_ARRAYNAME\n");
141 printf("#undef AO_SCHEME_BUILTIN_ARRAYNAME\n");
142 printf("static const ao_poly builtin_names[] = {\n");
143 for (int i = 0; i < dim(builtins); i++) {
144 if (is_func(builtins[i])) {
145 dump_ifdef(builtins[i]);
146 printf("\t[builtin_%s] = _ao_scheme_atom_",
148 cify_lisp(builtins[i].lisp_names[0].name);
150 dump_endif(builtins[i]);
154 printf("#endif /* AO_SCHEME_BUILTIN_ARRAYNAME */\n");
158 dump_funcs(builtin_t[*] builtins) {
159 printf("#ifdef AO_SCHEME_BUILTIN_FUNCS\n");
160 printf("#undef AO_SCHEME_BUILTIN_FUNCS\n");
161 printf("const ao_scheme_func_t ao_scheme_builtins[] = {\n");
162 for (int i = 0; i < dim(builtins); i++) {
163 if (is_func(builtins[i])) {
164 dump_ifdef(builtins[i]);
165 printf("\t[builtin_%s] = ao_scheme_do_%s,\n",
168 dump_endif(builtins[i]);
172 printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
176 dump_decls(builtin_t[*] builtins) {
177 printf("#ifdef AO_SCHEME_BUILTIN_DECLS\n");
178 printf("#undef AO_SCHEME_BUILTIN_DECLS\n");
179 for (int i = 0; i < dim(builtins); i++) {
180 if (is_func(builtins[i])) {
181 dump_ifdef(builtins[i]);
183 printf("ao_scheme_do_%s(struct ao_scheme_cons *cons);\n",
185 dump_endif(builtins[i]);
188 printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
192 dump_consts(builtin_t[*] builtins) {
193 printf("#ifdef AO_SCHEME_BUILTIN_CONSTS\n");
194 printf("#undef AO_SCHEME_BUILTIN_CONSTS\n");
195 printf("struct builtin_func funcs[] = {\n");
196 for (int i = 0; i < dim(builtins); i++) {
197 if (is_func(builtins[i])) {
198 dump_ifdef(builtins[i]);
199 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
200 string feature = builtins[i].feature;
201 if (builtins[i].lisp_names[j].feature != "all")
202 feature = builtins[i].lisp_names[j].feature;
203 printf ("\t{ .feature = \"%s\", .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
205 builtins[i].lisp_names[j].name,
209 dump_endif(builtins[i]);
213 printf("#endif /* AO_SCHEME_BUILTIN_CONSTS */\n");
217 dump_atoms(builtin_t[*] builtins) {
218 printf("#ifdef AO_SCHEME_BUILTIN_ATOMS\n");
219 printf("#undef AO_SCHEME_BUILTIN_ATOMS\n");
220 for (int i = 0; i < dim(builtins); i++) {
221 if (!is_feature(builtins[i])) {
222 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
223 printf("#define _ao_scheme_atom_");
224 cify_lisp(builtins[i].lisp_names[j].name);
225 printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j].name);
229 printf("#endif /* AO_SCHEME_BUILTIN_ATOMS */\n");
233 dump_atom_names(builtin_t[*] builtins) {
234 printf("#ifdef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
235 printf("#undef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
236 printf("static struct builtin_atom atoms[] = {\n");
237 for (int i = 0; i < dim(builtins); i++) {
238 if (is_atom(builtins[i])) {
239 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
240 string feature = builtins[i].feature;
241 if (builtins[i].lisp_names[j].feature != "all")
242 feature = builtins[i].lisp_names[j].feature;
243 printf("\t{ .feature = \"%s\", .name = \"%s\" },\n",
245 builtins[i].lisp_names[j].name);
250 printf("#endif /* AO_SCHEME_BUILTIN_ATOM_NAMES */\n");
254 dump_syntax_atoms(builtin_t[*] builtins) {
255 printf("#ifdef AO_SCHEME_BUILTIN_SYNTAX_ATOMS\n");
256 printf("#undef AO_SCHEME_BUILTIN_SYNTAX_ATOMS\n");
257 printf("static const char *syntax_atoms[] = {\n");
258 for (int i = 0; i < dim(builtins); i++) {
259 if (is_atom(builtins[i])) {
260 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
261 printf("\t\"%s\",\n", builtins[i].lisp_names[j].name);
266 printf("#endif /* AO_SCHEME_BUILTIN_SYNTAX_ATOMS */\n");
270 has_feature(string[*] features, string feature)
272 for (int i = 0; i < dim(features); i++)
273 if (features[i] == feature)
279 dump_features(builtin_t[*] builtins) {
280 string[...] features = {};
281 printf("#ifdef AO_SCHEME_BUILTIN_FEATURES\n");
282 for (int i = 0; i < dim(builtins); i++) {
283 if (builtins[i].feature != "all") {
284 string feature = builtins[i].feature;
285 if (!has_feature(features, feature)) {
286 features[dim(features)] = feature;
287 printf("#ifndef AO_SCHEME_NO_FEATURE_%s\n", feature);
288 printf("#define AO_SCHEME_FEATURE_%s\n", feature);
289 printf("#endif /* AO_SCHEME_NO_FEATURE_%s */\n", feature);
293 printf("#endif /* AO_SCHEME_BUILTIN_FEATURES */\n");
298 File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
301 twixt(file f = File::open(argv[1], "r"); File::close(f)) {
302 builtin_t[*] builtins = read_builtins(f);
304 printf("/* %d builtins */\n", dim(builtins));
306 dump_casename(builtins);
307 dump_arrayname(builtins);
308 dump_funcs(builtins);
309 dump_decls(builtins);
310 dump_consts(builtins);
311 dump_atoms(builtins);
312 dump_atom_names(builtins);
313 dump_syntax_atoms(builtins);
314 dump_features(builtins);