8e9c2c0b01294638a8fda795766d65a4a95dfe1f
[fw/altos] / src / scheme / ao_scheme_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         "macro" => "MACRO",
13         "f_lambda" => "F_LAMBDA",
14         "atom" => "atom",
15 };
16
17 string[*]
18 make_lisp(string[*] tokens)
19 {
20         string[...] lisp = {};
21
22         if (dim(tokens) < 3)
23                 return (string[1]) { tokens[dim(tokens) - 1] };
24         return (string[dim(tokens)-2]) { [i] = tokens[i+2] };
25 }
26
27 builtin_t
28 read_builtin(file f) {
29         string  line = File::fgets(f);
30         string[*]       tokens = String::wordsplit(line, " \t");
31
32         return (builtin_t) {
33                 .type = dim(tokens) > 0 ? type_map[tokens[0]] : "#",
34                 .c_name = dim(tokens) > 1 ? tokens[1] : "#",
35                 .lisp_names = make_lisp(tokens),
36         };
37 }
38
39 builtin_t[*]
40 read_builtins(file f) {
41         builtin_t[...] builtins = {};
42
43         while (!File::end(f)) {
44                 builtin_t       b = read_builtin(f);
45
46                 if (b.type[0] != '#')
47                         builtins[dim(builtins)] = b;
48         }
49         return builtins;
50 }
51
52 bool is_atom(builtin_t b) = b.type == "atom";
53
54 void
55 dump_ids(builtin_t[*] builtins) {
56         printf("#ifdef AO_SCHEME_BUILTIN_ID\n");
57         printf("#undef AO_SCHEME_BUILTIN_ID\n");
58         printf("enum ao_scheme_builtin_id {\n");
59         for (int i = 0; i < dim(builtins); i++)
60                 if (!is_atom(builtins[i]))
61                         printf("\tbuiltin_%s,\n", builtins[i].c_name);
62         printf("\t_builtin_last\n");
63         printf("};\n");
64         printf("#endif /* AO_SCHEME_BUILTIN_ID */\n");
65 }
66
67 void
68 dump_casename(builtin_t[*] builtins) {
69         printf("#ifdef AO_SCHEME_BUILTIN_CASENAME\n");
70         printf("#undef AO_SCHEME_BUILTIN_CASENAME\n");
71         printf("static char *ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {\n");
72         printf("\tswitch(b) {\n");
73         for (int i = 0; i < dim(builtins); i++)
74                 if (!is_atom(builtins[i]))
75                         printf("\tcase builtin_%s: return ao_scheme_poly_atom(_atom(\"%s\"))->name;\n",
76                                builtins[i].c_name, builtins[i].lisp_names[0]);
77         printf("\tdefault: return \"???\";\n");
78         printf("\t}\n");
79         printf("}\n");
80         printf("#endif /* AO_SCHEME_BUILTIN_CASENAME */\n");
81 }
82
83 void
84 cify_lisp(string l) {
85         for (int j = 0; j < String::length(l); j++) {
86                 int c= l[j];
87                 if (Ctype::isalnum(c) || c == '_')
88                         printf("%c", c);
89                 else
90                         printf("%02x", c);
91         }
92 }
93
94 void
95 dump_arrayname(builtin_t[*] builtins) {
96         printf("#ifdef AO_SCHEME_BUILTIN_ARRAYNAME\n");
97         printf("#undef AO_SCHEME_BUILTIN_ARRAYNAME\n");
98         printf("static const ao_poly builtin_names[] = {\n");
99         for (int i = 0; i < dim(builtins); i++) {
100                 if (!is_atom(builtins[i])) {
101                         printf("\t[builtin_%s] = _ao_scheme_atom_",
102                                builtins[i].c_name);
103                         cify_lisp(builtins[i].lisp_names[0]);
104                         printf(",\n");
105                 }
106         }
107         printf("};\n");
108         printf("#endif /* AO_SCHEME_BUILTIN_ARRAYNAME */\n");
109 }
110
111 void
112 dump_funcs(builtin_t[*] builtins) {
113         printf("#ifdef AO_SCHEME_BUILTIN_FUNCS\n");
114         printf("#undef AO_SCHEME_BUILTIN_FUNCS\n");
115         printf("const ao_scheme_func_t ao_scheme_builtins[] = {\n");
116         for (int i = 0; i < dim(builtins); i++) {
117                 if (!is_atom(builtins[i]))
118                         printf("\t[builtin_%s] = ao_scheme_do_%s,\n",
119                                builtins[i].c_name,
120                                builtins[i].c_name);
121         }
122         printf("};\n");
123         printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
124 }
125
126 void
127 dump_decls(builtin_t[*] builtins) {
128         printf("#ifdef AO_SCHEME_BUILTIN_DECLS\n");
129         printf("#undef AO_SCHEME_BUILTIN_DECLS\n");
130         for (int i = 0; i < dim(builtins); i++) {
131                 if (!is_atom(builtins[i])) {
132                         printf("ao_poly\n");
133                         printf("ao_scheme_do_%s(struct ao_scheme_cons *cons);\n",
134                                builtins[i].c_name);
135                 }
136         }
137         printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
138 }
139
140 void
141 dump_consts(builtin_t[*] builtins) {
142         printf("#ifdef AO_SCHEME_BUILTIN_CONSTS\n");
143         printf("#undef AO_SCHEME_BUILTIN_CONSTS\n");
144         printf("struct builtin_func funcs[] = {\n");
145         for (int i = 0; i < dim(builtins); i++) {
146                 if (!is_atom(builtins[i])) {
147                         for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
148                                 printf ("\t{ .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
149                                         builtins[i].lisp_names[j],
150                                         builtins[i].type,
151                                         builtins[i].c_name);
152                         }
153                 }
154         }
155         printf("};\n");
156         printf("#endif /* AO_SCHEME_BUILTIN_CONSTS */\n");
157 }
158
159 void
160 dump_atoms(builtin_t[*] builtins) {
161         printf("#ifdef AO_SCHEME_BUILTIN_ATOMS\n");
162         printf("#undef AO_SCHEME_BUILTIN_ATOMS\n");
163         for (int i = 0; i < dim(builtins); i++) {
164                 for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
165                         printf("#define _ao_scheme_atom_");
166                         cify_lisp(builtins[i].lisp_names[j]);
167                         printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j]);
168                 }
169         }
170         printf("#endif /* AO_SCHEME_BUILTIN_ATOMS */\n");
171 }
172
173 void main() {
174         if (dim(argv) < 2) {
175                 File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
176                 exit(1);
177         }
178         twixt(file f = File::open(argv[1], "r"); File::close(f)) {
179                 builtin_t[*]    builtins = read_builtins(f);
180                 dump_ids(builtins);
181                 dump_casename(builtins);
182                 dump_arrayname(builtins);
183                 dump_funcs(builtins);
184                 dump_decls(builtins);
185                 dump_consts(builtins);
186                 dump_atoms(builtins);
187         }
188 }
189
190 main();