aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-03-03 14:12:40 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-03-03 14:12:40 -0500
commitc72d4ec8eb932e63c740983f2f6116de3ea36fba (patch)
treee8af3af8b996864fd15e611b68ee4ddb0f17941a
parentbde2a0b33833af613ab7d8949f25864ec268cb1e (diff)
Make constructors actually functions for enums
-rw-r--r--compile.c3
-rw-r--r--enums.c20
-rw-r--r--environment.h1
3 files changed, 21 insertions, 3 deletions
diff --git a/compile.c b/compile.c
index a7ab054f..88457ab7 100644
--- a/compile.c
+++ b/compile.c
@@ -1088,7 +1088,8 @@ module_code_t compile_file(ast_t *ast)
// CORD_asprintf("#line 0 %r\n", Str__quoted(ast->file->filename, false)),
env->code->imports, "\n",
env->code->typedefs, "\n",
- env->code->typecode, "\n"),
+ env->code->typecode, "\n",
+ env->code->fndefs, "\n"),
.c_file=CORD_all(
// CORD_asprintf("#line 0 %r\n", Str__quoted(ast->file->filename, false)),
env->code->staticdefs, "\n",
diff --git a/enums.c b/enums.c
index afd009fc..1e3d0773 100644
--- a/enums.c
+++ b/enums.c
@@ -107,8 +107,24 @@ void compile_enum_def(env_t *env, ast_t *ast)
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
compile_struct_def(env, WrapAST(ast, StructDef, .name=heap_strf("%s$%s", def->name, tag->name), .fields=tag->fields));
enum_def = CORD_all(enum_def, def->name, "$", tag->name, "_t ", tag->name, ";\n");
- CORD_appendf(&env->code->typedefs, "#define %s$tagged$%s(...) ((%s_t){$tag$%s$%s, .%s={__VA_ARGS__}})\n",
- def->name, tag->name, def->name, def->name, tag->name, tag->name);
+ // Constructor:
+ CORD arg_sig = CORD_EMPTY;
+ for (arg_ast_t *field = tag->fields; field; field = field->next) {
+ arg_sig = CORD_all(arg_sig, compile_type_ast(field->type), " ", field->name);
+ if (field->next) arg_sig = CORD_cat(arg_sig, ", ");
+ }
+ if (arg_sig == CORD_EMPTY) arg_sig = "void";
+ CORD constructor_def = CORD_all(def->name, "_t ", def->name, "$tagged$", tag->name, "(", arg_sig, ");\n");
+ env->code->fndefs = CORD_cat(env->code->fndefs, constructor_def);
+
+ CORD constructor_impl = CORD_all("public inline ", def->name, "_t ", def->name, "$tagged$", tag->name, "(", arg_sig, ") { return (",
+ def->name, "_t){.$tag=$tag$", def->name, "$", tag->name, ", .", tag->name, "={");
+ for (arg_ast_t *field = tag->fields; field; field = field->next) {
+ constructor_impl = CORD_all(constructor_impl, field->name);
+ if (field->next) constructor_impl = CORD_cat(constructor_impl, ", ");
+ }
+ constructor_impl = CORD_cat(constructor_impl, "}}; }\n");
+ 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);
diff --git a/environment.h b/environment.h
index bbbdd01d..47d1dea2 100644
--- a/environment.h
+++ b/environment.h
@@ -9,6 +9,7 @@ typedef struct {
CORD imports;
CORD typedefs;
CORD typecode;
+ CORD fndefs;
CORD staticdefs;
CORD funcs;
CORD typeinfos;