changed: removed `#quote` in favor of parameter syntax `[] {}`
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 3 Jun 2023 05:22:39 +0000 (00:22 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 3 Jun 2023 05:22:39 +0000 (00:22 -0500)
34 files changed:
compiler/include/astnodes.h
compiler/src/checker.c
compiler/src/clone.c
compiler/src/parser.c
compiler/src/symres.c
core/alloc/arena.onyx
core/container/array.onyx
core/container/bucket_array.onyx
core/container/iter.onyx
core/container/map.onyx
core/container/optional.onyx
core/container/result.onyx
core/container/slice.onyx
core/conv/format.onyx
core/encoding/csv.onyx
core/encoding/ini.onyx
core/encoding/json/encoder.onyx
core/encoding/utf8.onyx
core/net/tcp.onyx
core/os/file.onyx
core/random/random.onyx
core/runtime/info/helper.onyx
core/runtime/info/proc_tags.onyx
core/runtime/platform/wasi/wasi_env.onyx
core/string/string.onyx
core/time/date.onyx
examples/18_macros.onyx
interpreter/src/wasm/type.c
scripts/onyx-pkg.onyx
tests/aoc-2020/day24.onyx
tests/aoc-2021/day03.onyx
tests/aoc-2021/day15.onyx
tests/bucket_array.onyx
tests/switch_using_equals.onyx

index e145347128b7745932944d1aea1be75ad30f0c74..8bd054c1f88d2cc43438d9fdd503b30db7e7c703 100644 (file)
@@ -814,6 +814,7 @@ struct AstBlock         {
 
     Scope *scope;
     Scope *binding_scope;
+    Scope *quoted_block_capture_scope;
     BlockRule rules;
 
     u32 statement_idx;
@@ -1518,12 +1519,14 @@ struct AstCodeBlock {
     AstTyped_base;
 
     AstNode *code;
+    bh_arr(OnyxToken *) binding_symbols;
 };
 
 struct AstDirectiveInsert {
     AstTyped_base;
 
     AstTyped *code_expr;
+    bh_arr(AstTyped *) binding_exprs;
 };
 
 struct AstDirectiveInit {
index 2abf59de3b4c6521cededa733cd93f35e8434bae..a5fb1168cb8fc6fd7b4833d4578239cb278f518c 100644 (file)
@@ -2455,6 +2455,10 @@ CheckStatus check_insert_directive(AstDirectiveInsert** pinsert) {
         YIELD(insert->token->pos, "Waiting for resolution to code expression type.");
     }
 
+    bh_arr_each(AstTyped *, pexpr, insert->binding_exprs) {
+        CHECK(expression, pexpr);
+    }
+
     Type* code_type = type_build_from_ast(context.ast_alloc, builtin_code_type);
 
     TYPE_CHECK(&insert->code_expr, code_type) {
@@ -2469,8 +2473,53 @@ CheckStatus check_insert_directive(AstDirectiveInsert** pinsert) {
         ERROR(insert->token->pos, "Expected compile-time known expression of type 'Code'.");
     }
 
+    u32 bound_symbol_count = bh_arr_length(code_block->binding_symbols);
+    u32 bound_expr_count   = bh_arr_length(insert->binding_exprs);
+    if (bound_symbol_count > bound_expr_count) {
+        onyx_report_error(insert->token->pos, Error_Critical,
+                "Expected at least %d argument%s to unquote code block, only got %d.",
+                bound_symbol_count, bh_num_plural(bound_symbol_count), bound_expr_count);
+        ERROR(code_block->token->pos, "Here is the code block being unquoted.");
+    }
+
     AstNode* cloned_block = ast_clone(context.ast_alloc, code_block->code);
     cloned_block->next = insert->next;
+
+    if (bound_expr_count > 0) {
+        Scope **scope = NULL;
+
+        if (cloned_block->kind == Ast_Kind_Block) {
+            scope = &((AstBlock *) cloned_block)->quoted_block_capture_scope;
+
+        } else if (bound_symbol_count > 0) {
+            AstReturn* return_node = onyx_ast_node_new(context.ast_alloc, sizeof(AstReturn), Ast_Kind_Return);
+            return_node->token = cloned_block->token;
+            return_node->expr = (AstTyped *) cloned_block;
+
+            AstBlock* body_block = onyx_ast_node_new(context.ast_alloc, sizeof(AstBlock), Ast_Kind_Block);
+            body_block->token = cloned_block->token;
+            body_block->body = (AstNode *) return_node;
+            scope = &((AstBlock *) body_block)->quoted_block_capture_scope;
+
+            AstDoBlock* doblock = (AstDoBlock *) onyx_ast_node_new(context.ast_alloc, sizeof(AstDoBlock), Ast_Kind_Do_Block);
+            doblock->token = cloned_block->token;
+            doblock->block = body_block;
+            doblock->type = &type_auto_return;
+            doblock->next = cloned_block->next;
+
+            cloned_block = (AstNode *) doblock;
+        }
+
+        if (bound_symbol_count > 0) {
+            assert(scope);
+            *scope = scope_create(context.ast_alloc, NULL, code_block->token->pos);
+
+            fori (i, 0, bound_symbol_count) {
+                symbol_introduce(*scope, code_block->binding_symbols[i], (AstNode *) insert->binding_exprs[i]);
+            }
+        }
+    }
+
     *(AstNode **) pinsert = cloned_block;
 
     insert->flags |= Ast_Flag_Has_Been_Checked;
index 20897a40251294485fdb1293e27882b296c46a84..449899b042a6cb23ad0a1498b5f177834cc921ac 100644 (file)
@@ -272,6 +272,7 @@ AstNode* ast_clone(bh_allocator a, void* n) {
 
         case Ast_Kind_Block:
             ((AstBlock *) nn)->body = ast_clone_list(a, ((AstBlock *) node)->body);
+            ((AstBlock *) nn)->quoted_block_capture_scope = NULL;
             break;
 
         case Ast_Kind_Defer:
@@ -646,6 +647,15 @@ AstNode* ast_clone(bh_allocator a, void* n) {
 
         case Ast_Kind_Directive_Insert:
             C(AstDirectiveInsert, code_expr);
+
+            AstDirectiveInsert* id = (AstDirectiveInsert *) nn;
+            AstDirectiveInsert* is = (AstDirectiveInsert *) node;
+            id->binding_exprs = NULL;
+            bh_arr_new(global_heap_allocator, id->binding_exprs, bh_arr_length(is->binding_exprs));
+
+            bh_arr_each(AstTyped *, expr, is->binding_exprs) {
+                bh_arr_push(id->binding_exprs, (AstTyped *) ast_clone(a, (AstNode *) *expr));
+            }
             break;
 
         case Ast_Kind_Directive_Defined:
index 441d0dada2af26fa2a036e6c9dde4736e381c0d7..98e39149d744f70cc96dd614898d92507458dfe3 100644 (file)
@@ -614,8 +614,44 @@ static AstTyped* parse_factor(OnyxParser* parser) {
             break;
         }
 
-        case '?':
         case '[': {
+            // HACK CLEANUP
+            // :LinearTokenDependent
+            OnyxToken *matching = find_matching_paren(parser->curr);
+            if (matching->type == ']' &&
+                ((matching + 1)->type == '{' || (matching + 1)->type == '(')) {
+                AstCodeBlock* code_block = make_node(AstCodeBlock, Ast_Kind_Code_Block);
+                code_block->token = expect_token(parser, '[');
+
+                assert(builtin_code_type != NULL);
+                code_block->type_node = builtin_code_type;
+
+                bh_arr_new(global_heap_allocator, code_block->binding_symbols, 4);
+                while (!consume_token_if_next(parser, ']')) {
+                    if (parser->hit_unexpected_token) return (AstTyped *) code_block;
+
+                    OnyxToken *symbol = expect_token(parser, Token_Type_Symbol);
+                    bh_arr_push(code_block->binding_symbols, symbol);
+
+                    if (parser->curr->type != ']')
+                        expect_token(parser, ',');
+                }
+
+                if (parser->curr->type == '{') {
+                    code_block->code = (AstNode *) parse_block(parser, 1, NULL);
+                    ((AstBlock *) code_block->code)->rules = Block_Rule_Code_Block;
+                } else {
+                    code_block->code = (AstNode *) parse_expression(parser, 1);
+                }
+
+                retval = (AstTyped *) code_block;
+                break;
+            }
+
+            // :fallthrough
+        }
+
+        case '?': {
             AstType *type = parse_type(parser);
             retval = (AstTyped *) type;
             break;
@@ -768,43 +804,6 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 retval = (AstTyped *) defined;
                 break;
             }
-            else if (parse_possible_directive(parser, "quote")) {
-                OnyxToken* code_token = parser->curr - 1;
-
-                AstCodeBlock* code_block = make_node(AstCodeBlock, Ast_Kind_Code_Block);
-                code_block->token = code_token;
-
-                assert(builtin_code_type != NULL);
-                code_block->type_node = builtin_code_type;
-
-                if (parser->curr->type == '{') {
-                    code_block->code = (AstNode *) parse_block(parser, 1, NULL);
-                    ((AstBlock *) code_block->code)->rules = Block_Rule_Code_Block;
-
-                } else {
-                    code_block->code = (AstNode *) parse_expression(parser, 0);
-                }
-
-                retval = (AstTyped *) code_block;
-                break;
-            }
-            else if (next_tokens_are(parser, 2, '#', '(')) {
-                OnyxToken* code_token = expect_token(parser, '#');
-                expect_token(parser, '(');
-
-                AstCodeBlock* code_block = make_node(AstCodeBlock, Ast_Kind_Code_Block);
-                code_block->token = code_token;
-
-                assert(builtin_code_type != NULL);
-                code_block->type_node = builtin_code_type;
-
-                code_block->code = (AstNode *) parse_expression(parser, 0);
-
-                expect_token(parser, ')');
-
-                retval = (AstTyped *) code_block;
-                break;
-            }
             else if (parse_possible_directive(parser, "unquote")) {
                 AstDirectiveInsert* insert = make_node(AstDirectiveInsert, Ast_Kind_Directive_Insert);
                 insert->token = parser->curr - 1;
@@ -820,6 +819,19 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 insert->code_expr = parse_expression(parser, 0);
                 parser->parse_calls = 1;
 
+                if (consume_token_if_next(parser, '(')) {
+                    bh_arr_new(global_heap_allocator, insert->binding_exprs, 4);
+                    while (!consume_token_if_next(parser, ')')) {
+                        if (parser->hit_unexpected_token) break;
+
+                        AstTyped *expr = parse_expression(parser, 0);
+                        bh_arr_push(insert->binding_exprs, expr);
+
+                        if (parser->curr->type != ')')
+                            expect_token(parser, ',');
+                    }
+                }
+
                 retval = (AstTyped *) insert;
                 break;
             }
index 527b9be1472e5c6a3afad4c7437fc7a590c21342..385e77438d5efe136ca65a4f9b047a8206165e39 100644 (file)
@@ -916,6 +916,9 @@ static SymresStatus symres_directive_defined(AstDirectiveDefined** pdefined) {
 
 static SymresStatus symres_directive_insert(AstDirectiveInsert* insert) {
     SYMRES(expression, &insert->code_expr);
+    bh_arr_each(AstTyped *, pexpr, insert->binding_exprs) {
+        SYMRES(expression, pexpr);
+    }
     return Symres_Success;
 }
 
@@ -1003,6 +1006,9 @@ static SymresStatus symres_block(AstBlock* block) {
     if (block->binding_scope != NULL)
         scope_include(current_scope, block->binding_scope, block->token->pos);
 
+    if (block->quoted_block_capture_scope != NULL)
+        scope_include(current_scope, block->quoted_block_capture_scope, block->token->pos);
+
     if (block->body) {
         AstNode** start = &block->body;
         fori (i, 0, block->statement_idx) {
index 61ea86810b62bd79fb2dbfd39c87676b363bea9c..7e736b1b8d14d71679a4983a638cc1cd1b2c94e6 100644 (file)
@@ -156,7 +156,7 @@ get_allocated_bytes :: (arena: &Arena) -> u32 {
 }
 
 auto :: #match {
-    macro (size := 32 * 1024, $dest: Code = #(context.allocator)) {
+    macro (size := 32 * 1024, $dest: Code = [](context.allocator)) {
         use core.alloc {arena, heap_allocator}
 
         a := arena.make(heap_allocator, size);
index be2ad6e278ed400d04947b1782ee584727489d2a..8d0bca8f504a7165151ca15df0dc74bc5c869d8d 100644 (file)
@@ -300,7 +300,7 @@ concat :: (arr: &[..] $T, other: Iterator(T)) {
     Use `it` to refer to the current element being tested.
 
         arr := array.make(.[ 1, 2, 3, 4, 5 ]);
-        array.filter(&arr, #(it % 2 == 0));
+        array.filter(&arr, [v](v % 2 == 0));
         println(arr); // 2, 4
 """
 filter :: macro (arr: &[..] $T, body: Code) {
@@ -310,7 +310,7 @@ filter :: macro (arr: &[..] $T, body: Code) {
         defer i += 1;
 
         it := arr[i];
-        if !(#unquote body) do move += 1;
+        if !(#unquote body(it)) do move += 1;
         if move != 0 do arr.data[i] = arr.data[i + move];
     }
 
@@ -354,6 +354,7 @@ fill_range  :: slice.fill_range
 to_list     :: slice.to_list
 find        :: slice.find
 find_ptr    :: slice.find_ptr
+find_opt    :: slice.find_opt
 first       :: slice.first
 count_where :: slice.count_where
 windows     :: slice.windows
index e7eadb86ec8b6d67ea7fc9b5718357392953fde6..8df7e88276bab1ad6190c4115f61583d55200291 100644 (file)
@@ -99,7 +99,7 @@ for_each :: macro (b: Bucket_Array($T), body: Code) {
         for bucket_index: bucket.count {
             it := &bucket.data[bucket_index];
 
-            #unquote body;
+            #unquote body(it);
         }
     }
 }
index 07c477d13631b3905e8e77d08c5fe06b76580caf..d7a78478f48a8a39332a0c2725056f6db02449cc 100644 (file)
@@ -529,7 +529,7 @@ take_one :: (it: Iterator($T), no_close := false) -> (T, bool) {
     value: i32;
     iterator: Iterator(i32) = ...;
     
-    if #(value) << iterator {
+    if [](value) << iterator {
         ...iterater closed...
     }
 """
@@ -649,13 +649,13 @@ generic_dynamic_array_as_iter :: (x: &[..] $T, $access: Code, $return_type: type
 #overload
 as_iter :: macro (x: &[..] $T) => {
     G :: generic_dynamic_array_as_iter
-    return G(x, #(arr.data[current]), Iterator(T));
+    return G(x, [](arr.data[current]), Iterator(T));
 }
 
 #overload
 as_iter :: macro (x: &[..] $T, by_pointer: bool) => {
     G :: generic_dynamic_array_as_iter
-    return G(x, #(&arr.data[current]), Iterator(&T));
+    return G(x, [](&arr.data[current]), Iterator(&T));
 }
 
 
@@ -773,6 +773,14 @@ to_map :: (it: Iterator(Pair($K, $V)), allocator := context.allocator) -> Map(K,
     return m;
 }
 
+#doc """
+    Collects elements into an array, or a map, depending on if the
+    iterator produces a Pair(K, V) or not.
+"""
+collect :: #match {
+    to_array
+}
+
 
 #doc """
     Produces an iterator that first yields all values from the
@@ -832,7 +840,7 @@ prod :: (x: $I1/Iterable, y_iter: Iterator($Y)) => {
     Python:
         results = [it * 2 for it in [1, 2, 3, 4, 5]]
     Onyx:
-        results := iter.comp(u32.[1, 2, 3, 4, 5], #(it * 2));
+        results := iter.comp(u32.[1, 2, 3, 4, 5], [it](it * 2));
 """
 comp :: #match #local {}
 
@@ -843,7 +851,7 @@ comp :: macro (i: Iterator(&$V), value: Code) => {
 
     for __it: i {
         it := *__it;
-        a << (#unquote value);
+        a << (#unquote value(it));
     }
     return a;
 }
@@ -853,7 +861,7 @@ comp :: macro (i: Iterator($V), value: Code) => {
     it: V;
     a := make([..] typeof #unquote value);
 
-    for i do a << (#unquote value);
+    for i do a << (#unquote value(it));
     return a;
 }
 
index afaece43de27857289661ce00642782ed387f378..aa3b6d41ab0569f6dba92d20d043d44b8ce6752b 100644 (file)
@@ -213,7 +213,7 @@ to the value.
         *it += 10;
     }
 or:
-    m->update("test", #(*it += 10));
+    m->update("test", [v](*v += 10));
 """  
 update :: macro (map: ^Map, key: map.Key_Type, body: Code) {
     lookup_ :: lookup
@@ -221,7 +221,7 @@ update :: macro (map: ^Map, key: map.Key_Type, body: Code) {
 
     if lr.entry_index >= 0 {
         it := &map.entries[lr.entry_index].value;
-        #unquote body;
+        #unquote body(it);
     }
 }
 
index 6acb33e582fc9278ae2a190b609111b8d24e8349..fa7bad9477d8d421b055fec45b713c259766842b 100644 (file)
@@ -146,6 +146,15 @@ use core
         }
     }
 
+    with :: macro (o: ?$T, body: Code) {
+        switch o {
+            case .None ---;
+            case .Some => it {
+                #unquote body(it);
+            }
+        }
+    }
+
     #doc """
         Creates a scope that the `?` operator on an Optional type can
         return to, instead of returning from the enclosing function.
@@ -173,7 +182,7 @@ use core
                 // ...
             });
     """
-    try :: macro (body: Code, catch: Code = #quote {}) -> bool {
+    try :: macro (body: Code, catch: Code = []{}) -> bool {
         //
         // Using a 'do'-expression block to introduce a new
         // 'return' location. This way, when the code in the `body`
@@ -227,6 +236,7 @@ use core
 #operator ?? macro (opt: ?$T, catch: Code) -> T {
     switch value := opt; value {
         case .Some => v do return v;
+        case #default ---
     }
 
     #unquote catch;
index 2ed9c51dfb40a3f26601d52fb46dddf1551a98ce..edd5958957120a4e7aa32358fc6c941d8615e08e 100644 (file)
@@ -175,8 +175,8 @@ Result :: union (Ok_Type: type_expr, Err_Type: type_expr) {
     catch :: macro (r: Result($T, $E), on_err: Code) -> T {
         switch res := r; res {
             case .Ok => v  do return v;
-            case .Err {
-                #unquote on_err;
+            case .Err => err {
+                #unquote on_err(err);
             }
         }
     }
index e5fed63857d83417b7c9b3deeccf7adc51312ad5..a54385f20ed47a014c2f7e58b522554053dfae30 100644 (file)
@@ -166,7 +166,7 @@ contains :: #match #locked {
     }, 
 
     macro (arr: [] $T, $cmp: Code) -> bool {
-        for it: arr do if #unquote cmp do return true;
+        for it: arr do if #unquote cmp(it) do return true;
         return false;
     }
 }
@@ -371,7 +371,7 @@ unique :: (arr: &[] $T) {
 
         // OR
 
-        slice.fold(arr, 0, #(it + acc)) |> println();
+        slice.fold(arr, 0, [it](it + acc)) |> println();
 """
 fold :: #match #local {}
 
@@ -385,7 +385,7 @@ fold :: (arr: [] $T, init: $R, f: (T, R) -> R) -> R {
 #overload
 fold :: macro (arr: [] $T, init: $R, body: Code) -> R {
     acc := init;
-    for it: arr do acc = #unquote body;
+    for it: arr do acc = #unquote body(it, acc);
     return acc;
 }
 
@@ -395,12 +395,12 @@ fold :: macro (arr: [] $T, init: $R, body: Code) -> R {
 every :: #match #local {}
 
 #overload
-every :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.every(arr, #(predicate(it)));
+every :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.every(arr, [it](predicate(it)));
 
 #overload
 every :: macro (arr: [] $T, predicate_body: Code) -> bool {
     for arr {
-        if !(#unquote predicate_body) do return false;
+        if !(#unquote predicate_body(it)) do return false;
     }
     return true;
 }
@@ -411,12 +411,12 @@ every :: macro (arr: [] $T, predicate_body: Code) -> bool {
 some :: #match #local {}
 
 #overload
-some :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.some(arr, #(predicate(it)));
+some :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.some(arr, [it](predicate(it)));
 
 #overload
 some :: macro (arr: [] $T/type_is_struct, predicate_body: Code) -> bool {
     for & arr {
-        if #unquote predicate_body do return true;
+        if #unquote predicate_body(it) do return true;
     }
     return false;
 }
@@ -424,7 +424,7 @@ some :: macro (arr: [] $T/type_is_struct, predicate_body: Code) -> bool {
 #overload
 some :: macro (arr: [] $T, predicate_body: Code) -> bool {
     for arr {
-        if #unquote predicate_body do return true;
+        if #unquote predicate_body(it) do return true;
     }
     return false;
 }
@@ -481,7 +481,7 @@ find :: (arr: [] $T, value: T) -> i32 {
 find :: macro (arr: [] $T/type_is_struct, pred: Code) -> i32 {
     for i: arr.count {
         it := &arr[i];
-        if #unquote pred do return i;
+        if #unquote pred(it) do return i;
     }
 
     return -1;
@@ -491,7 +491,7 @@ find :: macro (arr: [] $T/type_is_struct, pred: Code) -> i32 {
 find :: macro (arr: [] $T, pred: Code) -> i32 {
     for i: arr.count {
         it := arr[i];
-        if #unquote pred do return i;
+        if #unquote pred(it) do return i;
     }
 
     return -1;
@@ -510,15 +510,38 @@ find_ptr :: (arr: [] $T, value: T) -> &T {
     return null;
 }
 
+#doc """
+    
+"""
+find_opt :: #match {
+    macro (arr: [] $T/type_is_struct, cond: Code) -> ? T {
+        for& it: arr {
+            if #unquote cond(it) {
+                return *it;
+            }
+        }
+        return .{};
+    },
+
+    macro (arr: [] $T, cond: Code) -> ? T {
+        for it: arr {
+            if #unquote cond(it) {
+                return it;
+            }
+        }
+        return .{};
+    },
+}
+
 first :: #match #locked {
     macro (arr: [] $T, predicate: (T) -> bool) -> &T {
         first :: first
-        return first(arr, #(predicate(it)));
+        return first(arr, [it](predicate(it)));
     },
 
     macro (arr: [] $T/type_is_struct, predicate_body: Code) -> &T {
         for & arr {
-            if #unquote predicate_body do return it;
+            if #unquote predicate_body(it) do return it;
         }
 
         return null;
@@ -530,7 +553,7 @@ first :: #match #locked {
         // structure.
         for &it_ptr: arr {
             it := *it_ptr;
-            if #unquote predicate_body do return it_ptr;
+            if #unquote predicate_body(it) do return it_ptr;
         }
 
         return null;
@@ -543,13 +566,13 @@ first :: #match #locked {
 count_where :: #match #local {}
 
 #overload
-count_where :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.count_where(arr, #(predicate(it)));
+count_where :: macro (arr: [] $T, predicate: (T) -> bool) => #this_package.count_where(arr, [it](predicate(it)));
 
 #overload
 count_where :: macro (arr: [] $T, predicate_body: Code) -> u32 {
     count: u32 = 0;
     for arr {
-        if #unquote predicate_body do count += 1;
+        if #unquote predicate_body(it) do count += 1;
     }
     return count;
 }
@@ -618,7 +641,7 @@ chunks :: (arr: [] $T, width: i32) -> Iterator([] T) {
 """
 greatest :: macro (arr: [] $T) -> (i32, T) {
     fold_idx_elem :: fold_idx_elem
-    return fold_idx_elem(arr, #(*A > *B));
+    return fold_idx_elem(arr, [](*A > *B));
 }
 
 #doc """
@@ -626,5 +649,5 @@ greatest :: macro (arr: [] $T) -> (i32, T) {
 """
 least :: macro (arr: [] $T) -> (i32, T) {
     fold_idx_elem :: fold_idx_elem
-    return fold_idx_elem(arr, #(*A < *B));
+    return fold_idx_elem(arr, [](*A < *B));
 }
index eb15333b0cba98071e0c21c92473259c117585ef..ce9aa44805c8745c21c61ebe083f51c54972b9fc 100644 (file)
@@ -729,7 +729,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) {
 
                 tag_value := *cast(&u32, v.data);
 
-                variant := array.first(u.variants, #(it.tag_value == tag_value));
+                variant := array.first(u.variants, [x](x.tag_value == tag_value));
 
                 if !variant {
                     output->write("unknown_variant");
index 915f1578a87baf128c036197aa1f6bb0312ae1e9..3e82d45b6708629040b924ef0485c4b5b509d627 100644 (file)
@@ -93,8 +93,8 @@ CSV_Column :: struct {
                         |> string.strip_trailing_whitespace();
 
             for header: string.split_iter(header_line, #char ",") {
-                member := array.first(output_type_info.members, #(do {
-                    if tag := array.first(it.tags, #(it.type == CSV_Column)); tag {
+                member := array.first(output_type_info.members, [](do {
+                    if tag := array.first(it.tags, [t](t.type == CSV_Column)); tag {
                         return any_as(*tag, CSV_Column).name == header;
                     }
 
@@ -144,7 +144,7 @@ CSV_Column :: struct {
             for &member: output_type_info.members {
                 if !#first do io.write(writer, ",");
 
-                if tag := array.first(member.tags, #(it.type == CSV_Column)); tag {
+                if tag := array.first(member.tags, [t](t.type == CSV_Column)); tag {
                     io.write(writer, any_as(*tag, CSV_Column).name);
                 } else {
                     io.write(writer, member.name);
index 56576c8a2b6be65d456cc1e8bd8ed4c5deecba7a..1fe9e8c1599161e8a053337f3874b7271cc6c3de 100644 (file)
@@ -91,7 +91,7 @@ parse_ini_file_inner :: (r: &io.Reader, output_ptr: any) -> (IniParseResult, Ini
         output.type = (cast(&info.Type_Info_Pointer) t).to;
     }
 
-    alloc.arena.auto(dest=#(context.temp_allocator));
+    alloc.arena.auto(dest=[](context.temp_allocator));
 
     active_item_ptr  := null;
     active_item_type := void;
index 25f570817a62a98f2231714d5f12785f9c5c18e4..60baaf1bcca942ff81f065a1cc2e1689ea894261 100644 (file)
@@ -211,11 +211,11 @@ encode :: (w: ^io.Writer, data: any) -> Encoding_Error {
 
             for ^member: s.members {
                 key := member.name;
-                if tag := array.first(member.tags, #(it.type == Custom_Key)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == Custom_Key)); tag != null {
                     key = (cast(^Custom_Key) tag.data).key;
                 }
 
-                if tag := array.first(member.tags, #(it.type == type_expr)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == type_expr)); tag != null {
                     if *cast(^type_expr, tag.data) == Ignore {
                         continue;
                     }
@@ -326,11 +326,11 @@ from_any :: (type: type_expr, in: rawptr, allocator := context.allocator) -> Val
 
             for^ member: s_info.members {
                 key := member.name;
-                if tag := array.first(member.tags, #(it.type == Custom_Key)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == Custom_Key)); tag != null {
                     key = (cast(^Custom_Key) tag.data).key;
                 }
 
-                if tag := array.first(member.tags, #(it.type == type_expr)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == type_expr)); tag != null {
                     if *cast(^type_expr, tag.data) == Ignore {
                         continue;
                     }
@@ -424,11 +424,11 @@ as_any :: (value: Value, type: type_expr, out: rawptr) {
 
             for^ member: s_info.members {
                 key := member.name;
-                if tag := array.first(member.tags, #(it.type == Custom_Key)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == Custom_Key)); tag != null {
                     key = (cast(^Custom_Key) tag.data).key;
                 }
 
-                if tag := array.first(member.tags, #(it.type == type_expr)); tag != null {
+                if tag := array.first(member.tags, [t](t.type == type_expr)); tag != null {
                     if *cast(^type_expr, tag.data) == Ignore {
                         continue;
                     }
index 3c1117d238ccfd7025adfe7b05f3c8286dffb808..a80450927f9abc8e344b23e1936e7b9cd0d16f47 100644 (file)
@@ -102,7 +102,7 @@ full_rune :: (buffer: [] u8) -> bool {
     // be a valid rune.
     if buffer.length < len do return false;
 
-    return array.every(buffer[1 .. buffer.length], #(it & 0xC0 == 0x80));
+    return array.every(buffer[1 .. buffer.length], [c](c & 0xC0 == 0x80));
 }
 
 rune_count :: (s: str) -> i32 {
index 66d35e9e41372a8309225c00045e0709c66ab4a0..f57281f35f614392783f98b21b3a66536c99bce8 100644 (file)
@@ -286,7 +286,7 @@ tcp_server_pulse :: (use server: &TCP_Server) -> bool {
         }
     }
 
-    client_count = array.count_where(clients, #(it != null));
+    client_count = array.count_where(clients, [v](v != null));
 
     return server.alive;
 }
@@ -308,7 +308,7 @@ tcp_server_broadcast :: (use server: &TCP_Server, data: [] u8, except: &TCP_Serv
 tcp_server_handle_events :: macro (server: &TCP_Server, handler: Code) {
     while server->pulse() {
         for iter.as_iter(&server.connection) {
-            switch it.kind do #unquote handler;
+            switch it.kind do #unquote handler(it);
         }
     }
 }
index c0e694e43b7870e0fd6be0fc8182371258fa7e87..c2c791f877bee386426eeb55f676d48b1212f665 100644 (file)
@@ -154,7 +154,7 @@ file_logger_open :: (filename: str, allocator := context.allocator) -> Result(&F
 
     file_logger.file = new(File, allocator);
 
-    *file_logger.file = open(filename, mode=.Append)->catch(#quote {
+    *file_logger.file = open(filename, mode=.Append)->catch([] {
         raw_free(allocator, file_logger.file);
         raw_free(allocator, file_logger);
 
index c8bbe7d3308ae9a0a67c716c16c49ce7d4cceeb1..2423fb32ff0392bfce45e3575e5c74d15c3cd7d8 100644 (file)
@@ -118,16 +118,16 @@ string :: (bytes_long: u32, alpha_numeric := false, allocator := context.allocat
     RANDOM_INCREMENT  :: cast(i64) 11
 
     #if #defined(runtime.platform.__random_get) {
-        __initial_value :: #(do {
+        __initial_value :: [](do {
             v: u64;
             runtime.platform.__random_get(.{ ~~&v, sizeof typeof v });
             return v;
         })
     } else {
         #if #defined(core.os.time) {
-            __initial_value :: #(core.os.time())
+            __initial_value :: [](core.os.time())
         } else {
-            __initial_value :: #(8675309)
+            __initial_value :: [](8675309)
         }
     }
 }
index b7c921de9b98ea11d0f6ab5b24f27088a44abba2..d97bbf214b340e2005a67c396780e8212e6709c5 100644 (file)
@@ -321,7 +321,7 @@ get_struct_method :: (type: type_expr, method_name: str) -> &any {
     info := cast(&Type_Info_Struct) get_type_info(type);
     if info.kind != .Struct do return null;
 
-    method := core.array.first(info.methods, #(it.name == method_name));
+    method := core.array.first(info.methods, [x](x.name == method_name));
     if method != null do return &method.func;
     return null;
 }
@@ -349,6 +349,6 @@ for_all_types :: macro (body: Code) {
         type_info := runtime.info.type_table[it];
         type_idx  : type_expr = ~~ it;
 
-        #unquote body;
+        #unquote body(type_info, type_idx);
     }
 }
index 6472e135b086eb6a5a1e4b195c4f0b47d769657a..42dfc491bb9bd4b5d025c2ceb87bae23d3f2ef38 100644 (file)
@@ -35,7 +35,7 @@ get_procedures_with_tag :: ($tag_type: type_expr) -> [] GPWT_Result(tag_type) {
     results := make([..] GPWT_Result(tag_type));
 
     for proc: tagged_procedures {
-        if tag := array.first(proc.tags, #(it.type == tag_type)); tag != null {
+        if tag := array.first(proc.tags, [v](v.type == tag_type)); tag != null {
             array.push(&results, .{
                 func = proc.func,
                 type = proc.type,
index df1b33fd157924a95ee05b77efd6930a7198e2c7..3ff2d07f86fd5db72517ed5692707deee99ebfd7 100644 (file)
@@ -48,7 +48,7 @@ __get_all_env :: () -> [] Pair(str, str) {
 __get_env :: (key: str) -> ? str {
     __lookup_all_envs();
 
-    return slice.first(all_env, #(it.first == key))
+    return slice.first(all_env, [v](v.first == key))
         |> Optional.from_ptr()
         |> Optional.transform(x => x.second);
 }
index 81736c81432979805334358ea55cba92bb51f56b..a1b89a402560d600ef383614a26639c702b598e1 100644 (file)
@@ -171,7 +171,7 @@ contains :: (s: str, substr: str) -> bool {
 join :: (strs: [] str, sep: str, allocator := context.allocator) -> str {
     if strs.count == 0 do return "";
 
-    len_sum := array.fold(strs, 0, #(acc + it.length));
+    len_sum := array.fold(strs, 0, [v, acc](acc + v.length));
     out := make(str, len_sum + (strs.count - 1) * sep.count);
 
     i := 0;
index eeb21b3eaa74769a06321a8d1bb098e34821f3a7..e84a90d5fa1a0aceef5902097316960b4a680aaf 100644 (file)
@@ -1,7 +1,6 @@
 package core.time
 
 use core {package, *}
-use runtime
 
 Date :: struct {
     year: i32;
index 1361d6d5d62bffda8576a081d71c1b9f4e15f46c..39a55e73ba70f4cbdae3698846fe48cbdf2ac093 100644 (file)
@@ -108,8 +108,8 @@ main :: (args: [] cstr) {
     triple_macro(simple_code);
 
     // As another small shorthand, if a code block only contains one expression (like the code block above),
-    // then you can write by wrapping the expression in #(...).
-    triple_macro(#(println("Short code block!")));
+    // then you can write by wrapping the expression in [](...).
+    triple_macro([](println("Short code block!")));
 
     // As yet another small piece of syntactic sugar, you can pass a code block to a macro or procedure in
     // the following way:
index 8bc6298f31890bf161096724de60875c0e0efc69..fc6e3ae478c0fb4d2669e3a122b43dea9db738d1 100644 (file)
@@ -157,7 +157,7 @@ WASM_DECLARE_VEC_IMPL(memorytype, *)
 
 // wasm_externtype_t
 
-const wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t *externtype) {
+wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t *externtype) {
     return externtype->kind;
 }
 
index ddedbc00cec4f6a1d4a2d853f34b9fa36ed2e4ef..6d2c1e4b0cd47551490e900b2af1739ced252a4a 100644 (file)
@@ -58,7 +58,7 @@ main :: (args: [] cstr) {
     command_procedures := runtime.info.get_procedures_with_tag(Command);
     defer delete(&command_procedures);
 
-    command_tag := array.first(command_procedures, #(it.tag.command == command));
+    command_tag := array.first(command_procedures, [p](p.tag.command == command));
     if !command_tag {
         run_help_command(arguments);
         return;
index 903e11a401bda49d004b509f9042305aacdb1d92..9d183c7c6340343329de972916fd8b8fcea39bc2 100644 (file)
@@ -108,7 +108,7 @@ main :: (args: [] cstr) {
                }
 
                for &cell: cells_to_consider {
-                       map.update(&grid, *cell, #quote { it.alive = it.next; });
+                       map.update(&grid, *cell, [v]{ v.alive = v.next; });
                }
 
                array.clear(&cells_to_consider);
index d9ccdd5715f2e4765f2468cbf573b992ded1bebb..e922a5f8b61fc9cc7a35f6b126bb2c2c89908d9d 100644 (file)
@@ -73,8 +73,8 @@ main :: (args) => {
         }
 
         for iter.as_iter(range.{ BITS - 1, 0, -1 }) {
-            filter_array(oxygen_array, it, #(A >= B));
-            filter_array(co2_array,    it, #(A <  B));
+            filter_array(oxygen_array, it, [](A >= B));
+            filter_array(co2_array,    it, [](A <  B));
         }
 
         printf("Part 2: {}\n", oxygen_array[0] * co2_array[0]);
index d1b084611ae569bb9f8a8eab3471df5cbf97dc53..e9ff322ff160b58818da5a897a8a1998e1035df4 100644 (file)
@@ -56,10 +56,10 @@ main :: (args) => {
                 }
             }
 
-            attempt_add(#(try.x > 0), -1, 0);
-            attempt_add(#(try.x < width * 5 - 1), 1, 0);
-            attempt_add(#(try.y > 0), 0, -1);
-            attempt_add(#(try.y < height * 5 - 1), 0, 1);
+            attempt_add([](try.x > 0), -1, 0);
+            attempt_add([](try.x < width * 5 - 1), 1, 0);
+            attempt_add([](try.y > 0), 0, -1);
+            attempt_add([](try.y < height * 5 - 1), 0, 1);
         }
 
         printf("Part 2: {}\n", minimum);
index d19715fb9a0e65b2f64b6f8b065b314a6bff529d..8a78e2e338b3531260ab267df049e2ac7b1c6434 100644 (file)
@@ -9,9 +9,9 @@ main :: (args: [] cstr) {
     printf("ba[10] is {}.\n", ba[10]);
 
     sum := 0;
-    bucket_array.for_each(ba, #quote {
-        printf("[{}] -> {}\n", bucket_index, *it);
-        sum += *it;
+    bucket_array.for_each(ba, [value] {
+        printf("[{}] -> {}\n", bucket_index, *value);
+        sum += *value;
     });
 
     for it: bucket_array.as_iter(&ba) {
index 9ed4e1a0c030ebe4c0073faf752255c8925e3650..e0fd805172dfd8142d1359d82f2f8ca1f1db3f02 100644 (file)
@@ -5,7 +5,7 @@ use core {*}
 Vector2 :: struct { x, y: i32; }
 #operator == macro (v1: Vector2, v2: Vector2) => v1.x == v2.x && v1.y == v2.y;
 
-none_of_the_above :: #quote {
+none_of_the_above :: [] {
     case #default {
         println("Got default!");
     }
@@ -29,4 +29,4 @@ main :: (args: [] cstr) {
 
         #unquote none_of_the_above;
     }
-}
\ No newline at end of file
+}