altos/scheme: Support scheme subsetting via feature settings
[fw/altos] / src / scheme / ao_scheme_make_builtin
index 8e9c2c0b01294638a8fda795766d65a4a95dfe1f..78f97789de4eddd08763f0a27e923dbede6d73c9 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/nickle
 
 typedef struct {
 #!/usr/bin/nickle
 
 typedef struct {
+       string  feature;
        string  type;
        string  c_name;
        string[*]       lisp_names;
        string  type;
        string  c_name;
        string[*]       lisp_names;
@@ -12,6 +13,7 @@ string[string] type_map = {
        "macro" => "MACRO",
        "f_lambda" => "F_LAMBDA",
        "atom" => "atom",
        "macro" => "MACRO",
        "f_lambda" => "F_LAMBDA",
        "atom" => "atom",
+       "feature" => "feature",
 };
 
 string[*]
 };
 
 string[*]
@@ -19,9 +21,9 @@ make_lisp(string[*] tokens)
 {
        string[...] lisp = {};
 
 {
        string[...] lisp = {};
 
-       if (dim(tokens) < 3)
+       if (dim(tokens) < 4)
                return (string[1]) { tokens[dim(tokens) - 1] };
                return (string[1]) { tokens[dim(tokens) - 1] };
-       return (string[dim(tokens)-2]) { [i] = tokens[i+2] };
+       return (string[dim(tokens)-3]) { [i] = tokens[i+3] };
 }
 
 builtin_t
 }
 
 builtin_t
@@ -30,8 +32,9 @@ read_builtin(file f) {
        string[*]       tokens = String::wordsplit(line, " \t");
 
        return (builtin_t) {
        string[*]       tokens = String::wordsplit(line, " \t");
 
        return (builtin_t) {
-               .type = dim(tokens) > 0 ? type_map[tokens[0]] : "#",
-               .c_name = dim(tokens) > 1 ? tokens[1] : "#",
+               .feature = dim(tokens) > 0 ? tokens[0] : "#",
+               .type = dim(tokens) > 1 ? type_map[tokens[1]] : "#",
+               .c_name = dim(tokens) > 2 ? tokens[2] : "#",
                .lisp_names = make_lisp(tokens),
        };
 }
                .lisp_names = make_lisp(tokens),
        };
 }
@@ -49,16 +52,37 @@ read_builtins(file f) {
        return builtins;
 }
 
        return builtins;
 }
 
+void
+dump_ifdef(builtin_t builtin)
+{
+       if (builtin.feature != "all")
+               printf("#ifdef AO_SCHEME_FEATURE_%s\n", builtin.feature);
+}
+
+void
+dump_endif(builtin_t builtin)
+{
+       if (builtin.feature != "all")
+               printf("#endif /* AO_SCHEME_FEATURE_%s */\n", builtin.feature);
+}
+
 bool is_atom(builtin_t b) = b.type == "atom";
 
 bool is_atom(builtin_t b) = b.type == "atom";
 
+bool is_func(builtin_t b) = b.type != "atom" && b.type != "feature";
+
+bool is_feature(builtin_t b) = b.type == "feature";
+
 void
 dump_ids(builtin_t[*] builtins) {
        printf("#ifdef AO_SCHEME_BUILTIN_ID\n");
        printf("#undef AO_SCHEME_BUILTIN_ID\n");
        printf("enum ao_scheme_builtin_id {\n");
        for (int i = 0; i < dim(builtins); i++)
 void
 dump_ids(builtin_t[*] builtins) {
        printf("#ifdef AO_SCHEME_BUILTIN_ID\n");
        printf("#undef AO_SCHEME_BUILTIN_ID\n");
        printf("enum ao_scheme_builtin_id {\n");
        for (int i = 0; i < dim(builtins); i++)
-               if (!is_atom(builtins[i]))
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        printf("\tbuiltin_%s,\n", builtins[i].c_name);
                        printf("\tbuiltin_%s,\n", builtins[i].c_name);
+                       dump_endif(builtins[i]);
+               }
        printf("\t_builtin_last\n");
        printf("};\n");
        printf("#endif /* AO_SCHEME_BUILTIN_ID */\n");
        printf("\t_builtin_last\n");
        printf("};\n");
        printf("#endif /* AO_SCHEME_BUILTIN_ID */\n");
@@ -71,9 +95,12 @@ dump_casename(builtin_t[*] builtins) {
        printf("static char *ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {\n");
        printf("\tswitch(b) {\n");
        for (int i = 0; i < dim(builtins); i++)
        printf("static char *ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {\n");
        printf("\tswitch(b) {\n");
        for (int i = 0; i < dim(builtins); i++)
-               if (!is_atom(builtins[i]))
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        printf("\tcase builtin_%s: return ao_scheme_poly_atom(_atom(\"%s\"))->name;\n",
                               builtins[i].c_name, builtins[i].lisp_names[0]);
                        printf("\tcase builtin_%s: return ao_scheme_poly_atom(_atom(\"%s\"))->name;\n",
                               builtins[i].c_name, builtins[i].lisp_names[0]);
+                       dump_endif(builtins[i]);
+               }
        printf("\tdefault: return \"???\";\n");
        printf("\t}\n");
        printf("}\n");
        printf("\tdefault: return \"???\";\n");
        printf("\t}\n");
        printf("}\n");
@@ -97,11 +124,13 @@ dump_arrayname(builtin_t[*] builtins) {
        printf("#undef AO_SCHEME_BUILTIN_ARRAYNAME\n");
        printf("static const ao_poly builtin_names[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
        printf("#undef AO_SCHEME_BUILTIN_ARRAYNAME\n");
        printf("static const ao_poly builtin_names[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
-               if (!is_atom(builtins[i])) {
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        printf("\t[builtin_%s] = _ao_scheme_atom_",
                               builtins[i].c_name);
                        cify_lisp(builtins[i].lisp_names[0]);
                        printf(",\n");
                        printf("\t[builtin_%s] = _ao_scheme_atom_",
                               builtins[i].c_name);
                        cify_lisp(builtins[i].lisp_names[0]);
                        printf(",\n");
+                       dump_endif(builtins[i]);
                }
        }
        printf("};\n");
                }
        }
        printf("};\n");
@@ -114,10 +143,13 @@ dump_funcs(builtin_t[*] builtins) {
        printf("#undef AO_SCHEME_BUILTIN_FUNCS\n");
        printf("const ao_scheme_func_t ao_scheme_builtins[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
        printf("#undef AO_SCHEME_BUILTIN_FUNCS\n");
        printf("const ao_scheme_func_t ao_scheme_builtins[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
-               if (!is_atom(builtins[i]))
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        printf("\t[builtin_%s] = ao_scheme_do_%s,\n",
                               builtins[i].c_name,
                               builtins[i].c_name);
                        printf("\t[builtin_%s] = ao_scheme_do_%s,\n",
                               builtins[i].c_name,
                               builtins[i].c_name);
+                       dump_endif(builtins[i]);
+               }
        }
        printf("};\n");
        printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
        }
        printf("};\n");
        printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
@@ -128,10 +160,12 @@ dump_decls(builtin_t[*] builtins) {
        printf("#ifdef AO_SCHEME_BUILTIN_DECLS\n");
        printf("#undef AO_SCHEME_BUILTIN_DECLS\n");
        for (int i = 0; i < dim(builtins); i++) {
        printf("#ifdef AO_SCHEME_BUILTIN_DECLS\n");
        printf("#undef AO_SCHEME_BUILTIN_DECLS\n");
        for (int i = 0; i < dim(builtins); i++) {
-               if (!is_atom(builtins[i])) {
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        printf("ao_poly\n");
                        printf("ao_scheme_do_%s(struct ao_scheme_cons *cons);\n",
                               builtins[i].c_name);
                        printf("ao_poly\n");
                        printf("ao_scheme_do_%s(struct ao_scheme_cons *cons);\n",
                               builtins[i].c_name);
+                       dump_endif(builtins[i]);
                }
        }
        printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
                }
        }
        printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
@@ -143,13 +177,16 @@ dump_consts(builtin_t[*] builtins) {
        printf("#undef AO_SCHEME_BUILTIN_CONSTS\n");
        printf("struct builtin_func funcs[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
        printf("#undef AO_SCHEME_BUILTIN_CONSTS\n");
        printf("struct builtin_func funcs[] = {\n");
        for (int i = 0; i < dim(builtins); i++) {
-               if (!is_atom(builtins[i])) {
+               if (is_func(builtins[i])) {
+                       dump_ifdef(builtins[i]);
                        for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
                        for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
-                               printf ("\t{ .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
+                               printf ("\t{ .feature = \"%s\", .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
+                                       builtins[i].feature,
                                        builtins[i].lisp_names[j],
                                        builtins[i].type,
                                        builtins[i].c_name);
                        }
                                        builtins[i].lisp_names[j],
                                        builtins[i].type,
                                        builtins[i].c_name);
                        }
+                       dump_endif(builtins[i]);
                }
        }
        printf("};\n");
                }
        }
        printf("};\n");
@@ -161,15 +198,60 @@ dump_atoms(builtin_t[*] builtins) {
        printf("#ifdef AO_SCHEME_BUILTIN_ATOMS\n");
        printf("#undef AO_SCHEME_BUILTIN_ATOMS\n");
        for (int i = 0; i < dim(builtins); i++) {
        printf("#ifdef AO_SCHEME_BUILTIN_ATOMS\n");
        printf("#undef AO_SCHEME_BUILTIN_ATOMS\n");
        for (int i = 0; i < dim(builtins); i++) {
-               for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
-                       printf("#define _ao_scheme_atom_");
-                       cify_lisp(builtins[i].lisp_names[j]);
-                       printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j]);
+               if (!is_feature(builtins[i])) {
+                       for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
+                               printf("#define _ao_scheme_atom_");
+                               cify_lisp(builtins[i].lisp_names[j]);
+                               printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j]);
+                       }
                }
        }
        printf("#endif /* AO_SCHEME_BUILTIN_ATOMS */\n");
 }
 
                }
        }
        printf("#endif /* AO_SCHEME_BUILTIN_ATOMS */\n");
 }
 
+void
+dump_atom_names(builtin_t[*] builtins) {
+       printf("#ifdef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
+       printf("#undef AO_SCHEME_BUILTIN_ATOM_NAMES\n");
+       printf("static struct builtin_atom atoms[] = {\n");
+       for (int i = 0; i < dim(builtins); i++) {
+               if (is_atom(builtins[i])) {
+                       for (int j = 0; j < dim(builtins[i].lisp_names); j++) {
+                               printf("\t{ .feature = \"%s\", .name = \"%s\" },\n",
+                                      builtins[i].feature,
+                                      builtins[i].lisp_names[j]);
+                       }
+               }
+       }
+       printf("};\n");
+       printf("#endif /* AO_SCHEME_BUILTIN_ATOM_NAMES */\n");
+}
+
+bool
+has_feature(string[*] features, string feature)
+{
+       for (int i = 0; i < dim(features); i++)
+               if (features[i] == feature)
+                       return true;
+       return false;
+}
+
+void
+dump_features(builtin_t[*] builtins) {
+       string[...] features = {};
+       printf("#ifdef AO_SCHEME_BUILTIN_FEATURES\n");
+       for (int i = 0; i < dim(builtins); i++) {
+               if (builtins[i].feature != "all") {
+                       string feature = builtins[i].feature;
+                       if (!has_feature(features, feature)) {
+                               features[dim(features)] = feature;
+                               printf("#define AO_SCHEME_FEATURE_%s\n", feature);
+                       }
+               }
+       }
+       printf("#endif /* AO_SCHEME_BUILTIN_FEATURES */\n");
+}
+
 void main() {
        if (dim(argv) < 2) {
                File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
 void main() {
        if (dim(argv) < 2) {
                File::fprintf(stderr, "usage: %s <file>\n", argv[0]);
@@ -177,6 +259,8 @@ void main() {
        }
        twixt(file f = File::open(argv[1], "r"); File::close(f)) {
                builtin_t[*]    builtins = read_builtins(f);
        }
        twixt(file f = File::open(argv[1], "r"); File::close(f)) {
                builtin_t[*]    builtins = read_builtins(f);
+
+               printf("/* %d builtins */\n", dim(builtins));
                dump_ids(builtins);
                dump_casename(builtins);
                dump_arrayname(builtins);
                dump_ids(builtins);
                dump_casename(builtins);
                dump_arrayname(builtins);
@@ -184,6 +268,8 @@ void main() {
                dump_decls(builtins);
                dump_consts(builtins);
                dump_atoms(builtins);
                dump_decls(builtins);
                dump_consts(builtins);
                dump_atoms(builtins);
+               dump_atom_names(builtins);
+               dump_features(builtins);
        }
 }
 
        }
 }