Repository: goplus/gop
Pull request #2112 (2025-02-21 23:35:14)

#2107 parser: send statement in parseSimpleStmtEx


Patch:
diff --git a/README.md b/README.md
index 0ebc4653..09712e05 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,6 @@ Code style is just the first step. We have made many efforts to make the code mo
 | fmt.Println("Hi") | echo("Hi") | More builtin functions: It simplifies the expression of the most common tasks |
 | fmt.Println("Hi") | echo "Hi" | Command-line style code: It reduces the number of parentheses in the code as much as possible, making it closer to natural language |
 | a := []int{1, 2, 3} | a := [1, 2, 3] | List literals |
-| a = append(a, 4) | a <- 4 | Append values to a list |
 | a := map[string]int{<br>&nbsp;&nbsp;&nbsp;&nbsp;"Monday": 1,<br>&nbsp;&nbsp;&nbsp;&nbsp;"Tuesday": 2,<br>} | a := {<br>&nbsp;&nbsp;&nbsp;&nbsp;"Monday": 1,<br>&nbsp;&nbsp;&nbsp;&nbsp;"Tuesday": 2,<br>} | Mapping literals |
 | OnStart(func() {<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>}) | onStart => {<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>} | Lambda expressions |
 | type Rect struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp; float64<br>&nbsp;&nbsp;&nbsp;&nbsp;Height float64<br>}<br><br>func (this *Rect) Area() float64 { <br>&nbsp;&nbsp;&nbsp;&nbsp;return this.Width * this.Height<br>} | var (<br>&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp; float64<br>&nbsp;&nbsp;&nbsp;&nbsp;Height float64<br>)<br><br>func Area() float64 { <br>&nbsp;&nbsp;&nbsp;&nbsp;return Width * Height<br>} | [Go+ Classfiles](doc/classfile.md): We can express OOP with global variables and functions. |
diff --git a/parser/parser.go b/parser/parser.go
index 2178c0c4..dd7110dc 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -2762,9 +2762,19 @@ func (p *parser) parseSimpleStmtEx(mode int, allowCmd, allowRangeExpr bool) (ast
 		// send statement
 		arrow := p.pos
 		p.next()
-		y := p.parseRHS()
-		// TODO(xsw): https://github.com/goplus/gop/issues/2107
-		return &ast.SendStmt{Chan: x[0], Arrow: arrow, Values: []ast.Expr{y}}, false
+		var ellipsis token.Pos
+		vals := make([]ast.Expr, 1)
+		vals[0] = p.parseRHS()
+		if p.tok == token.ELLIPSIS { // a <- v... (issues #2107)
+			ellipsis = p.pos
+			p.next()
+		} else {
+			for p.tok == token.COMMA { // a <- v1, v2, v3 (issues #2107)
+				p.next()
+				vals = append(vals, p.parseRHS())
+			}
+		}
+		return &ast.SendStmt{Chan: x[0], Arrow: arrow, Values: vals, Ellipsis: ellipsis}, false
 
 	case token.INC, token.DEC:
 		// increment or decrement


Test patch:
diff --git a/parser/_testdata/append1/append.gop b/parser/_testdata/append1/append.gop
new file mode 100644
index 00000000..dc89bb7d
--- /dev/null
+++ b/parser/_testdata/append1/append.gop
@@ -0,0 +1,1 @@
+a <- 1, 2, 3
diff --git a/parser/_testdata/append1/parser.expect b/parser/_testdata/append1/parser.expect
new file mode 100644
index 00000000..2cc8e03c
--- /dev/null
+++ b/parser/_testdata/append1/parser.expect
@@ -0,0 +1,29 @@
+package main
+
+file append.gop
+noEntrypoint
+ast.FuncDecl:
+  Name:
+    ast.Ident:
+      Name: main
+  Type:
+    ast.FuncType:
+      Params:
+        ast.FieldList:
+  Body:
+    ast.BlockStmt:
+      List:
+        ast.SendStmt:
+          Chan:
+            ast.Ident:
+              Name: a
+          Values:
+            ast.BasicLit:
+              Kind: INT
+              Value: 1
+            ast.BasicLit:
+              Kind: INT
+              Value: 2
+            ast.BasicLit:
+              Kind: INT
+              Value: 3
diff --git a/parser/_testdata/append2/append.gop b/parser/_testdata/append2/append.gop
new file mode 100644
index 00000000..492ca1b6
--- /dev/null
+++ b/parser/_testdata/append2/append.gop
@@ -0,0 +1,1 @@
+a <- b...
diff --git a/parser/_testdata/append2/parser.expect b/parser/_testdata/append2/parser.expect
new file mode 100644
index 00000000..9f7f4b5d
--- /dev/null
+++ b/parser/_testdata/append2/parser.expect
@@ -0,0 +1,22 @@
+package main
+
+file append.gop
+noEntrypoint
+ast.FuncDecl:
+  Name:
+    ast.Ident:
+      Name: main
+  Type:
+    ast.FuncType:
+      Params:
+        ast.FieldList:
+  Body:
+    ast.BlockStmt:
+      List:
+        ast.SendStmt:
+          Chan:
+            ast.Ident:
+              Name: a
+          Values:
+            ast.Ident:
+              Name: b