Browse Source

core:odin/parser allow args after varargs in parse_call_expr

Walther Chen 2 years ago
parent
commit
4b9afd787c
2 changed files with 30 additions and 2 deletions
  1. 8 2
      core/odin/parser/parser.odin
  2. 22 0
      examples/demo/demo.odin

+ 8 - 2
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
 		}

+ 22 - 0
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()