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