diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-11 12:50:46 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-11 12:50:46 -0400 |
| commit | 908673c9d95a57e794dc1ee5708ffb511958abb9 (patch) | |
| tree | 0e72884a44e0ce3b9ee2ff15f3c1a54b107af865 | |
| parent | 30d39378c721aa6506c5aa038f6da9bf98cb1527 (diff) | |
Optional channels (plus fixed some channel bugs)
| -rw-r--r-- | builtins/channel.c | 8 | ||||
| -rw-r--r-- | builtins/channel.h | 8 | ||||
| -rw-r--r-- | builtins/optionals.c | 1 | ||||
| -rw-r--r-- | compile.c | 6 | ||||
| -rw-r--r-- | test/optionals.tm | 19 |
5 files changed, 32 insertions, 10 deletions
diff --git a/builtins/channel.c b/builtins/channel.c index b5868ee6..692322b5 100644 --- a/builtins/channel.c +++ b/builtins/channel.c @@ -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) { diff --git a/builtins/channel.h b/builtins/channel.h index 5eaf2a19..affed1c1 100644 --- a/builtins/channel.h +++ b/builtins/channel.h @@ -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 diff --git a/builtins/optionals.c b/builtins/optionals.c index 93fac2ed..5a524f35 100644 --- a/builtins/optionals.c +++ b/builtins/optionals.c @@ -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; @@ -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)"); diff --git a/test/optionals.tm b/test/optionals.tm index 521bba51..5d54b29e 100644 --- a/test/optionals.tm +++ b/test/optionals.tm @@ -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 |
