aboutsummaryrefslogtreecommitdiff
path: root/enums.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-06-06 16:28:53 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-06-06 16:28:53 -0400
commit8c7d53008072dfda8b9d60be92fae1a8046fae5d (patch)
tree769407e0461b3c989c27a740c423827a21adfa91 /enums.c
parent31c8d0af1597b6b4996a90808b1b8c0983db309e (diff)
Split header compilation into a separate function
Diffstat (limited to 'enums.c')
-rw-r--r--enums.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/enums.c b/enums.c
index e9256b11..ee631572 100644
--- a/enums.c
+++ b/enums.c
@@ -153,19 +153,8 @@ void compile_enum_def(env_t *env, ast_t *ast)
{
auto def = Match(ast, EnumDef);
CORD full_name = CORD_cat(env->file_prefix, def->name);
- CORD_appendf(&env->code->typedefs, "typedef struct %r_s %r_t;\n", full_name, full_name);
- CORD_appendf(&env->code->typedefs, "extern const TypeInfo %r;\n", full_name);
- CORD enum_def = CORD_all("struct ", full_name, "_s {\n"
- "\tenum {");
- for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
- CORD_appendf(&enum_def, "%r$tag$%s = %ld", full_name, tag->name, tag->value);
- if (tag->next) enum_def = CORD_cat(enum_def, ", ");
- }
- enum_def = CORD_cat(enum_def, "} $tag;\n"
- "union {\n");
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
compile_struct_def(env, WrapAST(ast, StructDef, .name=CORD_to_const_char_star(CORD_all(def->name, "$", tag->name)), .fields=tag->fields));
- enum_def = CORD_all(enum_def, full_name, "$", tag->name, "_t ", tag->name, ";\n");
if (tag->fields) { // Constructor macros:
CORD arg_sig = CORD_EMPTY;
for (arg_ast_t *field = tag->fields; field; field = field->next) {
@@ -174,9 +163,6 @@ void compile_enum_def(env_t *env, ast_t *ast)
if (field->next) arg_sig = CORD_cat(arg_sig, ", ");
}
if (arg_sig == CORD_EMPTY) arg_sig = "void";
- CORD constructor_def = CORD_all(full_name, "_t ", full_name, "$tagged$", tag->name, "(", arg_sig, ");\n");
- env->code->fndefs = CORD_cat(env->code->fndefs, constructor_def);
-
CORD constructor_impl = CORD_all("public inline ", full_name, "_t ", full_name, "$tagged$", tag->name, "(", arg_sig, ") { return (",
full_name, "_t){.$tag=", full_name, "$tag$", tag->name, ", .", tag->name, "={");
for (arg_ast_t *field = tag->fields; field; field = field->next) {
@@ -187,8 +173,6 @@ void compile_enum_def(env_t *env, ast_t *ast)
env->code->funcs = CORD_cat(env->code->funcs, constructor_impl);
}
}
- enum_def = CORD_cat(enum_def, "};\n};\n");
- env->code->typecode = CORD_cat(env->code->typecode, enum_def);
type_t *t = Table$str_get(*env->types, def->name);
CORD typeinfo = CORD_asprintf("public const TypeInfo %s = {%zu, %zu, {.tag=CustomInfo, .CustomInfo={",
@@ -216,4 +200,40 @@ void compile_enum_def(env_t *env, ast_t *ast)
compile_namespace(env, def->name, def->namespace);
}
+CORD compile_enum_header(env_t *env, ast_t *ast)
+{
+ auto def = Match(ast, EnumDef);
+ CORD full_name = CORD_cat(env->file_prefix, def->name);
+ CORD header = CORD_all("typedef struct ", full_name, "_s ", full_name, "_t;\n",
+ "extern const TypeInfo ", full_name, ";\n");
+ CORD enum_def = CORD_all("struct ", full_name, "_s {\n"
+ "\tenum {");
+ for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
+ CORD_appendf(&enum_def, "%r$tag$%s = %ld", full_name, tag->name, tag->value);
+ if (tag->next) enum_def = CORD_cat(enum_def, ", ");
+ }
+ enum_def = CORD_cat(enum_def, "} $tag;\n"
+ "union {\n");
+ CORD constructors = CORD_EMPTY;
+ for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
+ CORD field_header = compile_struct_header(env, WrapAST(ast, StructDef, .name=CORD_to_const_char_star(CORD_all(def->name, "$", tag->name)), .fields=tag->fields));
+ header = CORD_all(header, field_header);
+ enum_def = CORD_all(enum_def, full_name, "$", tag->name, "_t ", tag->name, ";\n");
+ if (tag->fields) { // Constructor macros:
+ CORD arg_sig = CORD_EMPTY;
+ for (arg_ast_t *field = tag->fields; field; field = field->next) {
+ type_t *field_t = get_arg_ast_type(env, field);
+ arg_sig = CORD_all(arg_sig, compile_declaration(env, field_t, field->name));
+ if (field->next) arg_sig = CORD_cat(arg_sig, ", ");
+ }
+ if (arg_sig == CORD_EMPTY) arg_sig = "void";
+ CORD constructor_def = CORD_all(full_name, "_t ", full_name, "$tagged$", tag->name, "(", arg_sig, ");\n");
+ constructors = CORD_cat(constructors, constructor_def);
+ }
+ }
+ enum_def = CORD_cat(enum_def, "};\n};\n");
+ header = CORD_all(header, enum_def, constructors);
+ return CORD_all(header, compile_namespace_headers(env, def->name, def->namespace));
+}
+
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0