From 9f55a74d2eacc6aa534a7d82b6ac6a1199dc45f9 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 6 Sep 2025 18:35:03 +0200 Subject: [PATCH] Remove use of find_len and len_from_list. Rename lenof to lengthof --- lib/std/core/array.c3 | 16 ++++++------- lib/std/sort/binarysearch.c3 | 2 +- lib/std/sort/countingsort.c3 | 2 +- lib/std/sort/insertionsort.c3 | 2 +- lib/std/sort/quicksort.c3 | 4 ++-- lib/std/sort/sort.c3 | 8 ------- lib/std/sort/sorted.c3 | 2 +- releasenotes.md | 2 +- src/compiler/compiler_internal.h | 2 +- src/compiler/copying.c | 2 +- src/compiler/enums.h | 6 ++--- src/compiler/parse_expr.c | 8 +++---- src/compiler/parse_stmt.c | 2 +- src/compiler/sema_expr.c | 8 +++---- src/compiler/tokens.c | 4 ++-- test/test_suite/generic/generic_over_fn.c3t | 23 ++++++++----------- test/unit/regression/lenof.c3 | 12 +++++----- test/unit/stdlib/collections/interfacelist.c3 | 2 +- 18 files changed, 46 insertions(+), 61 deletions(-) diff --git a/lib/std/core/array.c3 b/lib/std/core/array.c3 index 3db3f9e99..0177c754d 100644 --- a/lib/std/core/array.c3 +++ b/lib/std/core/array.c3 @@ -216,7 +216,7 @@ macro @product(array, identity_value = 1) *> macro usz[] @indices_of(Allocator allocator, array, #predicate) { - usz[] results = allocator::new_array(allocator, usz, find_len(array)); + usz[] results = allocator::new_array(allocator, usz, lengthof(array)); usz matches; $typefrom(@predicate_fn(array)) $predicate = #predicate; @@ -399,8 +399,8 @@ macro @zip(Allocator allocator, left, right, #operation = ..., fill_with = ...) $Type = $typeof(#operation).returns; $endif - usz left_len = find_len(left); - usz right_len = find_len(right); + usz left_len = lengthof(left); + usz right_len = lengthof(right); $LeftType left_fill; $RightType right_fill; @@ -493,7 +493,7 @@ macro @tzip(left, right, #operation = ..., fill_with = ...) @nodiscard @require @is_valid_list(left) : "Expected a valid list" @require @is_valid_list(right) : "Expected a valid list" - @require find_len(right) >= find_len(left) : `Right side length must be >= the destination (left) side length; consider using a sub-array of data for the assignment.` + @require lengthof(right) >= lengthof(left) : `Right side length must be >= the destination (left) side length; consider using a sub-array of data for the assignment.` @require $defined($typefrom(@zip_into_fn(left, right)) x = #operation) : "The functor must use the same types as the `left` and `right` inputs, and return a value of the `left` type." *> macro @zip_into(left, right, #operation) @@ -537,7 +537,7 @@ macro bool @is_valid_operation(#left, #right, #operation = ...) @const macro bool @is_valid_list(#expr) @const { - return $defined(#expr[0]) &&& ($defined(#expr.len) ||| $defined(#expr.len())); + return $defined(#expr[0], lengthof(#expr)); } macro bool @is_valid_fill(left, right, fill_with = ...) @@ -545,11 +545,9 @@ macro bool @is_valid_fill(left, right, fill_with = ...) $if !$defined(fill_with): return true; $else - usz left_len = $defined(left.len()) ??? left.len() : left.len; - usz right_len = $defined(right.len()) ??? right.len() : right.len; + usz left_len = lengthof(left); + usz right_len = lengthof(right); if (left_len == right_len) return true; return left_len > right_len ? $defined(($typeof(right[0]))fill_with) : $defined(($typeof(left[0]))fill_with); $endif } - -macro usz find_len(list) => $defined(list.len()) ??? list.len() : list.len; diff --git a/lib/std/sort/binarysearch.c3 b/lib/std/sort/binarysearch.c3 index ae37d0bb9..b2e6bb7e2 100644 --- a/lib/std/sort/binarysearch.c3 +++ b/lib/std/sort/binarysearch.c3 @@ -10,7 +10,7 @@ in [0, array.len) where x would be inserted or cmp(i) is true and cmp(j) is true macro usz binarysearch(list, x, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin { usz i; - usz len = len_from_list(list); + usz len = lengthof(list); var $no_cmp = @is_empty_macro_slot(cmp); var $has_context = @is_valid_macro_slot(context); for (usz j = len; i < j;) diff --git a/lib/std/sort/countingsort.c3 b/lib/std/sort/countingsort.c3 index 925b1efd1..4b788469c 100644 --- a/lib/std/sort/countingsort.c3 +++ b/lib/std/sort/countingsort.c3 @@ -10,7 +10,7 @@ Sort list using the counting sort algorithm. *> macro countingsort(list, key_fn = EMPTY_MACRO_SLOT) @builtin { - usz len = sort::len_from_list(list); + usz len = lengthof(list); cs::csort{$typeof(list), $typeof(key_fn)}(list, 0, len, key_fn, ~((uint)0)); } diff --git a/lib/std/sort/insertionsort.c3 b/lib/std/sort/insertionsort.c3 index 08588c15d..069ca2de1 100644 --- a/lib/std/sort/insertionsort.c3 +++ b/lib/std/sort/insertionsort.c3 @@ -12,7 +12,7 @@ macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @b $typeof((*list)[0])[] list2 = list; is::isort{$typeof(list2), $typeof(cmp), $typeof(context)}(list2, 0, list.len, cmp, context); $else - usz len = sort::len_from_list(list); + usz len = lengthof(list); is::isort{$typeof(list), $typeof(cmp), $typeof(context)}(list, 0, (isz)len, cmp, context); $endif } diff --git a/lib/std/sort/quicksort.c3 b/lib/std/sort/quicksort.c3 index 3e326481e..1c683f329 100644 --- a/lib/std/sort/quicksort.c3 +++ b/lib/std/sort/quicksort.c3 @@ -13,7 +13,7 @@ macro quicksort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @built $typeof((*list)[0])[] list2 = list; qs::qsort{$typeof(list2), $typeof(cmp), $typeof(context)}(list2, 0, (isz)list.len - 1, cmp, context); $else - usz len = sort::len_from_list(list); + usz len = lengthof(list); qs::qsort{$typeof(list), $typeof(cmp), $typeof(context)}(list, 0, (isz)len - 1, cmp, context); $endif } @@ -29,7 +29,7 @@ list will be partially sorted. *> macro quickselect(list, isz k, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin { - usz len = sort::len_from_list(list); + usz len = lengthof(list); return qs::qselect{$typeof(list), $typeof(cmp), $typeof(context)}(list, 0, (isz)len - 1, k, cmp, context); } diff --git a/lib/std/sort/sort.c3 b/lib/std/sort/sort.c3 index fd1469815..7ebfa4c5d 100644 --- a/lib/std/sort/sort.c3 +++ b/lib/std/sort/sort.c3 @@ -1,13 +1,5 @@ module std::sort; -macro usz len_from_list(list) -{ - $if $defined(list.len()): - return list.len(); - $else - return list.len; - $endif -} macro bool @is_sortable(#list) { diff --git a/lib/std/sort/sorted.c3 b/lib/std/sort/sorted.c3 index ff45f1f81..fa3cffea1 100644 --- a/lib/std/sort/sorted.c3 +++ b/lib/std/sort/sorted.c3 @@ -9,7 +9,7 @@ Returns true if list is sorted in either ascending or descending order. macro bool is_sorted(list, cmp = EMPTY_MACRO_SLOT, ctx = EMPTY_MACRO_SLOT) @builtin { var $Type = $typeof(list); - usz len = sort::len_from_list(list); + usz len = lengthof(list); if (len <= 1) return true; var check_sort = fn bool($Type list, usz start, usz end, $typeof(cmp) cmp, $typeof(ctx) ctx) { diff --git a/releasenotes.md b/releasenotes.md index 9cd57cfca..f5af6efa4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -3,7 +3,7 @@ ## 0.7.6 Change list ### Changes / improvements -- Add lenof() compile time function #2439 +- Add lengthof() compile time function #2439 - Allow doc comments on individual struct members, faultdefs and enum values #2427. ### Fixes diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 6b49e4fab..8d69ad13f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3713,7 +3713,7 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc) case EXPR_VECTOR_FROM_ARRAY: case EXPR_ADDR_CONVERSION: case EXPR_RECAST: - case EXPR_LENOF: + case EXPR_LENGTHOF: expr_set_span(expr->inner_expr, loc); return; case EXPR_EXPRESSION_LIST: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 108ba3322..f93bb9657 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -503,7 +503,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) case EXPR_RVALUE: case EXPR_RECAST: case EXPR_ADDR_CONVERSION: - case EXPR_LENOF: + case EXPR_LENGTHOF: MACRO_COPY_EXPR(expr->inner_expr); return expr; case EXPR_MAKE_ANY: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 69a9f2460..34317fb01 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -781,7 +781,7 @@ typedef enum EXPR_PTR_TO_INT, EXPR_LAMBDA, EXPR_LAST_FAULT, - EXPR_LENOF, + EXPR_LENGTHOF, EXPR_MACRO_BLOCK, EXPR_MACRO_BODY, EXPR_MACRO_BODY_EXPANSION, @@ -1228,7 +1228,7 @@ typedef enum TOKEN_IF, TOKEN_INLINE, TOKEN_IMPORT, - TOKEN_LENOF, + TOKEN_LENGTHOF, TOKEN_MACRO, TOKEN_MODULE, TOKEN_NEXTCASE, @@ -1721,5 +1721,5 @@ case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 #define UNRESOLVED_EXPRS EXPR_TRY_UNRESOLVED: case EXPR_ACCESS_UNRESOLVED: \ case EXPR_CATCH_UNRESOLVED: case EXPR_UNRESOLVED_IDENTIFIER: case EXPR_CAST: \ case EXPR_TYPEID: case EXPR_EMBED: case EXPR_VASPLAT: case EXPR_OTHER_CONTEXT: \ - case EXPR_IOTA_DECL: case EXPR_LENOF: \ + case EXPR_IOTA_DECL: case EXPR_LENGTHOF: \ case EXPR_GENERIC_IDENT: case EXPR_COMPOUND_LITERAL: case EXPR_MACRO_BODY: case EXPR_CT_SUBSCRIPT diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 063f866df..2e2ee933c 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1238,13 +1238,13 @@ static Expr *parse_ct_embed(ParseContext *c, Expr *left, SourceSpan lhs_start UN } /** - * lenof ::= LENOF '(' expr ')' + * lengthof ::= LENGTHOF '(' expr ')' * flat_path ::= expr ('.' primary) | '[' expr ']')* */ -static Expr *parse_lenof(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED) +static Expr *parse_lengthof(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED) { ASSERT(!left && "Unexpected left hand side"); - Expr *expr = EXPR_NEW_TOKEN(EXPR_LENOF); + Expr *expr = EXPR_NEW_TOKEN(EXPR_LENGTHOF); advance(c); CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); ASSIGN_EXPR_OR_RET(expr->inner_expr, parse_expr(c), poisoned_expr); @@ -2171,7 +2171,7 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_TRUE] = { parse_bool, NULL, PREC_NONE }, [TOKEN_FALSE] = { parse_bool, NULL, PREC_NONE }, [TOKEN_NULL] = { parse_null, NULL, PREC_NONE }, - [TOKEN_LENOF] = { parse_lenof, NULL, PREC_NONE }, + [TOKEN_LENGTHOF] = { parse_lengthof, NULL, PREC_NONE }, [TOKEN_INTEGER] = { parse_integer, NULL, PREC_NONE }, [TOKEN_BUILTIN] = { parse_builtin, NULL, PREC_NONE }, [TOKEN_CHAR_LITERAL] = { parse_char_lit, NULL, PREC_NONE }, diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index c51d5caa8..22cab9afe 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -1409,7 +1409,7 @@ Ast *parse_stmt(ParseContext *c) case TOKEN_CT_VAEXPR: case TOKEN_FALSE: case TOKEN_INTEGER: - case TOKEN_LENOF: + case TOKEN_LENGTHOF: case TOKEN_LPAREN: case TOKEN_MINUS: case TOKEN_MINUSMINUS: diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a8dd32bf9..ab0073481 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -10429,7 +10429,7 @@ static bool sema_expr_analyse_lenof(SemaContext *context, Expr *expr, bool *miss *missing_ref = true; return false; } - RETURN_SEMA_ERROR(inner, "%s does support lenof()", type_quoted_error_string(inner->type)); + RETURN_SEMA_ERROR(inner, "%s does support lengthof()", type_quoted_error_string(inner->type)); } } @@ -10460,7 +10460,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr active_context->call_env.in_no_eval = true; main_expr = main_expr->expr_other_context.inner; goto RETRY; - case EXPR_LENOF: + case EXPR_LENGTHOF: if (!sema_expr_analyse_lenof(active_context, main_expr, &failed)) { if (!failed) goto FAIL; @@ -11088,7 +11088,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr, case EXPR_MAKE_SLICE: case EXPR_CT_SUBSCRIPT: UNREACHABLE - case EXPR_LENOF: + case EXPR_LENGTHOF: return sema_expr_analyse_lenof(context, expr, NULL); case EXPR_IOTA_DECL: return sema_expr_analyse_iota_decl(context, expr); @@ -11638,7 +11638,7 @@ IDENT_CHECK:; case EXPR_INT_TO_FLOAT: case EXPR_INT_TO_PTR: case EXPR_PTR_TO_INT: - case EXPR_LENOF: + case EXPR_LENGTHOF: case EXPR_RETHROW: case EXPR_RETVAL: case EXPR_RVALUE: diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index c28031274..7dd2070c9 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -235,8 +235,8 @@ const char *token_type_to_string(TokenType type) return "interface"; case TOKEN_IMPORT: return "import"; - case TOKEN_LENOF: - return "lenof"; + case TOKEN_LENGTHOF: + return "lengthof"; case TOKEN_MACRO: return "macro"; case TOKEN_MODULE: diff --git a/test/test_suite/generic/generic_over_fn.c3t b/test/test_suite/generic/generic_over_fn.c3t index 1ba0958dc..3f62e985f 100644 --- a/test/test_suite/generic/generic_over_fn.c3t +++ b/test/test_suite/generic/generic_over_fn.c3t @@ -12,7 +12,7 @@ macro quicksort(list, cmp = null) { var $Type = $typeof(list); var $CmpType = $typeof(cmp); - usz len = sort::len_from_list(list); + usz len = lengthof(list); test_generic::sort{$Type, $CmpType}(list, 0, (isz)len - 1, cmp); } @@ -70,7 +70,6 @@ entry: %tc = alloca %"int[]", align 8 %list = alloca %"int[]", align 8 %len = alloca i64, align 8 - %list9 = alloca %"int[]", align 8 store %"int[]" zeroinitializer, ptr %literal, align 8 %ptradd = getelementptr inbounds i8, ptr %literal, i64 16 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal1, ptr align 4 @.__const, i32 8, i1 false) @@ -111,15 +110,14 @@ loop.body: ; preds = %loop.cond %ptroffset = getelementptr inbounds [16 x i8], ptr %12, i64 %13 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tc, ptr align 8 %ptroffset, i32 16, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %list, ptr align 8 %tc, i32 16, i1 false) - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %list9, ptr align 8 %list, i32 16, i1 false) - %ptradd10 = getelementptr inbounds i8, ptr %list9, i64 8 - %14 = load i64, ptr %ptradd10, align 8 + %ptradd9 = getelementptr inbounds i8, ptr %list, i64 8 + %14 = load i64, ptr %ptradd9, align 8 store i64 %14, ptr %len, align 8 %15 = load i64, ptr %len, align 8 %sub = sub i64 %15, 1 %lo = load ptr, ptr %list, align 8 - %ptradd11 = getelementptr inbounds i8, ptr %list, i64 8 - %hi = load i64, ptr %ptradd11, align 8 + %ptradd10 = getelementptr inbounds i8, ptr %list, i64 8 + %hi = load i64, ptr %ptradd10, align 8 call void @"test_generic$sa$int$fn$int$int$$int$$.sort"(ptr %lo, i64 %hi, i64 0, i64 %sub, ptr @sort_test.cmp_int_value) %16 = load i64, ptr %.anon, align 8 %addnuw = add nuw i64 %16, 1 @@ -130,7 +128,6 @@ loop.exit: ; preds = %loop.cond ret void } -; Function Attrs: define void @sort_test.quicksort_with_value2() #0 { entry: %tcases = alloca %"int[][]", align 8 @@ -143,7 +140,6 @@ entry: %tc = alloca %"int[]", align 8 %list = alloca %"int[]", align 8 %len = alloca i64, align 8 - %list9 = alloca %"int[]", align 8 store %"int[]" zeroinitializer, ptr %literal, align 8 %ptradd = getelementptr inbounds i8, ptr %literal, i64 16 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal1, ptr align 4 @.__const.4, i32 8, i1 false) @@ -184,15 +180,14 @@ loop.body: ; preds = %loop.cond %ptroffset = getelementptr inbounds [16 x i8], ptr %12, i64 %13 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tc, ptr align 8 %ptroffset, i32 16, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %list, ptr align 8 %tc, i32 16, i1 false) - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %list9, ptr align 8 %list, i32 16, i1 false) - %ptradd10 = getelementptr inbounds i8, ptr %list9, i64 8 - %14 = load i64, ptr %ptradd10, align 8 + %ptradd9 = getelementptr inbounds i8, ptr %list, i64 8 + %14 = load i64, ptr %ptradd9, align 8 store i64 %14, ptr %len, align 8 %15 = load i64, ptr %len, align 8 %sub = sub i64 %15, 1 %lo = load ptr, ptr %list, align 8 - %ptradd11 = getelementptr inbounds i8, ptr %list, i64 8 - %hi = load i64, ptr %ptradd11, align 8 + %ptradd10 = getelementptr inbounds i8, ptr %list, i64 8 + %hi = load i64, ptr %ptradd10, align 8 call void @"test_generic$sa$int$fn$int$int$$int$$.sort"(ptr %lo, i64 %hi, i64 0, i64 %sub, ptr @sort_test.cmp_int_value2) %16 = load i64, ptr %.anon, align 8 %addnuw = add nuw i64 %16, 1 diff --git a/test/unit/regression/lenof.c3 b/test/unit/regression/lenof.c3 index af1c16153..0cae821c6 100644 --- a/test/unit/regression/lenof.c3 +++ b/test/unit/regression/lenof.c3 @@ -8,13 +8,13 @@ fn void lenof_test() @test l.push(123); l.push(222); l.push(111); - test::eq(lenof(l), 3); + test::eq(lengthof(l), 3); int[] x = { 1, 2 }; - test::eq(lenof(x), 2); + test::eq(lengthof(x), 2); l.push(111); - test::eq(lenof(l), 4); - assert(!$defined(lenof(1))); - assert($defined(lenof(x))); + test::eq(lengthof(l), 4); + assert(!$defined(lengthof(1))); + assert($defined(lengthof(x))); int* zz; - assert(!$defined(lenof(zz))); + assert(!$defined(lengthof(zz))); } \ No newline at end of file diff --git a/test/unit/stdlib/collections/interfacelist.c3 b/test/unit/stdlib/collections/interfacelist.c3 index d00ba6032..41170890c 100644 --- a/test/unit/stdlib/collections/interfacelist.c3 +++ b/test/unit/stdlib/collections/interfacelist.c3 @@ -120,7 +120,7 @@ fn int[] to_ints(TestL l) => @map(tmem, l.array_view(), fn int(Test x) => x.test import std::core::array @public; macro @map(Allocator alloc, array, operation) { - var res = allocator::alloc_array(alloc, $typeof(operation).returns, array::find_len(array)); + var res = allocator::alloc_array(alloc, $typeof(operation).returns, lengthof(array)); foreach (i, val : array) res[i] = operation(val); return res; }