Skip to content

Commit

Permalink
Merge pull request #1285 from xushiwei/cls
Browse files Browse the repository at this point in the history
parseErrWrapExpr: ErrWrapExpr as PrimaryExpr
  • Loading branch information
xushiwei authored Jun 18, 2022
2 parents d20cc79 + b465ff8 commit 188672b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 22 deletions.
2 changes: 2 additions & 0 deletions parser/_testdata/errwrap3/errwrap3.gop
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mkdir! "foo"
println foo()!.fields
47 changes: 47 additions & 0 deletions parser/_testdata/errwrap3/parser.expect
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions parser/_testdata/fncall/fncall.gop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn(1)(x)
30 changes: 30 additions & 0 deletions parser/_testdata/fncall/parser.expect
Original file line number Diff line number Diff line change
@@ -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
38 changes: 16 additions & 22 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 188672b

Please sign in to comment.