Use optional ints in the array find()/first() API

This commit is contained in:
Bruce Hill 2024-09-11 01:39:19 -04:00
parent 7126755275
commit 23209a0aab
4 changed files with 16 additions and 16 deletions

View File

@ -13,6 +13,7 @@
#include "array.h"
#include "functions.h"
#include "integers.h"
#include "optionals.h"
#include "table.h"
#include "text.h"
#include "types.h"
@ -227,20 +228,19 @@ public Int_t Array$find(Array_t arr, void *item, const TypeInfo *type)
if (generic_equal(item, arr.data + i*arr.stride, item_type))
return I(i+1);
}
return I(0);
return NULL_INT;
}
public void *Array$first(Array_t arr, closure_t predicate)
public Int_t Array$first(Array_t arr, closure_t predicate)
{
bool (*is_good)(void*, void*) = (void*)predicate.fn;
for (int64_t i = 0; i < arr.length; i++) {
if (is_good(arr.data + i*arr.stride, predicate.userdata))
return arr.data + i*arr.stride;
return I(i+1);
}
return NULL;
return NULL_INT;
}
public void Array$sort(Array_t *arr, closure_t comparison, int64_t padded_item_size)
{
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)

View File

@ -69,7 +69,7 @@ void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeI
#define Array$remove_item_value(arr, item_expr, max, type) ({ __typeof(item_expr) item = item_expr; Array$remove_item(arr, &item, max, type); })
Int_t Array$find(Array_t arr, void *item, const TypeInfo *type);
#define Array$find_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$find(arr, &item, type); })
void *Array$first(Array_t arr, closure_t predicate);
Int_t Array$first(Array_t arr, closure_t predicate);
void Array$sort(Array_t *arr, closure_t comparison, int64_t padded_item_size);
Array_t Array$sorted(Array_t arr, closure_t comparison, int64_t padded_item_size);
void Array$shuffle(Array_t *arr, int64_t padded_item_size);

View File

@ -163,13 +163,13 @@ func main():
>> [nums:binary_search(i, func(a,b:&Int): a:abs() <> b:abs()) for i in nums]
= [1, 2, 3, 4, 5]
>> [10, 20, 30]:find(20)
= 2
>> [10, 20, 30]:find(999)
= 0
>> ["a", "b", "c"]:find("b")
= 2?
>> ["a", "b", "c"]:find("XXX")
= !Int
# >> [10, 20]:first(func(i:&Int): i:is_prime())
# = !Int
# >> [4, 5, 6]:first(func(i:&Int): i:is_prime())
# = @%5?
>> [10, 20]:first(func(i:&Int): i:is_prime())
= !Int
>> [4, 5, 6]:first(func(i:&Int): i:is_prime())
= 2?

View File

@ -773,8 +773,8 @@ type_t *get_type(env_t *env, ast_t *ast)
else if (streq(call->name, "by")) return self_value_t;
else if (streq(call->name, "clear")) return Type(VoidType);
else if (streq(call->name, "counts")) return Type(TableType, .key_type=item_type, .value_type=INT_TYPE);
else if (streq(call->name, "find")) return INT_TYPE;
else if (streq(call->name, "first")) return Type(OptionalType, .type=Type(PointerType, .pointed=item_type, .is_readonly=true));
else if (streq(call->name, "find")) return Type(OptionalType, .type=INT_TYPE);
else if (streq(call->name, "first")) return Type(OptionalType, .type=INT_TYPE);
else if (streq(call->name, "from")) return self_value_t;
else if (streq(call->name, "has")) return Type(BoolType);
else if (streq(call->name, "heap_pop")) return item_type;