aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/parser.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-08-23 13:52:25 -0700
committerGopher Robot <gobot@golang.org>2023-08-24 07:17:27 +0000
commitd5c5808534f0ad97333b1fd5fff81998f44986fe (patch)
tree5fb63e5dd9910566ecf7f86fca171e95d20fe61c /src/cmd/compile/internal/syntax/parser.go
parent43e69b330a71e0d101bd57f0a1ea83bc4da259f3 (diff)
downloadgo-d5c5808534f0ad97333b1fd5fff81998f44986fe.tar.xz
cmd/compile/internal/syntax: add Unparen and UnpackListExpr helpers
We've added Unparen to go/ast, so add syntax.Unparen to be consistent (and because it's similarly useful). Also, types2 and noder both have similar functions for unpacking ListExprs, so might as well add a common implementation in package syntax too. Finally, addressing the TODO: UnpackListExpr is small enough to be inlined (when default optimizations are enabled), and for typical uses of UnpackListExpr (e.g., "range UnpackListExpr(x)") the single-element slice result is stack allocated in the caller. This CL adds a test using testing.AllocsPerRun to ensure this remains so in the future. Change-Id: I96a5591d202193ed5bf1ce6f290919107e3dc01b Reviewed-on: https://go-review.googlesource.com/c/go/+/522336 Auto-Submit: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/parser.go')
-rw-r--r--src/cmd/compile/internal/syntax/parser.go22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index b5602fcff7..7085287cad 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -885,7 +885,7 @@ func (p *parser) unaryExpr() Expr {
p.next()
// unaryExpr may have returned a parenthesized composite literal
// (see comment in operand) - remove parentheses if any
- x.X = unparen(p.unaryExpr())
+ x.X = Unparen(p.unaryExpr())
return x
}
@@ -965,7 +965,7 @@ func (p *parser) callStmt() *CallStmt {
p.next()
x := p.pexpr(nil, p.tok == _Lparen) // keep_parens so we can report error below
- if t := unparen(x); t != x {
+ if t := Unparen(x); t != x {
p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", s.Tok))
// already progressed, no need to advance
x = t
@@ -1190,7 +1190,7 @@ loop:
case _Lbrace:
// operand may have returned a parenthesized complit
// type; accept it but complain if we have a complit
- t := unparen(x)
+ t := Unparen(x)
// determine if '{' belongs to a composite literal or a block statement
complit_ok := false
switch t.(type) {
@@ -2812,8 +2812,8 @@ func (p *parser) typeList(strict bool) (x Expr, comma bool) {
return
}
-// unparen removes all parentheses around an expression.
-func unparen(x Expr) Expr {
+// Unparen returns e with any enclosing parentheses stripped.
+func Unparen(x Expr) Expr {
for {
p, ok := x.(*ParenExpr)
if !ok {
@@ -2823,3 +2823,15 @@ func unparen(x Expr) Expr {
}
return x
}
+
+// UnpackListExpr unpacks a *ListExpr into a []Expr.
+func UnpackListExpr(x Expr) []Expr {
+ switch x := x.(type) {
+ case nil:
+ return nil
+ case *ListExpr:
+ return x.ElemList
+ default:
+ return []Expr{x}
+ }
+}