Optional channels (plus fixed some channel bugs)

This commit is contained in:
Bruce Hill 2024-09-11 12:50:46 -04:00
parent 30d39378c7
commit 908673c9d9
5 changed files with 32 additions and 10 deletions

View File

@ -100,25 +100,25 @@ public void Channel$clear(channel_t *channel)
(void)pthread_cond_signal(&channel->cond);
}
public uint64_t Channel$hash(const channel_t **channel, const TypeInfo *type)
PUREFUNC public uint64_t Channel$hash(channel_t **channel, const TypeInfo *type)
{
(void)type;
return siphash24((void*)*channel, sizeof(channel_t*));
}
PUREFUNC public int32_t Channel$compare(const channel_t **x, const channel_t **y, const TypeInfo *type)
PUREFUNC public int32_t Channel$compare(channel_t **x, channel_t **y, const TypeInfo *type)
{
(void)type;
return (*x > *y) - (*x < *y);
}
PUREFUNC bool Channel$equal(const channel_t **x, const channel_t **y, const TypeInfo *type)
PUREFUNC public bool Channel$equal(channel_t **x, channel_t **y, const TypeInfo *type)
{
(void)type;
return (*x == *y);
}
Text_t Channel$as_text(const channel_t **channel, bool colorize, const TypeInfo *type)
public Text_t Channel$as_text(channel_t **channel, bool colorize, const TypeInfo *type)
{
const TypeInfo *item_type = type->ChannelInfo.item;
if (!channel) {

View File

@ -21,9 +21,9 @@ void Channel$peek(channel_t *channel, void *out, bool front, int64_t item_size);
#define Channel$peek_value(channel, front, t) ({ t _val; Channel$peek(channel, &_val, front, sizeof(t)); _val; })
void Channel$clear(channel_t *channel);
Array_t Channel$view(channel_t *channel);
PUREFUNC uint64_t Channel$hash(const channel_t **channel, const TypeInfo *type);
PUREFUNC int32_t Channel$compare(const channel_t **x, const channel_t **y, const TypeInfo *type);
PUREFUNC bool Channel$equal(const channel_t **x, const channel_t **y, const TypeInfo *type);
Text_t Channel$as_text(const channel_t **channel, bool colorize, const TypeInfo *type);
PUREFUNC uint64_t Channel$hash(channel_t **channel, const TypeInfo *type);
PUREFUNC int32_t Channel$compare(channel_t **x, channel_t **y, const TypeInfo *type);
PUREFUNC bool Channel$equal(channel_t **x, channel_t **y, const TypeInfo *type);
Text_t Channel$as_text(channel_t **channel, bool colorize, const TypeInfo *type);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0

View File

@ -31,6 +31,7 @@ static inline bool is_null(const void *obj, const TypeInfo *non_optional_type)
return ((OptionalInt8_t*)obj)->is_null;
switch (non_optional_type->tag) {
case ChannelInfo: return *(channel_t**)obj == NULL;
case PointerInfo: return *(void**)obj == NULL;
case TextInfo: return ((Text_t*)obj)->length < 0;
case ArrayInfo: return ((Array_t*)obj)->length < 0;

View File

@ -222,7 +222,7 @@ CORD compile_type(type_t *t)
switch (nonnull->tag) {
case BoolType: case CStringType: case BigIntType: case NumType: case TextType:
case ArrayType: case SetType: case TableType: case FunctionType: case ClosureType:
case PointerType: case EnumType:
case PointerType: case EnumType: case ChannelType:
return compile_type(nonnull);
case IntType:
return CORD_all("Optional", compile_type(nonnull));
@ -328,7 +328,8 @@ 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 || t->tag == CStringType || t == THREAD_TYPE)
if (t->tag == PointerType || t->tag == FunctionType || t->tag == CStringType
|| t->tag == ChannelType || t == THREAD_TYPE)
return CORD_all("(", compile(env, ast), " != NULL)");
else if (t->tag == BigIntType)
return CORD_all("((", compile(env, ast), ").small != 0)");
@ -1706,6 +1707,7 @@ CORD compile(env_t *env, ast_t *ast)
case ArrayType: return "NULL_ARRAY";
case TableType: return "NULL_TABLE";
case SetType: return "NULL_TABLE";
case ChannelType: return "NULL";
case TextType: return "NULL_TEXT";
case CStringType: return "NULL";
case PointerType: return CORD_all("((", compile_type(t), ")NULL)");

View File

@ -55,6 +55,12 @@ func maybe_c_string(should_i:Bool)->CString?:
else:
return !CString
func maybe_channel(should_i:Bool)->|Int|?:
if should_i:
return |:Int|?
else:
return !|Int|
func main():
>> 5?
= 5? : Int?
@ -181,6 +187,19 @@ func main():
fail("Truthy: $nope")
else: !! Falsey: $nope
do:
!! ...
!! Channels:
>> yep := maybe_channel(yes)
# No "=" test here because channels use addresses in the text version
>> nope := maybe_channel(no)
= !|:Int|
>> if yep: >> yep
else: fail("Falsey: $yep")
>> if nope:
fail("Truthy: $nope")
else: !! Falsey: $nope
if yep := maybe_int(yes):
>> yep
= 123 : Int