aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-18 20:58:36 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-18 20:58:36 -0400
commit6f3b2c073a968e57d787849dce42ff1253ed0102 (patch)
treee5fb20ae4322fdbbded412c2cb771b7e4ed68ecf /compile.c
parent967b649da20f1cb2011025456853cb55f25e9a88 (diff)
Add `enum.tag` as a way to do a boolean test for whether a value has a
particular tag or not
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/compile.c b/compile.c
index fb60e387..17d19f30 100644
--- a/compile.c
+++ b/compile.c
@@ -270,7 +270,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
auto enum_t = Match(subject_t, EnumType);
CORD code = CORD_all("{ ", compile_type(subject_t), " subject = ", compile(env, when->subject), ";\n"
- "switch (subject.$tag) {");
+ "switch (subject.tag) {");
for (when_clause_t *clause = when->clauses; clause; clause = clause->next) {
const char *clause_tag_name = Match(clause->tag_name, Var)->name;
code = CORD_all(code, "case ", namespace_prefix(enum_t->env->libname, enum_t->env->namespace), "tag$", clause_tag_name, ": {\n");
@@ -1077,7 +1077,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
}
env_t *enum_env = Match(fn->ret, EnumType)->env;
- next_fn = CORD_all("(cur=", next_fn, iter_t->tag == ClosureType ? "(next.userdata)" : "()", ").$tag == ",
+ next_fn = CORD_all("(cur=", next_fn, iter_t->tag == ClosureType ? "(next.userdata)" : "()", ").tag == ",
namespace_prefix(enum_env->libname, enum_env->namespace), "tag$Next");
if (for_->empty) {
@@ -2610,6 +2610,22 @@ CORD compile(env_t *env, ast_t *ast)
}
code_err(ast, "The field '%s' is not a valid field name of %T", f->field, value_t);
}
+ case EnumType: {
+ auto e = Match(value_t, EnumType);
+ for (tag_t *tag = e->tags; tag; tag = tag->next) {
+ if (streq(f->field, tag->name)) {
+ CORD prefix = namespace_prefix(e->env->libname, e->env->namespace);
+ if (fielded_t->tag == PointerType) {
+ CORD fielded = compile_to_pointer_depth(env, f->fielded, 1, false);
+ return CORD_all("((", fielded, ")->tag == ", prefix, "tag$", tag->name, ")");
+ } else {
+ CORD fielded = compile(env, f->fielded);
+ return CORD_all("((", fielded, ").tag == ", prefix, "tag$", tag->name, ")");
+ }
+ }
+ }
+ code_err(ast, "The field '%s' is not a valid tag name of %T", f->field, value_t);
+ }
case ArrayType: {
if (streq(f->field, "length"))
return CORD_all("Int64_to_Int((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)");