501052b91b991a0c4533e86f4c39f9cd1d6f3e4e
[fw/altos] / src / lisp / ao_lisp_make_const.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include "ao_lisp.h"
16 #include <stdlib.h>
17 #include <ctype.h>
18
19 static struct ao_lisp_builtin *
20 ao_lisp_make_builtin(enum ao_lisp_builtin_id func, int args) {
21         struct ao_lisp_builtin *b = ao_lisp_alloc(sizeof (struct ao_lisp_builtin));
22
23         b->type = AO_LISP_BUILTIN;
24         b->func = func;
25         b->args = args;
26         return b;
27 }
28
29 struct builtin_func {
30         char    *name;
31         int     args;
32         int     func;
33 };
34
35 struct builtin_func funcs[] = {
36         "lambda",       AO_LISP_FUNC_NLAMBDA,   builtin_lambda,
37         "lexpr",        AO_LISP_FUNC_NLAMBDA,   builtin_lexpr,
38         "nlambda",      AO_LISP_FUNC_NLAMBDA,   builtin_nlambda,
39         "macro",        AO_LISP_FUNC_NLAMBDA,   builtin_macro,
40         "car",          AO_LISP_FUNC_LAMBDA,    builtin_car,
41         "cdr",          AO_LISP_FUNC_LAMBDA,    builtin_cdr,
42         "cons",         AO_LISP_FUNC_LAMBDA,    builtin_cons,
43         "last",         AO_LISP_FUNC_LAMBDA,    builtin_last,
44         "quote",        AO_LISP_FUNC_NLAMBDA,   builtin_quote,
45         "set",          AO_LISP_FUNC_LAMBDA,    builtin_set,
46         "setq",         AO_LISP_FUNC_MACRO,     builtin_setq,
47         "cond",         AO_LISP_FUNC_NLAMBDA,   builtin_cond,
48         "print",        AO_LISP_FUNC_LEXPR,     builtin_print,
49         "patom",        AO_LISP_FUNC_LEXPR,     builtin_patom,
50         "+",            AO_LISP_FUNC_LEXPR,     builtin_plus,
51         "-",            AO_LISP_FUNC_LEXPR,     builtin_minus,
52         "*",            AO_LISP_FUNC_LEXPR,     builtin_times,
53         "/",            AO_LISP_FUNC_LEXPR,     builtin_divide,
54         "%",            AO_LISP_FUNC_LEXPR,     builtin_mod,
55         "=",            AO_LISP_FUNC_LEXPR,     builtin_equal,
56         "<",            AO_LISP_FUNC_LEXPR,     builtin_less,
57         ">",            AO_LISP_FUNC_LEXPR,     builtin_greater,
58         "<=",           AO_LISP_FUNC_LEXPR,     builtin_less_equal,
59         ">=",           AO_LISP_FUNC_LEXPR,     builtin_greater_equal,
60 };
61
62 #define N_FUNC (sizeof funcs / sizeof funcs[0])
63
64 /* Syntactic atoms */
65 char *atoms[] = {
66         "lambda",
67         "nlambda",
68         "lexpr",
69         "macro"
70 };
71
72 #define N_ATOM (sizeof atoms / sizeof atoms[0])
73
74 struct ao_lisp_frame    *globals;
75
76 static int
77 is_atom(int offset)
78 {
79         struct ao_lisp_atom *a;
80
81         for (a = ao_lisp_atoms; a; a = ao_lisp_poly_atom(a->next))
82                 if (((uint8_t *) a->name - ao_lisp_const) == offset)
83                         return strlen(a->name);
84         return 0;
85 }
86
87 int
88 main(int argc, char **argv)
89 {
90         int     f, o, i;
91         ao_poly sexpr, val;
92         struct ao_lisp_atom     *a;
93         struct ao_lisp_builtin  *b;
94         int     in_atom;
95
96         printf("/*\n");
97         printf(" * Generated file, do not edit\n");
98         for (f = 0; f < N_FUNC; f++) {
99                 b = ao_lisp_make_builtin(funcs[f].func, funcs[f].args);
100                 a = ao_lisp_atom_intern(funcs[f].name);
101                 ao_lisp_atom_set(ao_lisp_atom_poly(a),
102                                  ao_lisp_builtin_poly(b));
103         }
104
105         /* atoms for syntax */
106         for (i = 0; i < N_ATOM; i++)
107                 (void) ao_lisp_atom_intern(atoms[i]);
108
109         /* boolean constants */
110         ao_lisp_atom_set(ao_lisp_atom_poly(ao_lisp_atom_intern("nil")),
111                          AO_LISP_NIL);
112         a = ao_lisp_atom_intern("t");
113         ao_lisp_atom_set(ao_lisp_atom_poly(a),
114                          ao_lisp_atom_poly(a));
115
116         for (;;) {
117                 sexpr = ao_lisp_read();
118                 if (!sexpr)
119                         break;
120                 printf ("sexpr: ");
121                 ao_lisp_poly_print(sexpr);
122                 printf("\n");
123                 val = ao_lisp_eval(sexpr);
124                 if (ao_lisp_exception)
125                         exit(1);
126                 printf("\t");
127                 ao_lisp_poly_print(val);
128                 printf("\n");
129         }
130
131         /* Reduce to referenced values */
132         ao_lisp_collect();
133         printf(" */\n");
134
135         printf("#define AO_LISP_POOL_CONST %d\n", ao_lisp_top);
136         printf("extern const uint8_t ao_lisp_const[AO_LISP_POOL_CONST] __attribute__((aligned(4)));\n");
137         printf("#define ao_builtin_atoms 0x%04x\n", ao_lisp_atom_poly(ao_lisp_atoms));
138         printf("#define ao_builtin_frame 0x%04x\n", ao_lisp_frame_poly(ao_lisp_frame_global));
139
140         for (a = ao_lisp_atoms; a; a = ao_lisp_poly_atom(a->next)) {
141                 char    *n = a->name, c;
142                 printf ("#define _ao_lisp_atom_");
143                 while ((c = *n++)) {
144                         if (isalnum(c))
145                                 printf("%c", c);
146                         else
147                                 printf("%02x", c);
148                 }
149                 printf("  0x%04x\n", ao_lisp_atom_poly(a));
150         }
151         printf("#ifdef AO_LISP_CONST_BITS\n");
152         printf("const uint8_t ao_lisp_const[] = {");
153         for (o = 0; o < ao_lisp_top; o++) {
154                 uint8_t c;
155                 if ((o & 0xf) == 0)
156                         printf("\n\t");
157                 else
158                         printf(" ");
159                 c = ao_lisp_const[o];
160                 if (!in_atom)
161                         in_atom = is_atom(o);
162                 if (in_atom) {
163                         printf (" '%c',", c);
164                         in_atom--;
165                 } else {
166                         printf("0x%02x,", c);
167                 }
168         }
169         printf("\n};\n");
170         printf("#endif /* AO_LISP_CONST_BITS */\n");
171 }