From: Brendan Hansen Date: Mon, 6 Mar 2023 03:39:06 +0000 (-0600) Subject: added: coalesce operator (??) X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=6d3a4ed7938f9c6d432c14a9b4f3abf8182a156e;p=onyx.git added: coalesce operator (??) --- diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index 714c2e04..64be00f7 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -342,6 +342,8 @@ typedef enum BinaryOp { Binary_Op_Subscript_Equals = 37, Binary_Op_Ptr_Subscript = 38, + Binary_Op_Coalesce = 39, + Binary_Op_Count } BinaryOp; diff --git a/compiler/include/lex.h b/compiler/include/lex.h index 6665cd32..cd437ece 100644 --- a/compiler/include/lex.h +++ b/compiler/include/lex.h @@ -70,6 +70,7 @@ typedef enum TokenType { Token_Type_Dot_Dot, Token_Type_Tilde_Tilde, + Token_Type_Question_Question, Token_Type_Symbol, Token_Type_Literal_String, diff --git a/compiler/src/astnodes.c b/compiler/src/astnodes.c index b1a5f984..8cc2e2cc 100644 --- a/compiler/src/astnodes.c +++ b/compiler/src/astnodes.c @@ -131,6 +131,8 @@ const char *binaryop_string[Binary_Op_Count] = { "|>", "..", "->", "[]", "[]=", "^[]", + + "??" }; const char* entity_state_strings[Entity_State_Count] = { diff --git a/compiler/src/lex.c b/compiler/src/lex.c index 43079f69..e85304ca 100644 --- a/compiler/src/lex.c +++ b/compiler/src/lex.c @@ -450,6 +450,10 @@ whitespace_skipped: case '~': LITERAL_TOKEN("~~", 0, Token_Type_Tilde_Tilde); break; + + case '?': + LITERAL_TOKEN("??", 0, Token_Type_Question_Question); + break; } // Symbols diff --git a/compiler/src/parser.c b/compiler/src/parser.c index 76140ab7..4e94e76d 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -944,6 +944,8 @@ static inline i32 get_precedence(BinaryOp kind) { case Binary_Op_Method_Call: return 10; + case Binary_Op_Coalesce: return 11; + default: return -1; } } @@ -990,6 +992,7 @@ static BinaryOp binary_op_from_token_type(TokenType t) { case Token_Type_Dot_Dot: return Binary_Op_Range; case '[': return Binary_Op_Subscript; case Token_Type_Right_Arrow: return Binary_Op_Method_Call; + case Token_Type_Question_Question: return Binary_Op_Coalesce; default: return Binary_Op_Count; } } diff --git a/core/container/optional.onyx b/core/container/optional.onyx index 3c5e85e3..87202b9d 100644 --- a/core/container/optional.onyx +++ b/core/container/optional.onyx @@ -88,6 +88,13 @@ package core return #from_enclosing .{}; } + catch :: macro (o: ?$T, body: Code) -> T { + value := o; + if value.has_value do return value.value; + + #unquote body; + } + hash :: (o: ?$T/core.hash.Hashable) -> u32 { if !o.has_value do return 0; return core.hash.to_u32(o.value); @@ -100,6 +107,21 @@ package core return o1.value == o2.value; } +#operator ?? macro (opt: ?$T, catch: Code) -> T { + value := opt; + if value do return value.value; + + #unquote catch; +} + +#operator ?? macro (opt: ?$T, default: T) -> T { + value := opt; + if value do return value.value; + + return default; +} + + #overload __implicit_bool_cast :: macro (o: ?$T) => o.has_value;