altos/lisp: Finish first pass through r7rs
[fw/altos] / src / lisp / ao_lisp_make_builtin
1 #!/usr/bin/nickle
2
3 typedef struct {
4         string  type;
5         string  c_name;
6         string[*]       lisp_names;
7 } builtin_t;
8
9 string[string] type_map = {
10         "lambda" => "LAMBDA",
11         "nlambda" => "NLAMBDA",
12         "lexpr" => "LEXPR",
13         "macro" => "MACRO",
14         "f_lambda" => "F_LAMBDA",
15         "f_lexpr" => "F_LEXPR",
16 };
17
18 string[*]
19 make_lisp(string[*] tokens)
20 {
21         string[...] lisp = {};
22
23         if (dim(tokens) < 3)
24                 return (string[1]) { tokens[dim(tokens) - 1] };
25         return (string[dim(tokens)-2]) { [i] = tokens[i+2] };
26 }
27
28 builtin_t
29 read_builtin(file f) {
30         string  line = File::fgets(f);
31         string[*]       tokens = String::wordsplit(line, " \t");
32
33         return (builtin_t) {
34                 .type = dim(tokens) > 0 ? type_map[tokens[0]] : "#",
35                 .c_name = dim(tokens) > 1 ? tokens[1] : "#",
36                 .lisp_names = make_lisp(tokens),
37         };
38 }
39
40 builtin_t[*]
41 read_builtins(file f) {
42         builtin_t[...] builtins = {};
43
44         while (!File::end(f)) {
45                 builtin_t       b = read_builtin(f);
46
47                 if (b.type[0] != '#')
48                         builtins[dim(builtins)] = b;
49         }
50         return builtins;
51 }
52
53 void
54 dump_ids(builtin_t[*] builtins) {
55         printf("#ifdef AO_LISP_BUILTIN_ID\n");
56         printf("#undef AO_LISP_BUILTIN_ID\n");
57         printf("enum ao_lisp_builtin_id {\n");
58         for (int i = 0; i < dim(builtins); i++)
59                 printf("\tbuiltin_%s,\n", builtins[i].c_name);
60         printf("\t_builtin_last\n");
61         printf("};\n");
62         printf("#endif /* AO_LISP_BUILTIN_ID */\n");
63 }
64
65 void
66 dump_casename(builtin_t[*] builtins) {
67         printf("#ifdef AO_LISP_BUILTIN_CASENAME\n");
68         printf("#undef AO_LISP_BUILTIN_CASENAME\n");
69         printf("static char *ao_lisp_builtin_name(enum ao_lisp_builtin_id b) {\n");
70         printf("\tswitch(b) {\n");
71         for (int i = 0; i < dim(builtins); i++)
72                 printf("\tcase builtin_%s: return ao_lisp_poly_atom(_atom(\"%s\"))->name;\n",
73                        builtins[i].c_name, builtins[i].lisp_names[0]);
74         printf("\tdefault: return \"???\";\n");
75         printf("\t}\n");
76         printf("}\n");
77         printf("#endif /* AO_LISP_BUILTIN_CASENAME */\n");
78 }
79
80 void
81 cify_lisp(string l) {
82         for (int j = 0; j < String::length(l); j++) {
83                 int c= l[j];
84                 if (Ctype::isalnum(c) || c == '_')
85                         printf("%c", c);
86                 else
87                         printf("%02x", c);
88         }
89 }
90
91 void
92 dump_arrayname(builtin_t[*] builtins) {
93         printf("#ifdef AO_LISP_BUILTIN_ARRAYNAME\n");
94         printf("#undef AO_LISP_BUILTIN_ARRAYNAME\n");
95         printf("static const ao_poly builtin_names[] = {\n");
96         for (int i = 0; i < dim(builtins); i++) {
97                 printf("\t[builtin_%s] = _ao_lisp_atom_",
98                        builtins[i].c_name);
99                 cify_lisp(builtins[i].lisp_names[0]);
100                 printf(",\n");
101         }
102         printf("};\n");
103         printf("#endif /* AO_LISP_BUILTIN_ARRAYNAME */\n");
104 }
105
106 void
107 dump_funcs(builtin_t[*] builtins) {
108         printf("#ifdef AO_LISP_BUILTIN_FUNCS\n");
109         printf("#undef AO_LISP_BUILTIN_FUNCS\n");
110         printf("const ao_lisp_func_t ao_lisp_builtins[] = {\n");
111         for (int i = 0; i < dim(builtins); i++) {
112                 printf("\t[builtin_%s] = ao_lisp_do_%s,\n",
113                        builtins[i].c_name,
114                        builtins[i].c_name);
115         }
116         printf("};\n");
117         printf("#endif /* AO_LISP_BUILTIN_FUNCS */\n");
118 }
119
120 void
121 dump_decls(builtin_t[*] builtins) {
122         printf("#ifdef AO_LISP_BUILTIN_DECLS\n");
123         printf("#undef AO_LISP_BUILTIN_DECLS\n");
124         for (int i = 0; i < dim(builtins); i++) {
125                 printf("ao_poly\n");
126                 printf("ao_lisp_do_%s(struct ao_lisp_cons *cons);\n",
127                        builtins[i].c_name);
128         }
129         printf("#endif /* AO_LISP_BUILTIN_DECLS */\n");
130 }
131
132 void
133 dump_consts(builtin_t[*] builtins) {
134         printf("#ifdef AO_LISP_BUILTIN_CONSTS\n");
135         printf("#undef AO_LISP_BUILTIN_CONSTS\n");
136         printf("struct builtin_func funcs[] = {\n");
137         for (int i = 0; i < dim(builtins); i++) {
138                 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
139                         printf ("\t{ .name = \"%s\", .args = AO_LISP_FUNC_%s, .func = builtin_%s },\n",
140                                 builtins[i].lisp_names[j],
141                                 builtins[i].type,
142                                 builtins[i].c_name);
143                 }
144         }
145         printf("};\n");
146         printf("#endif /* AO_LISP_BUILTIN_CONSTS */\n");
147 }
148
149 void
150 dump_atoms(builtin_t[*] builtins) {
151         printf("#ifdef AO_LISP_BUILTIN_ATOMS\n");
152         printf("#undef AO_LISP_BUILTIN_ATOMS\n");
153         for (int i = 0; i < dim(builtins); i++) {
154                 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
155                         printf("#define _ao_lisp_atom_");
156                         cify_lisp(builtins[i].lisp_names[j]);
157                         printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j]);
158                 }
159         }
160         printf("#endif /* AO_LISP_BUILTIN_ATOMS */\n");
161 }
162
163 void main() {
164         if (dim(argv) < 2) {
165                 File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
166                 exit(1);
167         }
168         twixt(file f = File::open(argv[1], "r"); File::close(f)) {
169                 builtin_t[*]    builtins = read_builtins(f);
170                 dump_ids(builtins);
171                 dump_casename(builtins);
172                 dump_arrayname(builtins);
173                 dump_funcs(builtins);
174                 dump_decls(builtins);
175                 dump_consts(builtins);
176                 dump_atoms(builtins);
177         }
178 }
179
180 main();