Repository: goplus/gop
Pull request #1846 (2024-04-07 10:34:44)

parser: _testdata/matrix2 (support row...)


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index f3e4bc2b..234cf129 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -21,10 +21,7 @@ jobs:
   Test:
     strategy:
       matrix:
-        os:
-        - ubuntu-latest
-        - windows-latest
-        - macos-latest
+        os: [ubuntu-latest, windows-latest, macos-11]
         go:
         - 1.18.x
         - 1.19.x
diff --git a/ast/ast_gop.go b/ast/ast_gop.go
index 8ccb2a1c..da6227a5 100644
--- a/ast/ast_gop.go
+++ b/ast/ast_gop.go
@@ -159,6 +159,26 @@ func (*MatrixLit) exprNode() {}
 
 // -----------------------------------------------------------------------------
 
+// A ElemEllipsis node represents a matrix row elements.
+type ElemEllipsis struct {
+	Elt      Expr      // ellipsis element
+	Ellipsis token.Pos // position of "..."
+}
+
+// Pos - position of first character belonging to the node.
+func (p *ElemEllipsis) Pos() token.Pos {
+	return p.Elt.Pos()
+}
+
+// End - position of first character immediately after the node.
+func (p *ElemEllipsis) End() token.Pos {
+	return p.Ellipsis + 3
+}
+
+func (*ElemEllipsis) exprNode() {}
+
+// -----------------------------------------------------------------------------
+
 // ErrWrapExpr represents `expr!`, `expr?` or `expr?: defaultValue`.
 type ErrWrapExpr struct {
 	X       Expr
diff --git a/parser/parser.go b/parser/parser.go
index 0df026d1..f2d2fc42 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -899,6 +899,11 @@ func (p *parser) parseSliceOrMatrixLit(lbrack token.Pos, first ast.Expr) ast.Exp
 		case token.SEMICOLON:
 			mat = append(mat, elts)
 			elts = make([]ast.Expr, 0, len(elts))
+		case token.ELLIPSIS:
+			n := len(elts)
+			elts[n-1] = &ast.ElemEllipsis{Ellipsis: p.pos, Elt: elts[n-1]}
+			p.next()
+			continue
 		default:
 			goto done
 		}
@@ -2195,6 +2200,7 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr {
 		p.error(v.opening, msgTupleNotSupported)
 		x = &ast.BadExpr{From: v.opening, To: v.closing}
 	case *ast.EnvExpr:
+	case *ast.ElemEllipsis:
 	default:
 		// all other nodes are not proper expressions
 		p.errorExpected(x.Pos(), "expression", 3)
diff --git a/printer/nodes.go b/printer/nodes.go
index e043c482..5b831449 100644
--- a/printer/nodes.go
+++ b/printer/nodes.go
@@ -1127,6 +1127,10 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
 			p.print(x.Name)
 		}
 
+	case *ast.ElemEllipsis:
+		p.expr(x.Elt)
+		p.print(token.ELLIPSIS)
+
 	default:
 		log.Fatalf("unreachable %T\n", x)
 	}


Test patch:
diff --git a/parser/_testdata/matrix2/matrix.gop b/parser/_testdata/matrix2/matrix.gop
new file mode 100644
index 00000000..1682ebec
--- /dev/null
+++ b/parser/_testdata/matrix2/matrix.gop
@@ -0,0 +1,5 @@
+echo [
+	1, 2, 3
+	row...
+	7, 8, 9
+]
diff --git a/parser/_testdata/matrix2/parser.expect b/parser/_testdata/matrix2/parser.expect
new file mode 100644
index 00000000..9e62b45b
--- /dev/null
+++ b/parser/_testdata/matrix2/parser.expect
@@ -0,0 +1,47 @@
+package main
+
+file matrix.gop
+noEntrypoint
+ast.FuncDecl:
+  Name:
+    ast.Ident:
+      Name: main
+  Type:
+    ast.FuncType:
+      Params:
+        ast.FieldList:
+  Body:
+    ast.BlockStmt:
+      List:
+        ast.ExprStmt:
+          X:
+            ast.CallExpr:
+              Fun:
+                ast.Ident:
+                  Name: echo
+              Args:
+                ast.MatrixLit:
+                  Elts:
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 1
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 2
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 3
+                    ast.ElemEllipsis:
+                      Elt:
+                        ast.Ident:
+                          Name: row
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 7
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 8
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 9
+                  NElt: 3
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 46921b00..c7cc3450 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -20,6 +20,7 @@ import (
 	"io/fs"
 	"testing"
 
+	"github.com/goplus/gop/ast"
 	"github.com/goplus/gop/token"
 	fsx "github.com/qiniu/x/http/fs"
 )
@@ -313,4 +314,15 @@ func TestParseFieldDecl(t *testing.T) {
 	p.parseFieldDecl(nil)
 }
 
+func TestCheckExpr(t *testing.T) {
+	var p parser
+	p.init(token.NewFileSet(), "/foo/bar.gop", []byte(``), 0)
+	p.checkExpr(&ast.Ellipsis{})
+	p.checkExpr(&ast.ElemEllipsis{})
+	p.checkExpr(&ast.StarExpr{})
+	p.checkExpr(&ast.IndexListExpr{})
+	p.checkExpr(&ast.FuncType{})
+	p.checkExpr(&ast.FuncLit{})
+}
+
 // -----------------------------------------------------------------------------