Implement optional hashing/equality/comparisons

This commit is contained in:
Bruce Hill 2024-09-12 13:17:53 -04:00
parent 990846debb
commit 10795782c6
4 changed files with 23 additions and 6 deletions

View File

@ -115,9 +115,7 @@ PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo *type)
case ArrayInfo: return Array$hash(obj, type);
case ChannelInfo: return Channel$hash((Channel_t**)obj, type);
case TableInfo: return Table$hash(obj, type);
case OptionalInfo: {
errx(1, "Optional hash not implemented");
}
case OptionalInfo: return is_null(obj, type->OptionalInfo.type) ? 0 : generic_hash(obj, type->OptionalInfo.type);
case EmptyStructInfo: return 0;
case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.hash)
@ -141,7 +139,11 @@ PUREFUNC public int32_t generic_compare(const void *x, const void *y, const Type
case ChannelInfo: return Channel$compare((Channel_t**)x, (Channel_t**)y, type);
case TableInfo: return Table$compare(x, y, type);
case OptionalInfo: {
errx(1, "Optional compare not implemented");
bool x_is_null = is_null(x, type->OptionalInfo.type);
bool y_is_null = is_null(y, type->OptionalInfo.type);
if (x_is_null && y_is_null) return 0;
else if (x_is_null != y_is_null) return (int32_t)y_is_null - (int32_t)x_is_null;
else return generic_compare(x, y, type->OptionalInfo.type);
}
case EmptyStructInfo: return 0;
case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
@ -166,7 +168,11 @@ PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo
case TableInfo: return Table$equal(x, y, type);
case EmptyStructInfo: return true;
case OptionalInfo: {
errx(1, "Optional equal not implemented");
bool x_is_null = is_null(x, type->OptionalInfo.type);
bool y_is_null = is_null(y, type->OptionalInfo.type);
if (x_is_null && y_is_null) return true;
else if (x_is_null != y_is_null) return false;
else return generic_equal(x, y, type->OptionalInfo.type);
}
case CustomInfo: case StructInfo: case EnumInfo: case CStringInfo: // These all share the same info
if (!type->CustomInfo.equal)

View File

@ -14,7 +14,7 @@ public const Table_t NULL_TABLE = {.entries.length=-1};
public const Closure_t NULL_CLOSURE = {.fn=NULL};
public const Text_t NULL_TEXT = {.length=-1};
static inline bool is_null(const void *obj, const TypeInfo *non_optional_type)
public PUREFUNC bool is_null(const void *obj, const TypeInfo *non_optional_type)
{
if (non_optional_type == &Int$info)
return ((Int_t*)obj)->small == 0;

View File

@ -18,6 +18,7 @@ extern const Int_t NULL_INT;
extern const Closure_t NULL_CLOSURE;
extern const Text_t NULL_TEXT;
PUREFUNC bool is_null(const void *obj, const TypeInfo *non_optional_type);
Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo *type);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0

View File

@ -274,3 +274,13 @@ func main():
>> maybe_int(yes)!
= 123 : Int
# Test comparisons, hashing, equality:
>> (!Int == 5?)
= no
>> (5? == 5?)
= yes
>> {!Int, !Int}
= {!Int}
>> [5?, !Int, !Int, 6?]:sorted()
= [!Int, !Int, 5?, 6?]