aboutsummaryrefslogtreecommitdiff
path: root/src/compile
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile')
-rw-r--r--src/compile/enums.c48
-rw-r--r--src/compile/headers.c61
-rw-r--r--src/compile/optionals.c30
-rw-r--r--src/compile/whens.c8
4 files changed, 40 insertions, 107 deletions
diff --git a/src/compile/enums.c b/src/compile/enums.c
index 853625ca..24da79b8 100644
--- a/src/compile/enums.c
+++ b/src/compile/enums.c
@@ -12,8 +12,6 @@ Text_t compile_enum_typeinfo(env_t *env, const char *name, tag_ast_t *tags) {
// Compile member types and constructors:
Text_t member_typeinfos = EMPTY_TEXT;
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
-
const char *tag_name = String(name, "$", tag->name);
type_t *tag_type = Table$str_get(*env->types, tag_name);
assert(tag_type && tag_type->tag == StructType);
@@ -38,9 +36,7 @@ Text_t compile_enum_typeinfo(env_t *env, const char *name, tag_ast_t *tags) {
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
const char *tag_type_name = String(name, "$", tag->name);
type_t *tag_type = Table$str_get(*env->types, tag_type_name);
- if (tag_type && Match(tag_type, StructType)->fields)
- typeinfo = Texts(typeinfo, "{\"", tag->name, "\", ", compile_type_info(tag_type), "}, ");
- else typeinfo = Texts(typeinfo, "{\"", tag->name, "\"}, ");
+ typeinfo = Texts(typeinfo, "{\"", tag->name, "\", ", compile_type_info(tag_type), "}, ");
}
typeinfo = Texts(typeinfo, "}}}};\n");
return Texts(member_typeinfos, typeinfo);
@@ -49,8 +45,6 @@ Text_t compile_enum_typeinfo(env_t *env, const char *name, tag_ast_t *tags) {
Text_t compile_enum_constructors(env_t *env, const char *name, tag_ast_t *tags) {
Text_t constructors = EMPTY_TEXT;
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
-
Text_t arg_sig = EMPTY_TEXT;
for (arg_ast_t *field = tag->fields; field; field = field->next) {
type_t *field_t = get_arg_ast_type(env, field);
@@ -76,25 +70,16 @@ Text_t compile_enum_constructors(env_t *env, const char *name, tag_ast_t *tags)
Text_t compile_enum_header(env_t *env, const char *name, tag_ast_t *tags) {
Text_t all_defs = EMPTY_TEXT;
Text_t none_name = namespace_name(env, env->namespace, Texts(name, "$none"));
- Text_t enum_name = namespace_name(env, env->namespace, Texts(name, "$$enum"));
Text_t enum_tags = Texts("{ ", none_name, "=0, ");
assert(Table$str_get(*env->types, name));
- bool has_any_tags_with_fields = false;
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
Text_t tag_name = namespace_name(env, env->namespace, Texts(name, "$tag$", tag->name));
enum_tags = Texts(enum_tags, tag_name);
if (tag->next) enum_tags = Texts(enum_tags, ", ");
- has_any_tags_with_fields = has_any_tags_with_fields || (tag->fields != NULL);
}
enum_tags = Texts(enum_tags, " }");
- if (!has_any_tags_with_fields) {
- Text_t enum_def = Texts("enum ", enum_name, " ", enum_tags, ";\n");
- Text_t info = namespace_name(env, env->namespace, Texts(name, "$$info"));
- return Texts(enum_def, "extern const TypeInfo_t ", info, ";\n");
- }
-
Text_t struct_name = namespace_name(env, env->namespace, Texts(name, "$$struct"));
Text_t enum_def = Texts("struct ", struct_name,
" {\n"
@@ -103,7 +88,6 @@ Text_t compile_enum_header(env_t *env, const char *name, tag_ast_t *tags) {
" $tag;\n"
"union {\n");
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
Text_t field_def = compile_struct_header(env, NewAST(tag->file, tag->start, tag->end, StructDef,
.name = Text$as_c_string(Texts(name, "$", tag->name)),
.fields = tag->fields));
@@ -117,8 +101,6 @@ Text_t compile_enum_header(env_t *env, const char *name, tag_ast_t *tags) {
Text_t info = namespace_name(env, env->namespace, Texts(name, "$$info"));
all_defs = Texts(all_defs, "extern const TypeInfo_t ", info, ";\n");
for (tag_ast_t *tag = tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
-
Text_t arg_sig = EMPTY_TEXT;
for (arg_ast_t *field = tag->fields; field; field = field->next) {
type_t *field_t = get_arg_ast_type(env, field);
@@ -140,11 +122,8 @@ Text_t compile_empty_enum(type_t *t) {
tag_t *tag = enum_->tags;
assert(tag);
assert(tag->type);
- if (Match(tag->type, StructType)->fields)
- return Texts("((", compile_type(t), "){.$tag=", tag->tag_value, ", .", tag->name, "=", compile_empty(tag->type),
- "})");
- else if (enum_has_fields(t)) return Texts("((", compile_type(t), "){.$tag=", tag->tag_value, "})");
- else return Texts("((", compile_type(t), ")", tag->tag_value, ")");
+ return Texts("((", compile_type(t), "){.$tag=", tag->tag_value, ", .", tag->name, "=", compile_empty(tag->type),
+ "})");
}
public
@@ -156,22 +135,11 @@ Text_t compile_enum_field_access(env_t *env, ast_t *ast) {
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 (tag->type != NULL && Match(tag->type, StructType)->fields) {
- Text_t member = compile_maybe_incref(
- env, WrapLiteralCode(ast, Texts("_e.", tag->name), .type = tag->type), tag->type);
- return Texts("({ ", compile_declaration(value_t, Text("_e")), " = ",
- compile_to_pointer_depth(env, f->fielded, 0, false), "; ", "_e.$tag == ", tag_name, " ? ",
- promote_to_optional(tag->type, member), " : ", compile_none(tag->type), "; })");
- } else if (fielded_t->tag == PointerType) {
- Text_t fielded = compile_to_pointer_depth(env, f->fielded, 1, false);
- return Texts("((", fielded, ")->$tag == ", tag_name, " ? OPTIONAL_EMPTY_STRUCT : NONE_EMPTY_STRUCT)");
- } else if (enum_has_fields(value_t)) {
- Text_t fielded = compile(env, f->fielded);
- return Texts("((", fielded, ").$tag == ", tag_name, " ? OPTIONAL_EMPTY_STRUCT : NONE_EMPTY_STRUCT)");
- } else {
- Text_t fielded = compile(env, f->fielded);
- return Texts("((", fielded, ") == ", tag_name, " ? OPTIONAL_EMPTY_STRUCT : NONE_EMPTY_STRUCT)");
- }
+ Text_t member =
+ compile_maybe_incref(env, WrapLiteralCode(ast, Texts("_e.", tag->name), .type = tag->type), tag->type);
+ return Texts("({ ", compile_declaration(value_t, Text("_e")), " = ",
+ compile_to_pointer_depth(env, f->fielded, 0, false), "; ", "_e.$tag == ", tag_name, " ? ",
+ promote_to_optional(tag->type, member), " : ", compile_none(tag->type), "; })");
}
}
code_err(ast, "The field '", f->field, "' is not a valid tag name of ", type_to_text(value_t));
diff --git a/src/compile/headers.c b/src/compile/headers.c
index 1dcf7abb..dc57da77 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -79,28 +79,16 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) {
*info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n");
} else if (ast->tag == EnumDef) {
DeclareMatch(def, ast, EnumDef);
- bool has_any_tags_with_fields = false;
- for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
- has_any_tags_with_fields = has_any_tags_with_fields || (tag->fields != NULL);
- }
+ Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$struct"));
+ Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type"));
+ *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n");
- if (has_any_tags_with_fields) {
- Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$struct"));
- Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type"));
- *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n");
-
- for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
- Text_t tag_struct =
- namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$struct"));
- Text_t tag_type =
- namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$type"));
- *info->header = Texts(*info->header, "typedef struct ", tag_struct, " ", tag_type, ";\n");
- }
- } else {
- Text_t enum_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$enum"));
- Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type"));
- *info->header = Texts(*info->header, "typedef enum ", enum_name, " ", type_name, ";\n");
+ for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
+ Text_t tag_struct =
+ namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$struct"));
+ Text_t tag_type =
+ namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$type"));
+ *info->header = Texts(*info->header, "typedef struct ", tag_struct, " ", tag_type, ";\n");
}
} else if (ast->tag == LangDef) {
DeclareMatch(def, ast, LangDef);
@@ -124,29 +112,16 @@ static void add_type_headers(type_ast_t *type_ast, void *userdata) {
// Force the type to get defined:
(void)parse_type_ast(info->env, type_ast);
DeclareMatch(enum_, type_ast, EnumTypeAST);
- bool has_any_tags_with_fields = false;
- for (tag_ast_t *tag = enum_->tags; tag; tag = tag->next) {
- has_any_tags_with_fields = has_any_tags_with_fields || (tag->fields != NULL);
- }
-
const char *name = String("enum$", (int64_t)(type_ast->start - type_ast->file->text));
- if (has_any_tags_with_fields) {
- Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$struct"));
- Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$type"));
- *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n");
-
- for (tag_ast_t *tag = enum_->tags; tag; tag = tag->next) {
- if (!tag->fields) continue;
- Text_t tag_struct =
- namespace_name(info->env, info->env->namespace, Texts(name, "$", tag->name, "$$struct"));
- Text_t tag_type =
- namespace_name(info->env, info->env->namespace, Texts(name, "$", tag->name, "$$type"));
- *info->header = Texts(*info->header, "typedef struct ", tag_struct, " ", tag_type, ";\n");
- }
- } else {
- Text_t enum_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$enum"));
- Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$type"));
- *info->header = Texts(*info->header, "typedef enum ", enum_name, " ", type_name, ";\n");
+ Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$struct"));
+ Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(name, "$$type"));
+ *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n");
+
+ for (tag_ast_t *tag = enum_->tags; tag; tag = tag->next) {
+ Text_t tag_struct =
+ namespace_name(info->env, info->env->namespace, Texts(name, "$", tag->name, "$$struct"));
+ Text_t tag_type = namespace_name(info->env, info->env->namespace, Texts(name, "$", tag->name, "$$type"));
+ *info->header = Texts(*info->header, "typedef struct ", tag_struct, " ", tag_type, ";\n");
}
*info->header = Texts(*info->header, compile_enum_header(info->env, name, enum_->tags));
diff --git a/src/compile/optionals.c b/src/compile/optionals.c
index 5ad67602..b9a3742e 100644
--- a/src/compile/optionals.c
+++ b/src/compile/optionals.c
@@ -103,10 +103,7 @@ Text_t check_none(type_t *t, Text_t value) {
else if (t->tag == BoolType) return Texts("((", value, ") == NONE_BOOL)");
else if (t->tag == TextType) return Texts("((", value, ").tag == TEXT_NONE)");
else if (t->tag == IntType || t->tag == ByteType || t->tag == StructType) return Texts("!(", value, ").has_value");
- else if (t->tag == EnumType) {
- if (enum_has_fields(t)) return Texts("((", value, ").$tag == 0)");
- else return Texts("((", value, ") == 0)");
- }
+ else if (t->tag == EnumType) return Texts("((", value, ").$tag == 0)");
print_err("Optional check not implemented for: ", type_to_text(t));
return EMPTY_TEXT;
}
@@ -139,20 +136,17 @@ Text_t compile_non_optional(env_t *env, ast_t *ast) {
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));
- return Texts("({ ", compile_declaration(enum_t, Text("_test_enum")), " = ",
- compile_to_pointer_depth(env, f->fielded, 0, true), ";",
- "if unlikely (_test_enum.$tag != ", tag_name, ") {\n", "#line ", line, "\n",
- "fail_source(", quoted_str(f->fielded->file->filename), ", ",
- (int64_t)(f->fielded->start - f->fielded->file->text), ", ",
- (int64_t)(f->fielded->end - f->fielded->file->text), ", ", "\"This was expected to be ",
- tag->name, ", but it was: \", ", expr_as_text(Text("_test_enum"), enum_t, Text("false")),
- ", \"\\n\");\n}\n",
- Match(tag->type, StructType)->fields
- ? compile_maybe_incref(
- env, WrapLiteralCode(value, Texts("_test_enum.", tag->name), .type = tag->type),
- tag->type)
- : Text("EMPTY_STRUCT"),
- "; })");
+ return Texts(
+ "({ ", compile_declaration(enum_t, Text("_test_enum")), " = ",
+ compile_to_pointer_depth(env, f->fielded, 0, true), ";",
+ "if unlikely (_test_enum.$tag != ", tag_name, ") {\n", "#line ", line, "\n", "fail_source(",
+ quoted_str(f->fielded->file->filename), ", ", (int64_t)(f->fielded->start - f->fielded->file->text),
+ ", ", (int64_t)(f->fielded->end - f->fielded->file->text), ", ", "\"This was expected to be ",
+ tag->name, ", but it was: \", ", expr_as_text(Text("_test_enum"), enum_t, Text("false")),
+ ", \"\\n\");\n}\n",
+ compile_maybe_incref(
+ env, WrapLiteralCode(value, Texts("_test_enum.", tag->name), .type = tag->type), tag->type),
+ "; })");
}
}
code_err(ast, "The field '", f->field, "' is not a valid tag name of ", type_to_text(enum_t));
diff --git a/src/compile/whens.c b/src/compile/whens.c
index 122c581c..618a667c 100644
--- a/src/compile/whens.c
+++ b/src/compile/whens.c
@@ -43,11 +43,7 @@ Text_t compile_when_statement(env_t *env, ast_t *ast) {
DeclareMatch(enum_t, subject_t, EnumType);
- Text_t code;
- if (enum_has_fields(subject_t))
- code = Texts("WHEN(", compile_type(subject_t), ", ", compile(env, when->subject), ", _when_subject, {\n");
- else code = Texts("switch(", compile(env, when->subject), ") {\n");
-
+ Text_t code = Texts("WHEN(", compile_type(subject_t), ", ", compile(env, when->subject), ", _when_subject, {\n");
for (when_clause_t *clause = when->clauses; clause; clause = clause->next) {
if (clause->pattern->tag == Var) {
const char *clause_tag_name = Match(clause->pattern, Var)->name;
@@ -132,7 +128,7 @@ Text_t compile_when_statement(env_t *env, ast_t *ast) {
} else {
code = Texts(code, "default: errx(1, \"Invalid tag!\");\n");
}
- code = Texts(code, "\n}", enum_has_fields(subject_t) ? Text(")") : EMPTY_TEXT, "\n");
+ code = Texts(code, "\n}", Text(")"), "\n");
return code;
}