Implement optional hashing/equality/comparisons
This commit is contained in:
parent
990846debb
commit
10795782c6
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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?]
|
||||
|
Loading…
Reference in New Issue
Block a user