X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fscheme%2Fao_scheme_make_const.c;h=79ba1bf19ba8aef9b15c65819ecac8021df43634;hb=431165e5fa72ba6dffd477de32960745cdec332c;hp=cf42ec521490c3e51dd7ca47fcb75324bd5603d2;hpb=2f8fce1cf6ce4bd12a836cc8ee15f4edbc95c95e;p=fw%2Faltos diff --git a/src/scheme/ao_scheme_make_const.c b/src/scheme/ao_scheme_make_const.c index cf42ec52..79ba1bf1 100644 --- a/src/scheme/ao_scheme_make_const.c +++ b/src/scheme/ao_scheme_make_const.c @@ -17,6 +17,7 @@ #include #include #include +#include static struct ao_scheme_builtin * ao_scheme_make_builtin(enum ao_scheme_builtin_id func, int args) { @@ -29,15 +30,25 @@ ao_scheme_make_builtin(enum ao_scheme_builtin_id func, int args) { } struct builtin_func { - char *name; - int args; + const char *feature; + const char *name; + int args; enum ao_scheme_builtin_id func; }; +struct builtin_atom { + const char *feature; + const char *name; +}; + #define AO_SCHEME_BUILTIN_CONSTS +#define AO_SCHEME_BUILTIN_ATOM_NAMES + #include "ao_scheme_builtin.h" -#define N_FUNC (sizeof funcs / sizeof funcs[0]) +#define N_FUNC (sizeof funcs / sizeof funcs[0]) + +#define N_ATOM (sizeof atoms / sizeof atoms[0]) struct ao_scheme_frame *globals; @@ -69,7 +80,7 @@ ao_fec_crc_byte(uint8_t byte, uint16_t crc) return crc; } -uint16_t +static uint16_t ao_fec_crc(const uint8_t *bytes, uint8_t len) { uint16_t crc = AO_FEC_CRC_INIT; @@ -86,7 +97,7 @@ struct ao_scheme_macro_stack { struct ao_scheme_macro_stack *macro_stack; -int +static int ao_scheme_macro_push(ao_poly p) { struct ao_scheme_macro_stack *m = macro_stack; @@ -103,7 +114,7 @@ ao_scheme_macro_push(ao_poly p) return 0; } -void +static void ao_scheme_macro_pop(void) { struct ao_scheme_macro_stack *m = macro_stack; @@ -130,7 +141,7 @@ void indent(void) ao_poly ao_has_macro(ao_poly p); -ao_poly +static ao_poly ao_macro_test_get(ao_poly atom) { ao_poly *ref = ao_scheme_atom_ref(atom, NULL); @@ -139,7 +150,7 @@ ao_macro_test_get(ao_poly atom) return AO_SCHEME_NIL; } -ao_poly +static ao_poly ao_is_macro(ao_poly p) { struct ao_scheme_builtin *builtin; @@ -209,7 +220,7 @@ ao_has_macro(ao_poly p) list = cons->cdr; p = AO_SCHEME_NIL; - while (list != AO_SCHEME_NIL && ao_scheme_poly_type(list) == AO_SCHEME_CONS) { + while (list != AO_SCHEME_NIL && AO_SCHEME_IS_CONS(list)) { cons = ao_scheme_poly_cons(list); m = ao_has_macro(cons->car); if (m) { @@ -228,7 +239,37 @@ ao_has_macro(ao_poly p) return p; } -int +static struct ao_scheme_builtin * +ao_scheme_get_builtin(ao_poly p) +{ + if (ao_scheme_poly_type(p) == AO_SCHEME_BUILTIN) + return ao_scheme_poly_builtin(p); + return NULL; +} + +struct seen_builtin { + struct seen_builtin *next; + struct ao_scheme_builtin *builtin; +}; + +static struct seen_builtin *seen_builtins; + +static int +ao_scheme_seen_builtin(struct ao_scheme_builtin *b) +{ + struct seen_builtin *s; + + for (s = seen_builtins; s; s = s->next) + if (s->builtin == b) + return 1; + s = malloc (sizeof (struct seen_builtin)); + s->builtin = b; + s->next = seen_builtins; + seen_builtins = s; + return 0; +} + +static int ao_scheme_read_eval_abort(void) { ao_poly in, out = AO_SCHEME_NIL; @@ -239,7 +280,7 @@ ao_scheme_read_eval_abort(void) out = ao_scheme_eval(in); if (ao_scheme_exception) return 0; - ao_scheme_poly_write(out); + ao_scheme_poly_write(out, true); putchar ('\n'); } return 1; @@ -248,6 +289,50 @@ ao_scheme_read_eval_abort(void) static FILE *in; static FILE *out; +struct feature { + struct feature *next; + char name[]; +}; + +static struct feature *enable; +static struct feature *disable; + +static void +ao_scheme_add_feature(struct feature **list, char *name) +{ + struct feature *feature = malloc (sizeof (struct feature) + strlen(name) + 1); + strcpy(feature->name, name); + feature->next = *list; + *list = feature; +} + +static bool +ao_scheme_has_feature(struct feature *list, const char *name) +{ + while (list) { + if (!strcmp(list->name, name)) + return true; + list = list->next; + } + return false; +} + +static void +ao_scheme_add_features(struct feature **list, const char *names) +{ + char *saveptr = NULL; + char *name; + char *copy = strdup(names); + char *save = copy; + + while ((name = strtok_r(copy, ",", &saveptr)) != NULL) { + copy = NULL; + if (!ao_scheme_has_feature(*list, name)) + ao_scheme_add_feature(list, name); + } + free(save); +} + int ao_scheme_getc(void) { @@ -256,35 +341,46 @@ ao_scheme_getc(void) static const struct option options[] = { { .name = "out", .has_arg = 1, .val = 'o' }, + { .name = "disable", .has_arg = 1, .val = 'd' }, + { .name = "enable", .has_arg = 1, .val = 'e' }, { 0, 0, 0, 0 } }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--out=] [input]\n", program); + fprintf(stderr, "usage: %s [--out=] [--disable={feature,...}] [--enable={feature,...} [input]\n", program); exit(1); } int main(int argc, char **argv) { - int f, o; + int f, o, an; ao_poly val; struct ao_scheme_atom *a; struct ao_scheme_builtin *b; + struct feature *d; int in_atom = 0; char *out_name = NULL; int c; enum ao_scheme_builtin_id prev_func; + enum ao_scheme_builtin_id target_func; + enum ao_scheme_builtin_id func_map[_builtin_last]; in = stdin; out = stdout; - while ((c = getopt_long(argc, argv, "o:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "o:d:e:", options, NULL)) != -1) { switch (c) { case 'o': out_name = optarg; break; + case 'd': + ao_scheme_add_features(&disable, optarg); + break; + case 'e': + ao_scheme_add_features(&enable, optarg); + break; default: usage(argv[0]); break; @@ -298,21 +394,35 @@ main(int argc, char **argv) ao_scheme_bool_get(1); prev_func = _builtin_last; + target_func = 0; + b = NULL; for (f = 0; f < (int) N_FUNC; f++) { - if (funcs[f].func != prev_func) - b = ao_scheme_make_builtin(funcs[f].func, funcs[f].args); - a = ao_scheme_atom_intern(funcs[f].name); - ao_scheme_atom_def(ao_scheme_atom_poly(a), - ao_scheme_builtin_poly(b)); + if (ao_scheme_has_feature(enable, funcs[f].feature) || !ao_scheme_has_feature(disable, funcs[f].feature)) { + if (funcs[f].func != prev_func) { + prev_func = funcs[f].func; + b = ao_scheme_make_builtin(prev_func, funcs[f].args); + + /* Target may have only a subset of + * the enum values; record what those + * values will be here. This obviously + * depends on the functions in the + * array being in the same order as + * the enumeration; which + * ao_scheme_make_builtin ensures. + */ + func_map[prev_func] = target_func++; + } + a = ao_scheme_atom_intern((char *) funcs[f].name); + ao_scheme_atom_def(ao_scheme_atom_poly(a), + ao_scheme_builtin_poly(b)); + } } - /* end of file value */ - a = ao_scheme_atom_intern("eof"); - ao_scheme_atom_def(ao_scheme_atom_poly(a), - ao_scheme_atom_poly(a)); - - /* 'else' */ - a = ao_scheme_atom_intern("else"); + /* atoms */ + for (an = 0; an < (int) N_ATOM; an++) { + if (ao_scheme_has_feature(enable, atoms[an].feature) || !ao_scheme_has_feature(disable, atoms[an].feature)) + a = ao_scheme_atom_intern((char *) atoms[an].name); + } if (argv[optind]){ in = fopen(argv[optind], "r"); @@ -331,14 +441,22 @@ main(int argc, char **argv) for (f = 0; f < ao_scheme_frame_global->num; f++) { struct ao_scheme_frame_vals *vals = ao_scheme_poly_frame_vals(ao_scheme_frame_global->vals); + val = ao_has_macro(vals->vals[f].val); if (val != AO_SCHEME_NIL) { printf("error: function %s contains unresolved macro: ", ao_scheme_poly_atom(vals->vals[f].atom)->name); - ao_scheme_poly_write(val); + ao_scheme_poly_write(val, true); printf("\n"); exit(1); } + + /* Remap builtin enum values to match target set */ + b = ao_scheme_get_builtin(vals->vals[f].val); + if (b != NULL) { + if (!ao_scheme_seen_builtin(b)) + b->func = func_map[b->func]; + } } if (out_name) { @@ -351,6 +469,9 @@ main(int argc, char **argv) fprintf(out, "/* Generated file, do not edit */\n\n"); + for (d = disable; d; d = d->next) + fprintf(out, "#undef AO_SCHEME_FEATURE_%s\n", d->name); + fprintf(out, "#define AO_SCHEME_POOL_CONST %d\n", ao_scheme_top); fprintf(out, "extern const uint8_t ao_scheme_const[AO_SCHEME_POOL_CONST] __attribute__((aligned(4)));\n"); fprintf(out, "#define ao_builtin_atoms 0x%04x\n", ao_scheme_atom_poly(ao_scheme_atoms)); @@ -361,32 +482,33 @@ main(int argc, char **argv) fprintf(out, "#define _ao_scheme_bool_true 0x%04x\n", ao_scheme_bool_poly(ao_scheme_true)); for (a = ao_scheme_atoms; a; a = ao_scheme_poly_atom(a->next)) { - char *n = a->name, c; + const char *n = a->name; + char ch; fprintf(out, "#define _ao_scheme_atom_"); - while ((c = *n++)) { - if (isalnum(c)) - fprintf(out, "%c", c); + while ((ch = *n++)) { + if (isalnum(ch)) + fprintf(out, "%c", ch); else - fprintf(out, "%02x", c); + fprintf(out, "%02x", ch); } fprintf(out, " 0x%04x\n", ao_scheme_atom_poly(a)); } fprintf(out, "#ifdef AO_SCHEME_CONST_BITS\n"); fprintf(out, "const uint8_t ao_scheme_const[AO_SCHEME_POOL_CONST] __attribute((aligned(4))) = {"); for (o = 0; o < ao_scheme_top; o++) { - uint8_t c; + uint8_t ch; if ((o & 0xf) == 0) fprintf(out, "\n\t"); else fprintf(out, " "); - c = ao_scheme_const[o]; + ch = ao_scheme_const[o]; if (!in_atom) in_atom = is_atom(o); if (in_atom) { - fprintf(out, " '%c',", c); + fprintf(out, " '%c',", ch); in_atom--; } else { - fprintf(out, "0x%02x,", c); + fprintf(out, "0x%02x,", ch); } } fprintf(out, "\n};\n");