diff --git a/lib/std/collections/list.c3 b/lib/std/collections/list.c3 index dc4921cfb..45eb5d2b1 100644 --- a/lib/std/collections/list.c3 +++ b/lib/std/collections/list.c3 @@ -91,6 +91,7 @@ fn void List.add_all(List* list, List* other_list) } } + fn Type[] List.to_array(List* list, Allocator* using = mem::heap()) { if (!list.size) return Type[] {}; @@ -99,6 +100,11 @@ fn Type[] List.to_array(List* list, Allocator* using = mem::heap()) return result; } +/** + * Reverse the elements in a list. + * + * @param [&inout] list "The list to reverse" + **/ fn void List.reverse(List* list) { if (list.size < 2) return; @@ -203,7 +209,7 @@ fn void List.swap(List* list, usz i, usz j) * @param filter "The function to determine if it should be removed or not" * @return "the number of deleted elements" **/ -fn usz List.delete_if(List* list, ElementPredicate filter) +fn usz List.remove_if(List* list, ElementPredicate filter) { usz size = list.size; for (usz i = size; i > 0; i--) @@ -321,12 +327,13 @@ fn bool List.contains(List* list, Type value) return false; } + /** * @param [&inout] list "The list to remove elements from" * @param value "The value to remove" * @return "the number of deleted elements." **/ -fn usz List.delete(List* list, Type value) +fn usz List.remove(List* list, Type value) { usz size = list.size; for (usz i = size; i > 0; i--) @@ -341,6 +348,13 @@ fn usz List.delete(List* list, Type value) return size - list.size; } +fn void List.remove_all(List* list, List* other_list) +{ + if (!other_list.size) return; + foreach (v : other_list) list.remove(v); +} + + $endif $if (Type.kindof == POINTER) diff --git a/releasenotes.md b/releasenotes.md index 28289f2df..d89b569ae 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -77,7 +77,7 @@ ### Stdlib changes - Stdlib updates to string. -- Many additions to `List`: `delete`, `array_view`, `add_all`, `compact` etc +- Many additions to `List`: `remove`, `array_view`, `add_all`, `compact` etc - Added dstringwriter. - Improved printf formatting. - is_finite/is_nam/is_inf added. diff --git a/resources/grammar/grammar.y b/resources/grammar/grammar.y index 0176c602c..2b105625e 100644 --- a/resources/grammar/grammar.y +++ b/resources/grammar/grammar.y @@ -104,6 +104,10 @@ bytes_expr | bytes_expr BYTES ; +expr_block + : LBRAPIPE opt_stmt_list RBRAPIPE + ; + primary_expression : string_expr | INTEGER @@ -125,7 +129,7 @@ primary_expression | '(' type ')' '.' IDENT | '(' type ')' '.' TYPEID | '(' expr ')' - | LBRAPIPE opt_stmt_list RBRAPIPE + | expr_block | ct_call '(' flat_path ')' | ct_arg '(' expr ')' | ct_analyse '(' expr ')' @@ -156,19 +160,25 @@ call_inline_attributes ; call_invocation - : '(' call_arg_list ')' compound_statement - | '(' call_arg_list ')' call_inline_attributes compound_statement - | '(' call_arg_list ')' + : '(' call_arg_list ')' | '(' call_arg_list ')' call_inline_attributes ; +access_ident + : IDENT + | AT_IDENT + | HASH_IDENT + | CT_EVAL '(' expr ')' + | TYPEID + ; + call_expr : primary_expression | call_expr '[' range_loc ']' | call_expr '[' range_expr ']' | call_expr call_invocation - | call_expr '.' IDENT - | call_expr '.' AT_IDENT + | call_expr call_invocation compound_statement + | call_expr '.' access_ident | call_expr INC_OP | call_expr DEC_OP | call_expr '!' diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 8a17c5aae..fae520ed4 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -90,7 +90,6 @@ inline Expr *parse_precedence_with_left_side(ParseContext *c, Expr *left_side, P while (1) { TokenType tok = c->tok; - Precedence token_precedence = rules[tok].precedence; // See if the operator precedence is greater than the last, if so exit. // Note that if the token is not an operator then token_precedence = 0 @@ -900,10 +899,6 @@ static Expr *parse_call_expr(ParseContext *c, Expr *left) SEMA_ERROR_HERE("Expected a macro body here."); return poisoned_expr; } - if (tok_is(c, TOKEN_LBRACE)) - { - ASSIGN_ASTID_OR_RET(call->call_expr.body, parse_compound_stmt(c), poisoned_expr); - } Attr *attr; int force_inline = -1; while (1) @@ -947,6 +942,10 @@ static Expr *parse_call_expr(ParseContext *c, Expr *left) call->call_expr.attr_force_inline = force_inline == 1; call->call_expr.attr_force_noinline = force_inline == 0; } + if (tok_is(c, TOKEN_LBRACE)) + { + ASSIGN_ASTID_OR_RET(call->call_expr.body, parse_compound_stmt(c), poisoned_expr); + } return call; } diff --git a/test/unit/stdlib/collections/list.c3 b/test/unit/stdlib/collections/list.c3 index 3bf2cf05e..8f7e569d8 100644 --- a/test/unit/stdlib/collections/list.c3 +++ b/test/unit/stdlib/collections/list.c3 @@ -16,7 +16,7 @@ fn void! test_delete_contains_index() test.push(3); assert(test.array_view() == int[]{ 1, 2, 3 }); assert(test.contains(3)); - test.delete(1); + test.remove(1); assert(test.array_view() == int[]{ 2, 3 }); assert(!test.contains(1)); assert(test.contains(2)); @@ -26,7 +26,7 @@ fn void! test_delete_contains_index() assert(test.array_view() == int[]{ 0, 2, 3, 0 }); assert(test.index_of(0)! == 0); assert(test.rindex_of(0)! == 3); - test.delete(0); + test.remove(0); assert(test.len() == 2); assert(test.array_view() == int[]{ 2, 3 }); } @@ -42,4 +42,19 @@ fn void! test_compact() assert(test.compact() == 2); assert(test.len() == 1); assert(test.compact() == 0); +} + +fn void! test_reverse() +{ + IntList test; + test.reverse(); + test.add_array({ 1, 2 }); + test.push(3); + assert(test.array_view() == int[] { 1, 2, 3}); + test.reverse(); + assert(test.array_view() == int[] { 3, 2, 1 }); + test.push(10); + assert(test.array_view() == int[] { 3, 2, 1, 10 }); + test.reverse(); + assert(test.array_view() == int[] { 10, 1, 2, 3 }); } \ No newline at end of file