aboutsummaryrefslogtreecommitdiff
path: root/src/compile/enums.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 15:29:52 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 15:29:52 -0400
commit3f9f82ca53ed353d10ae65fc958e73193e8d9739 (patch)
treecb92b570cd78a015cb62ae5c776d14cad7fe2b22 /src/compile/enums.c
parent634d1ad756fca46e1e8aec93a265998232dd58a6 (diff)
Move more stuff into structs/enums files
Diffstat (limited to 'src/compile/enums.c')
-rw-r--r--src/compile/enums.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/compile/enums.c b/src/compile/enums.c
index 3abe0307..c28aafae 100644
--- a/src/compile/enums.c
+++ b/src/compile/enums.c
@@ -9,6 +9,7 @@
#include "../stdlib/tables.h"
#include "../stdlib/text.h"
#include "../typecheck.h"
+#include "pointer.h"
#include "structs.h"
Text_t compile_enum_typeinfo(env_t *env, ast_t *ast) {
@@ -140,4 +141,41 @@ Text_t compile_enum_header(env_t *env, ast_t *ast) {
return all_defs;
}
+public
+Text_t compile_empty_enum(type_t *t) {
+ DeclareMatch(enum_, t, EnumType);
+ tag_t *tag = enum_->tags;
+ assert(tag);
+ assert(tag->type);
+ if (Match(tag->type, StructType)->fields)
+ return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), ", .", tag->name, "=",
+ compile_empty(tag->type), "})");
+ else if (enum_has_fields(t)) return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), "})");
+ else return Texts("((", compile_type(t), ")", String(tag->tag_value), ")");
+}
+
+public
+Text_t compile_enum_field_access(env_t *env, ast_t *ast) {
+ DeclareMatch(f, ast, FieldAccess);
+ type_t *fielded_t = get_type(env, ast);
+ type_t *value_t = value_type(fielded_t);
+ DeclareMatch(e, value_t, EnumType);
+ for (tag_t *tag = e->tags; tag; tag = tag->next) {
+ if (streq(f->field, tag->name)) {
+ Text_t tag_name = namespace_name(e->env, e->env->namespace, Texts("tag$", tag->name));
+ if (fielded_t->tag == PointerType) {
+ Text_t fielded = compile_to_pointer_depth(env, f->fielded, 1, false);
+ return Texts("((", fielded, ")->$tag == ", tag_name, ")");
+ } else if (enum_has_fields(value_t)) {
+ Text_t fielded = compile(env, f->fielded);
+ return Texts("((", fielded, ").$tag == ", tag_name, ")");
+ } else {
+ Text_t fielded = compile(env, f->fielded);
+ return Texts("((", fielded, ") == ", tag_name, ")");
+ }
+ }
+ }
+ code_err(ast, "The field '", f->field, "' is not a valid tag name of ", type_to_str(value_t));
+}
+
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0