aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtins/c_string.c2
-rw-r--r--builtins/functions.c8
-rw-r--r--builtins/optionals.c5
-rw-r--r--builtins/types.h2
-rw-r--r--compile.c5
-rw-r--r--test/optionals.tm19
6 files changed, 31 insertions, 10 deletions
diff --git a/builtins/c_string.c b/builtins/c_string.c
index 3e3ef740..c7c7a563 100644
--- a/builtins/c_string.c
+++ b/builtins/c_string.c
@@ -46,7 +46,7 @@ PUREFUNC public uint64_t CString$hash(const char **c_str)
public const TypeInfo CString$info = {
.size=sizeof(char*),
.align=__alignof__(char*),
- .tag=CustomInfo,
+ .tag=CStringInfo,
.CustomInfo={.as_text=(void*)CString$as_text, .compare=(void*)CString$compare, .equal=(void*)CString$equal, .hash=(void*)CString$hash},
};
diff --git a/builtins/functions.c b/builtins/functions.c
index ed0889d4..e506fe1c 100644
--- a/builtins/functions.c
+++ b/builtins/functions.c
@@ -118,7 +118,7 @@ PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo *type)
errx(1, "Optional hash not implemented");
}
case EmptyStructInfo: return 0;
- case CustomInfo: case StructInfo: case EnumInfo: // These all share the same info
+ case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.hash)
goto hash_data;
return type->CustomInfo.hash(obj, type);
@@ -143,7 +143,7 @@ PUREFUNC public int32_t generic_compare(const void *x, const void *y, const Type
errx(1, "Optional compare not implemented");
}
case EmptyStructInfo: return 0;
- case CustomInfo: case StructInfo: case EnumInfo: // These all share the same info
+ case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.compare)
goto compare_data;
return type->CustomInfo.compare(x, y, type);
@@ -167,7 +167,7 @@ PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo
case OptionalInfo: {
errx(1, "Optional equal not implemented");
}
- case CustomInfo: case StructInfo: case EnumInfo: // These all share the same info
+ case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.equal)
goto use_generic_compare;
return type->CustomInfo.equal(x, y, type);
@@ -191,7 +191,7 @@ public Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo *ty
case EmptyStructInfo: return colorize ?
Text$concat(Text("\x1b[0;1m"), Text$from_str(type->EmptyStructInfo.name), Text("\x1b[m()"))
: Text$concat(Text$from_str(type->EmptyStructInfo.name), Text("()"));
- case CustomInfo: case StructInfo: case EnumInfo: // These all share the same info
+ case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.as_text)
fail("No text function provided for type!\n");
return type->CustomInfo.as_text(obj, colorize, type);
diff --git a/builtins/optionals.c b/builtins/optionals.c
index 88f08097..93fac2ed 100644
--- a/builtins/optionals.c
+++ b/builtins/optionals.c
@@ -42,9 +42,8 @@ static inline bool is_null(const void *obj, const TypeInfo *non_optional_type)
offset += non_optional_type->align - (offset % non_optional_type->align);
return *(bool*)(obj + offset);
}
- case EnumInfo: {
- return (*(int*)obj) == 0; // NULL tag
- }
+ case EnumInfo: return (*(int*)obj) == 0; // NULL tag
+ case CStringInfo: return (*(char**)obj) == NULL;
default: {
Text_t t = generic_as_text(NULL, false, non_optional_type);
errx(1, "is_null() not implemented for: %k", &t);
diff --git a/builtins/types.h b/builtins/types.h
index 38d8bdc5..a7b4bb51 100644
--- a/builtins/types.h
+++ b/builtins/types.h
@@ -18,7 +18,7 @@ typedef struct TypeInfo {
int64_t size, align;
struct { // Anonymous tagged union for convenience
enum { CustomInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ArrayInfo, ChannelInfo, TableInfo, FunctionInfo,
- OptionalInfo, TypeInfoInfo, OpaqueInfo, EmptyStructInfo } tag;
+ OptionalInfo, TypeInfoInfo, OpaqueInfo, EmptyStructInfo, CStringInfo } tag;
union {
struct {
equal_fn_t equal;
diff --git a/compile.c b/compile.c
index cc3603ae..58cb2733 100644
--- a/compile.c
+++ b/compile.c
@@ -328,7 +328,7 @@ static CORD compile_optional_check(env_t *env, ast_t *ast)
{
type_t *t = get_type(env, ast);
t = Match(t, OptionalType)->type;
- if (t->tag == PointerType || t->tag == FunctionType)
+ if (t->tag == PointerType || t->tag == FunctionType || t->tag == CStringType || t == THREAD_TYPE)
return CORD_all("(", compile(env, ast), " != NULL)");
else if (t->tag == BigIntType)
return CORD_all("((", compile(env, ast), ").small != 0)");
@@ -1688,6 +1688,8 @@ CORD compile(env_t *env, ast_t *ast)
switch (ast->tag) {
case Nil: {
type_t *t = parse_type_ast(env, Match(ast, Nil)->type);
+ if (t == THREAD_TYPE) return "NULL";
+
switch (t->tag) {
case BigIntType: return "NULL_INT";
case IntType: {
@@ -1705,6 +1707,7 @@ CORD compile(env_t *env, ast_t *ast)
case TableType: return "NULL_TABLE";
case SetType: return "NULL_TABLE";
case TextType: return "NULL_TEXT";
+ case CStringType: return "NULL";
case PointerType: return CORD_all("((", compile_type(t), ")NULL)");
case ClosureType: return "NULL_CLOSURE";
case NumType: return "nan(\"null\")";
diff --git a/test/optionals.tm b/test/optionals.tm
index a721deaa..521bba51 100644
--- a/test/optionals.tm
+++ b/test/optionals.tm
@@ -49,6 +49,12 @@ func maybe_lambda(should_i:Bool)-> func()?:
else:
return !func()
+func maybe_c_string(should_i:Bool)->CString?:
+ if should_i:
+ return ("hi":as_c_string())?
+ else:
+ return !CString
+
func main():
>> 5?
= 5? : Int?
@@ -162,6 +168,19 @@ func main():
fail("Truthy: $nope")
else: !! Falsey: $nope
+ do:
+ !! ...
+ !! C Strings:
+ >> yep := maybe_c_string(yes)
+ = CString("hi")?
+ >> nope := maybe_c_string(no)
+ = !CString
+ >> if yep: >> yep
+ else: fail("Falsey: $yep")
+ >> if nope:
+ fail("Truthy: $nope")
+ else: !! Falsey: $nope
+
if yep := maybe_int(yes):
>> yep
= 123 : Int