grouped comptime param update

This commit is contained in:
2026-07-18 16:48:41 +02:00
parent 9eb7476522
commit f9448363e4
5 changed files with 75 additions and 16 deletions
+3
View File
@@ -1953,6 +1953,9 @@ parse_params :: proc(parser: ^Parser) -> ([]ast.Param, bool) {
break break
} }
skip_newlines(parser) skip_newlines(parser)
if comptime_value {
_, _ = allow(parser, .Dollar)
}
} }
type_syntax := parse_type(parser) type_syntax := parse_type(parser)
for name in names { for name in names {
+30 -5
View File
@@ -230,6 +230,31 @@ main func() void {}
testing.expect(t, !module.functions[0].params[1].comptime_value) testing.expect(t, !module.functions[0].params[1].comptime_value)
} }
@(test)
parser_accepts_grouped_comptime_params :: proc(t: ^testing.T) {
text := `grouped func($K, $V type, $A, B usize) void {}
main func() void {}
`
source_file := source.Source{path="test.bro", text=text}
diagnostics := source.init_diagnostics(&source_file)
defer source.destroy_diagnostics(&diagnostics)
symbols := symbol.init_table()
defer symbol.destroy_table(&symbols)
stream := lexer.lex(&source_file, &diagnostics, &symbols)
defer delete(stream.items)
module := parser.parse(&stream, &source_file, &diagnostics)
defer ast.destroy_module(&module)
params := module.functions[0].params
testing.expect_value(t, len(diagnostics.items), 0)
testing.expect_value(t, len(params), 4)
for param in params {
testing.expect(t, param.comptime_value)
}
testing.expect_value(t, params[0].type, params[1].type)
testing.expect_value(t, params[2].type, params[3].type)
}
@(test) @(test)
parser_accepts_comptime_type_params_and_builtin_type_args :: proc(t: ^testing.T) { parser_accepts_comptime_type_params_and_builtin_type_args :: proc(t: ^testing.T) {
text := `id func($T type, value T) T { text := `id func($T type, value T) T {
@@ -13130,12 +13155,12 @@ dependency_passes test {
defer delete(stderr) defer delete(stderr)
output := string(stderr) output := string(stderr)
testing.expect_value(t, state.exit_code, 1) testing.expect_value(t, state.exit_code, 1)
testing.expect(t, strings.contains(output, "PASS root.root_passes")) testing.expect(t, strings.contains(output, "root.root_passes [ok]"))
testing.expect(t, strings.contains(output, "FAIL root.root_fails")) testing.expect(t, strings.contains(output, "root.root_fails [failed]"))
testing.expect(t, strings.contains(output, "expected 42, found 41")) testing.expect(t, strings.contains(output, "expected 42, found 41"))
testing.expect(t, strings.contains(output, "PASS root.root_continues")) testing.expect(t, strings.contains(output, "root.root_continues [ok]"))
testing.expect(t, strings.contains(output, "FAIL root.root_errors")) testing.expect(t, strings.contains(output, "root.root_errors [failed]"))
testing.expect(t, strings.contains(output, "PASS dependency.dependency_passes")) testing.expect(t, strings.contains(output, "dependency.dependency_passes [ok]"))
testing.expect(t, strings.contains(output, root_path)) testing.expect(t, strings.contains(output, root_path))
testing.expect(t, strings.contains(output, "3 passed, 2 failed")) testing.expect(t, strings.contains(output, "3 passed, 2 failed"))
} }
+5 -5
View File
@@ -23,8 +23,8 @@ deinit func($T type, list @mut ArrayList(T)) void {
list.capacity = 0 list.capacity = 0
} }
reserve func($T type, list @mut ArrayList(T), minimum_capacity usize) void ! mem.AllocError { reserve func($T type, list @mut ArrayList(T), min_capacity usize) void ! mem.AllocError {
if minimum_capacity <= list.capacity { if min_capacity <= list.capacity {
return return
} }
@@ -32,13 +32,13 @@ reserve func($T type, list @mut ArrayList(T), minimum_capacity usize) void ! mem
if list.capacity >= 8 { if list.capacity >= 8 {
half usize :: divtrunc!(list.capacity, 2) half usize :: divtrunc!(list.capacity, 2)
if list.capacity > maxval!(usize) - half { if list.capacity > maxval!(usize) - half {
new_capacity = minimum_capacity new_capacity = min_capacity
} else { } else {
new_capacity = list.capacity + half new_capacity = list.capacity + half
} }
} }
if new_capacity < minimum_capacity { if new_capacity < min_capacity {
new_capacity = minimum_capacity new_capacity = min_capacity
} }
length usize :: list.items.len length usize :: list.items.len
+32
View File
@@ -0,0 +1,32 @@
import "@std/mem"
import "@std/testing"
handles_append test {
list ArrayList(i32) = init(mem.c_allocator)
defer deinit(&list)
try append(&list, 42)
try testing.expect_equal(1, list.items.len)
try testing.expect_equal(42, list.items[0])
}
handles_clear test {
list ArrayList(i32) = init(mem.c_allocator)
defer deinit(&list)
try append(&list, 42)
clear(&list)
try testing.expect_equal(0, list.items.len)
}
handles_reserve test {
list ArrayList(i32) = init(mem.c_allocator)
defer deinit(&list)
try reserve(&list, 10)
try testing.expect_equal(10, list.capacity)
try testing.expect_equal(0, list.items.len)
}
+5 -6
View File
@@ -1,4 +1,4 @@
debug :: import "@std/debug" import "@std/debug"
Error :: enum { Error :: enum {
expectation_failed expectation_failed
@@ -11,26 +11,25 @@ SourceLocation :: struct {
} }
expect func(condition bool, location SourceLocation) void ! Error { expect func(condition bool, location SourceLocation) void ! Error {
if (!condition) { if !condition {
debug.print("{s}:{d}:{d}: expectation failed\n", {location.file, location.line, location.column}) debug.print("{s}:{d}:{d}: expectation failed\n", {location.file, location.line, location.column})
return .expectation_failed return .expectation_failed
} }
} }
expect_equal func($T type, expected, actual T, location SourceLocation) void ! Error { expect_equal func($T type, expected, actual T, location SourceLocation) void ! Error {
if (expected != actual) { if expected != actual {
debug.print("{s}:{d}:{d}: expected {}, found {}\n", {location.file, location.line, location.column, expected, actual}) debug.print("{s}:{d}:{d}: expected {}, found {}\n", {location.file, location.line, location.column, expected, actual})
return .expectation_failed return .expectation_failed
} }
} }
run func(name []u8, callback *func() void ! Error) bool { run func(name []u8, callback *func() void ! Error) bool {
debug.print("RUN {s}\n", {name,})
callback() catch |_| { callback() catch |_| {
debug.print("FAIL {s}\n", {name,}) debug.print("{s} [failed]\n", {name,})
return false return false
} }
debug.print("PASS {s}\n", {name,}) debug.print("{s} [ok]\n", {name,})
return true return true
} }