aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtins/channel.c8
-rw-r--r--builtins/channel.h8
-rw-r--r--builtins/optionals.c1
-rw-r--r--compile.c6
-rw-r--r--test/optionals.tm19
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;
diff --git a/compile.c b/compile.c
index 58cb2733..6688a5ed 100644
--- a/compile.c
+++ b/compile.c
@@ -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