aboutsummaryrefslogtreecommitdiff
path: root/src/compile
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-10-05 17:52:33 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-10-05 17:52:33 -0400
commit398d2cab6988e20c59e7037ff7ef551540339abb (patch)
tree8c5154cfcd32d0664fd40ac8fa93f50f6434859a /src/compile
parent9b5b6b110bb80f8530dd7ca4e0cc9eb3236d8ad7 (diff)
Fix a bunch of issues with optional types
Diffstat (limited to 'src/compile')
-rw-r--r--src/compile/headers.c2
-rw-r--r--src/compile/integers.c8
-rw-r--r--src/compile/statements.c10
-rw-r--r--src/compile/structs.c8
-rw-r--r--src/compile/types.c4
5 files changed, 23 insertions, 9 deletions
diff --git a/src/compile/headers.c b/src/compile/headers.c
index bc0156ad..f132b312 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -106,6 +106,8 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) {
DeclareMatch(def, ast, LangDef);
*info->header = Texts(*info->header, "typedef Text_t ",
namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")), ";\n");
+ *info->header = Texts(*info->header, "typedef Text_t ", "Optional",
+ namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")), ";\n");
}
}
diff --git a/src/compile/integers.c b/src/compile/integers.c
index 41c2b78a..78d48b70 100644
--- a/src/compile/integers.c
+++ b/src/compile/integers.c
@@ -22,11 +22,13 @@ Text_t compile_int_to_type(env_t *env, ast_t *ast, type_t *target) {
return code;
}
- if (target->tag == BigIntType) return compile(env, ast);
+ if (non_optional(target)->tag == BigIntType) return compile(env, ast);
- if (target->tag == OptionalType && Match(target, OptionalType)->type)
+ if (target->tag == OptionalType && Match(target, OptionalType)->type) {
return Texts("((", compile_type(target),
- "){.value=", compile_int_to_type(env, ast, Match(target, OptionalType)->type), "})");
+ "){.value=", compile_int_to_type(env, ast, Match(target, OptionalType)->type),
+ ", .has_value=true})");
+ }
const char *literal = Match(ast, Int)->str;
OptionalInt_t int_val = Int$from_str(literal);
diff --git a/src/compile/statements.c b/src/compile/statements.c
index a9ec4327..0cd85b5d 100644
--- a/src/compile/statements.c
+++ b/src/compile/statements.c
@@ -117,7 +117,15 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) {
code = Texts(code, compile_statement(deferred->defer_env, deferred->block));
}
- type_t *ret_type = get_function_return_type(env, env->fn);
+ type_t *ret_type;
+ if (env->fn->tag == Lambda) {
+ if (Match(env->fn, Lambda)->ret_type != NULL)
+ ret_type = parse_type_ast(env, Match(env->fn, Lambda)->ret_type);
+ else ret_type = ret ? get_type(env, ret) : Type(VoidType);
+ } else {
+ ret_type = get_function_return_type(env, env->fn);
+ }
+
if (ret) {
if (ret_type->tag == VoidType || ret_type->tag == AbortType)
code_err(ast, "This function is not supposed to return any values, "
diff --git a/src/compile/structs.c b/src/compile/structs.c
index 2e7217f6..3f443c44 100644
--- a/src/compile/structs.c
+++ b/src/compile/structs.c
@@ -70,12 +70,14 @@ Text_t compile_struct_header(env_t *env, ast_t *ast) {
Text_t struct_code = def->external ? EMPTY_TEXT : Texts(type_code, " {\n", fields, "};\n");
type_t *t = Table$str_get(*env->types, def->name);
- Text_t unpadded_size = def->opaque ? Texts("sizeof(", type_code, ")") : Texts((int64_t)unpadded_struct_size(t));
Text_t typeinfo_code = Texts("extern const TypeInfo_t ", typeinfo_name, ";\n");
Text_t optional_code = EMPTY_TEXT;
if (!def->opaque) {
- optional_code = Texts("DEFINE_OPTIONAL_TYPE(", compile_type(t), ", ", unpadded_size, ", ",
- namespace_name(env, env->namespace, Texts("$Optional", def->name, "$$type")), ");\n");
+ optional_code = Texts("typedef struct {\n", compile_type(t),
+ " value;\n"
+ "Bool_t has_value;\n"
+ "} ",
+ namespace_name(env, env->namespace, Texts("$Optional", def->name, "$$type")), ";\n");
}
return Texts(struct_code, optional_code, typeinfo_code);
}
diff --git a/src/compile/types.c b/src/compile/types.c
index 58a0260b..2b345b41 100644
--- a/src/compile/types.c
+++ b/src/compile/types.c
@@ -135,8 +135,8 @@ Text_t compile_type_info(type_t *t) {
}
case OptionalType: {
type_t *non_optional = Match(t, OptionalType)->type;
- return Texts("Optional$info(sizeof(", compile_type(non_optional), "), __alignof__(", compile_type(non_optional),
- "), ", compile_type_info(non_optional), ")");
+ return Texts("Optional$info(", (int64_t)type_size(t), ", ", (int64_t)type_align(t), ", ",
+ compile_type_info(non_optional), ")");
}
case TypeInfoType: return Texts("Type$info(", quoted_text(type_to_text(Match(t, TypeInfoType)->type)), ")");
case MemoryType: return Text("&Memory$info");