aboutsummaryrefslogtreecommitdiff
path: root/src/compile/optionals.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile/optionals.c')
-rw-r--r--src/compile/optionals.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/compile/optionals.c b/src/compile/optionals.c
index 4b360b31..fa7f6f29 100644
--- a/src/compile/optionals.c
+++ b/src/compile/optionals.c
@@ -5,6 +5,7 @@
#include "../stdlib/text.h"
#include "../stdlib/util.h"
#include "../types.h"
+#include "types.h"
Text_t optional_into_nonnone(type_t *t, Text_t value) {
if (t->tag == OptionalType) t = Match(t, OptionalType)->type;
@@ -83,3 +84,29 @@ Text_t compile_none(type_t *t) {
}
return EMPTY_TEXT;
}
+
+public
+Text_t check_none(type_t *t, Text_t value) {
+ t = Match(t, OptionalType)->type;
+ // NOTE: these use statement expressions ({...;}) because some compilers
+ // complain about excessive parens around equality comparisons
+ if (t->tag == PointerType || t->tag == FunctionType || t->tag == CStringType)
+ return Texts("({", value, " == NULL;})");
+ else if (t == PATH_TYPE) return Texts("({(", value, ").type.$tag == PATH_NONE;})");
+ else if (t == PATH_TYPE_TYPE) return Texts("({(", value, ").$tag == PATH_NONE;})");
+ else if (t->tag == BigIntType) return Texts("({(", value, ").small == 0;})");
+ else if (t->tag == ClosureType) return Texts("({(", value, ").fn == NULL;})");
+ else if (t->tag == NumType)
+ return Texts(Match(t, NumType)->bits == TYPE_NBITS64 ? "Num$isnan(" : "Num32$isnan(", value, ")");
+ else if (t->tag == ListType) return Texts("({(", value, ").length < 0;})");
+ else if (t->tag == TableType || t->tag == SetType) return Texts("({(", value, ").entries.length < 0;})");
+ else if (t->tag == BoolType) return Texts("({(", value, ") == NONE_BOOL;})");
+ else if (t->tag == TextType) return Texts("({(", value, ").length < 0;})");
+ else if (t->tag == IntType || t->tag == ByteType || t->tag == StructType) return Texts("(", value, ").is_none");
+ else if (t->tag == EnumType) {
+ if (enum_has_fields(t)) return Texts("({(", value, ").$tag == 0;})");
+ else return Texts("((", value, ") == 0)");
+ }
+ print_err("Optional check not implemented for: ", type_to_str(t));
+ return EMPTY_TEXT;
+}