#!/usr/bin/nickle
typedef struct {
+ string name;
+ string feature;
+} lisp_name_t;
+
+typedef struct {
+ string feature;
string type;
string c_name;
- string[*] lisp_names;
+ lisp_name_t[*] lisp_names;
} builtin_t;
string[string] type_map = {
"macro" => "MACRO",
"f_lambda" => "F_LAMBDA",
"atom" => "atom",
+ "feature" => "feature",
};
-string[*]
+lisp_name_t
+make_one_lisp(string token)
+{
+ string[*] bits = String::split(token, "@");
+ string name = bits[0];
+ string feature = "all";
+
+ if (dim(bits) > 1)
+ feature = bits[1];
+ return (lisp_name_t) {.name = name, .feature = feature };
+}
+
+lisp_name_t[*]
make_lisp(string[*] tokens)
{
- string[...] lisp = {};
+ lisp_name_t[...] lisp = {};
- if (dim(tokens) < 3)
- return (string[1]) { tokens[dim(tokens) - 1] };
- return (string[dim(tokens)-2]) { [i] = tokens[i+2] };
+ if (dim(tokens) < 4)
+ return (lisp_name_t[1]) { make_one_lisp(tokens[dim(tokens) - 1]) };
+ return (lisp_name_t[dim(tokens)-3]) { [i] = make_one_lisp(tokens[i+3]) };
}
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),
};
}
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_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++)
- if (!is_atom(builtins[i]))
+ if (is_func(builtins[i])) {
+ dump_ifdef(builtins[i]);
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("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("\tdefault: return \"???\";\n");
+ builtins[i].c_name, builtins[i].lisp_names[0].name);
+ dump_endif(builtins[i]);
+ }
+ printf("\tdefault: return (char *) \"???\";\n");
printf("\t}\n");
printf("}\n");
printf("#endif /* AO_SCHEME_BUILTIN_CASENAME */\n");
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]);
+ cify_lisp(builtins[i].lisp_names[0].name);
printf(",\n");
+ dump_endif(builtins[i]);
}
}
printf("};\n");
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);
+ dump_endif(builtins[i]);
+ }
}
printf("};\n");
printf("#endif /* AO_SCHEME_BUILTIN_FUNCS */\n");
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);
+ dump_endif(builtins[i]);
}
}
printf("#endif /* AO_SCHEME_BUILTIN_DECLS */\n");
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++) {
- printf ("\t{ .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
- builtins[i].lisp_names[j],
+ string feature = builtins[i].feature;
+ if (builtins[i].lisp_names[j].feature != "all")
+ feature = builtins[i].lisp_names[j].feature;
+ printf ("\t{ .feature = \"%s\", .name = \"%s\", .args = AO_SCHEME_FUNC_%s, .func = builtin_%s },\n",
+ feature,
+ builtins[i].lisp_names[j].name,
builtins[i].type,
builtins[i].c_name);
}
+ dump_endif(builtins[i]);
}
}
printf("};\n");
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].name);
+ printf(" _atom(\"%s\")\n", builtins[i].lisp_names[j].name);
+ }
}
}
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++) {
+ string feature = builtins[i].feature;
+ if (builtins[i].lisp_names[j].feature != "all")
+ feature = builtins[i].lisp_names[j].feature;
+ printf("\t{ .feature = \"%s\", .name = \"%s\" },\n",
+ feature,
+ builtins[i].lisp_names[j].name);
+ }
+ }
+ }
+ printf("};\n");
+ printf("#endif /* AO_SCHEME_BUILTIN_ATOM_NAMES */\n");
+}
+
+void
+dump_syntax_atoms(builtin_t[*] builtins) {
+ printf("#ifdef AO_SCHEME_BUILTIN_SYNTAX_ATOMS\n");
+ printf("#undef AO_SCHEME_BUILTIN_SYNTAX_ATOMS\n");
+ printf("static const char *syntax_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\"%s\",\n", builtins[i].lisp_names[j].name);
+ }
+ }
+ }
+ printf("};\n");
+ printf("#endif /* AO_SCHEME_BUILTIN_SYNTAX_ATOMS */\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("#ifndef AO_SCHEME_NO_FEATURE_%s\n", feature);
+ printf("#define AO_SCHEME_FEATURE_%s\n", feature);
+ printf("#endif /* AO_SCHEME_NO_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]);
}
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_decls(builtins);
dump_consts(builtins);
dump_atoms(builtins);
+ dump_atom_names(builtins);
+ dump_syntax_atoms(builtins);
+ dump_features(builtins);
}
}