Repository: goplus/gop
Pull request #1285 (2022-06-18 05:09:14)

parseErrWrapExpr: ErrWrapExpr as PrimaryExpr


Patch:
diff --git a/parser/parser.go b/parser/parser.go
index 07e800f3..264a601d 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -1354,7 +1354,7 @@ func (p *parser) parseFuncTypeOrLit() ast.Expr {
 
 func (p *parser) isCommand(x ast.Expr) bool {
 	switch x.(type) {
-	case *ast.Ident, *ast.SelectorExpr:
+	case *ast.Ident, *ast.SelectorExpr, *ast.ErrWrapExpr:
 	default:
 		return false
 	}
@@ -1908,6 +1908,9 @@ L:
 			} else {
 				break L
 			}
+		case token.NOT, token.QUESTION:
+			x = &ast.ErrWrapExpr{X: x, Tok: p.tok, TokPos: p.pos}
+			p.next()
 		default:
 			if allowCmd && p.isCommand(x) {
 				if lhs {
@@ -1923,6 +1926,18 @@ L:
 	return x
 }
 
+// parseErrWrapExpr: expr! expr? expr?:defval
+func (p *parser) parseErrWrapExpr(lhs, allowTuple, allowCmd bool) ast.Expr {
+	x := p.parsePrimaryExpr(lhs, allowTuple, allowCmd)
+	if expr, ok := x.(*ast.ErrWrapExpr); ok {
+		if p.tok == token.COLON {
+			p.next()
+			expr.Default = p.parseUnaryExpr(false, true, false)
+		}
+	}
+	return x
+}
+
 // If lhs is set and the result is an identifier, it is not resolved.
 func (p *parser) parseUnaryExpr(lhs, allowTuple, allowCmd bool) ast.Expr {
 	if p.trace {
@@ -1993,27 +2008,6 @@ func (p *parser) parseUnaryExpr(lhs, allowTuple, allowCmd bool) ast.Expr {
 	return p.parseErrWrapExpr(lhs, allowTuple, allowCmd)
 }
 
-// parseErrWrapExpr: expr! expr? expr?:defval
-func (p *parser) parseErrWrapExpr(lhs, allowTuple, allowCmd bool) ast.Expr {
-	x := p.parsePrimaryExpr(lhs, allowTuple, allowCmd)
-	switch p.tok {
-	case token.NOT: // expr!
-		expr := &ast.ErrWrapExpr{X: x, Tok: token.NOT, TokPos: p.pos}
-		p.next()
-		return expr
-	case token.QUESTION: // expr? expr?:defval
-		expr := &ast.ErrWrapExpr{X: x, Tok: token.QUESTION, TokPos: p.pos}
-		p.next()
-		if p.tok == token.COLON {
-			p.next()
-			expr.Default = p.parseUnaryExpr(false, true, false)
-		}
-		return expr
-	default:
-		return x
-	}
-}
-
 func (p *parser) tokPrec() (token.Token, int) {
 	tok := p.tok
 	if p.inRHS && tok == token.ASSIGN {


Test patch:
diff --git a/parser/_testdata/errwrap3/errwrap3.gop b/parser/_testdata/errwrap3/errwrap3.gop
new file mode 100644
index 00000000..024a5476
--- /dev/null
+++ b/parser/_testdata/errwrap3/errwrap3.gop
@@ -0,0 +1,2 @@
+mkdir! "foo"
+println foo()!.fields
diff --git a/parser/_testdata/errwrap3/parser.expect b/parser/_testdata/errwrap3/parser.expect
new file mode 100644
index 00000000..eaab0127
--- /dev/null
+++ b/parser/_testdata/errwrap3/parser.expect
@@ -0,0 +1,47 @@
+package main
+
+file errwrap3.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.ErrWrapExpr:
+                  X:
+                    ast.Ident:
+                      Name: mkdir
+                  Tok: !
+              Args:
+                ast.BasicLit:
+                  Kind: STRING
+                  Value: "foo"
+        ast.ExprStmt:
+          X:
+            ast.CallExpr:
+              Fun:
+                ast.Ident:
+                  Name: println
+              Args:
+                ast.SelectorExpr:
+                  X:
+                    ast.ErrWrapExpr:
+                      X:
+                        ast.CallExpr:
+                          Fun:
+                            ast.Ident:
+                              Name: foo
+                      Tok: !
+                  Sel:
+                    ast.Ident:
+                      Name: fields
diff --git a/parser/_testdata/fncall/fncall.gop b/parser/_testdata/fncall/fncall.gop
new file mode 100644
index 00000000..103721cc
--- /dev/null
+++ b/parser/_testdata/fncall/fncall.gop
@@ -0,0 +1,1 @@
+fn(1)(x)
diff --git a/parser/_testdata/fncall/parser.expect b/parser/_testdata/fncall/parser.expect
new file mode 100644
index 00000000..a740e409
--- /dev/null
+++ b/parser/_testdata/fncall/parser.expect
@@ -0,0 +1,30 @@
+package main
+
+file fncall.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.CallExpr:
+                  Fun:
+                    ast.Ident:
+                      Name: fn
+                  Args:
+                    ast.BasicLit:
+                      Kind: INT
+                      Value: 1
+              Args:
+                ast.Ident:
+                  Name: x