From 4b9afd787ca88c1c9b4cf38cb4290de76da8ae94 Mon Sep 17 00:00:00 2001 From: Walther Chen Date: Wed, 2 Aug 2023 11:52:11 -0400 Subject: [PATCH] core:odin/parser allow args after varargs in parse_call_expr --- core/odin/parser/parser.odin | 10 ++++++++-- examples/demo/demo.odin | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 15a33d86b..4c223bebb 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2941,9 +2941,9 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr { p.expr_level += 1 open := expect_token(p, .Open_Paren) + seen_ellipsis := false for p.curr_tok.kind != .Close_Paren && - p.curr_tok.kind != .EOF && - ellipsis.pos.line == 0 { + p.curr_tok.kind != .EOF { if p.curr_tok.kind == .Comma { error(p, p.curr_tok.pos, "expected an expression not ,") @@ -2972,10 +2972,16 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr { fv.value = value arg = fv + } else if seen_ellipsis { + error(p, arg.pos, "Positional arguments are not allowed after '..'") } append(&args, arg) + if ellipsis.pos.line != 0 { + seen_ellipsis = true + } + if !allow_token(p, .Comma) { break } diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 5f1e84bbf..2c890ad71 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -459,6 +459,27 @@ named_proc_return_parameters :: proc() { fmt.println("foo2 =", foo2()) // 567 321 } +variadic_procedures :: proc() { + fmt.println("\n# variadic procedures") + sum :: proc(nums: ..int, init_value:= 0) -> (result: int) { + result = init_value + for n in nums { + result += n + } + return + } + fmt.println("sum(()) =", sum()) + fmt.println("sum(1, 2) =", sum(1, 2)) + fmt.println("sum(1, 2, 3, 4, 5) =", sum(1, 2, 3, 4, 5)) + fmt.println("sum(1, 2, 3, 4, 5, init_value = 5) =", sum(1, 2, 3, 4, 5, init_value = 5)) + + // pass a slice as varargs + odds := []int{1, 3, 5} + fmt.println("odds =", odds) + fmt.println("sum(..odds) =", sum(..odds)) + fmt.println("sum(..odds, init_value = 5) =", sum(..odds, init_value = 5)) +} + explicit_procedure_overloading :: proc() { fmt.println("\n# explicit procedure overloading") @@ -2463,6 +2484,7 @@ main :: proc() { the_basics() control_flow() named_proc_return_parameters() + variadic_procedures() explicit_procedure_overloading() struct_type() union_type()