Repository: goplus/gop
Pull request #2113 (2025-02-22 00:54:22)

#2107 cl: extend compileSendStmt


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/cl/stmt.go b/cl/stmt.go
index b2cc9817..48d92bb0 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -274,7 +274,11 @@ func compileSendStmt(ctx *blockCtx, expr *ast.SendStmt) {
 			for _, v := range vals {
 				compileExpr(ctx, v)
 			}
-			cb.CallWith(len(vals)+1, 0, expr).AssignWith(1, 1, expr)
+			flags := gogen.InstrFlags(0)
+			if expr.Ellipsis != 0 { // a = append(a, b...)
+				flags |= gogen.InstrFlagEllipsis
+			}
+			cb.CallWith(len(vals)+1, flags, expr).AssignWith(1, 1, expr)
 			return
 		}
 		goto normal
@@ -282,7 +286,10 @@ func compileSendStmt(ctx *blockCtx, expr *ast.SendStmt) {
 	compileExpr(ctx, ch)
 
 normal:
-	compileExpr(ctx, vals[0]) // TODO(xsw): issue #2107
+	if len(vals) != 1 || expr.Ellipsis != 0 {
+		panic(ctx.newCodeError(vals[0].End(), "can't send multiple values to a channel"))
+	}
+	compileExpr(ctx, vals[0])
 	ctx.cb.Send()
 }
 


Test patch:
diff --git a/cl/_testgop/append/in.gop b/cl/_testgop/append1/in.gop
similarity index 100%
rename from cl/_testgop/append/in.gop
rename to cl/_testgop/append1/in.gop
diff --git a/cl/_testgop/append/out.go b/cl/_testgop/append1/out.go
similarity index 100%
rename from cl/_testgop/append/out.go
rename to cl/_testgop/append1/out.go
diff --git a/cl/_testgop/append2/in.gop b/cl/_testgop/append2/in.gop
new file mode 100644
index 00000000..39d9a2b9
--- /dev/null
+++ b/cl/_testgop/append2/in.gop
@@ -0,0 +1,7 @@
+a := [1, 2, 3]
+a <- 4, 5
+echo a
+
+b := [7, 8]
+a <- b...
+echo a
diff --git a/cl/_testgop/append2/out.go b/cl/_testgop/append2/out.go
new file mode 100644
index 00000000..238884c8
--- /dev/null
+++ b/cl/_testgop/append2/out.go
@@ -0,0 +1,12 @@
+package main
+
+import "fmt"
+
+func main() {
+	a := []int{1, 2, 3}
+	a = append(a, 4, 5)
+	fmt.Println(a)
+	b := []int{7, 8}
+	a = append(a, b...)
+	fmt.Println(a)
+}
diff --git a/cl/error_msg_test.go b/cl/error_msg_test.go
index 6341a700..a9553ee3 100644
--- a/cl/error_msg_test.go
+++ b/cl/error_msg_test.go
@@ -37,6 +37,13 @@ func codeErrorTestAst(t *testing.T, pkgname, filename, msg, src string) {
 	cltest.ErrorAst(t, pkgname, filename, msg, src)
 }
 
+func TestErrSendStmt(t *testing.T) {
+	codeErrorTest(t, `bar.gop:3:8: can't send multiple values to a channel`, `
+	var a chan int
+	a <- 1, 2
+`)
+}
+
 func TestErrVargCommand(t *testing.T) {
 	codeErrorTest(t, `bar.gop:5:1: not enough arguments in call to Ls
 	have ()