diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-06-06 16:28:53 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-06-06 16:28:53 -0400 |
| commit | 8c7d53008072dfda8b9d60be92fae1a8046fae5d (patch) | |
| tree | 769407e0461b3c989c27a740c423827a21adfa91 /enums.c | |
| parent | 31c8d0af1597b6b4996a90808b1b8c0983db309e (diff) | |
Split header compilation into a separate function
Diffstat (limited to 'enums.c')
| -rw-r--r-- | enums.c | 52 |
1 files changed, 36 insertions, 16 deletions
@@ -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 |
