Skip to content

Commit

Permalink
Merge pull request #1315 from visualfc/tuple
Browse files Browse the repository at this point in the history
parser: cmd style check tuple to list
  • Loading branch information
xushiwei committed Jul 4, 2022
2 parents e0f975b + d6c877e commit 94eb724
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 28 deletions.
1 change: 1 addition & 0 deletions parser/_testdata/cmdlinestyle6/cmd.gop
@@ -0,0 +1 @@
println (1+2i,2)
35 changes: 35 additions & 0 deletions parser/_testdata/cmdlinestyle6/parser.expect
@@ -0,0 +1,35 @@
package main

file cmd.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: println
Args:
ast.BinaryExpr:
X:
ast.BasicLit:
Kind: INT
Value: 1
Op: +
Y:
ast.BasicLit:
Kind: IMAG
Value: 2i
ast.BasicLit:
Kind: INT
Value: 2
79 changes: 51 additions & 28 deletions parser/parser.go
Expand Up @@ -688,10 +688,10 @@ func (p *parser) parseExprList(lhs, allowCmd bool) (list []ast.Expr) {
defer un(trace(p, "ExpressionList"))
}

list = append(list, p.checkExpr(p.parseExpr(lhs, allowCmd, false)))
list = append(list, p.checkExpr(p.parseExpr(lhs, false, allowCmd, false)))
for p.tok == token.COMMA {
p.next()
list = append(list, p.checkExpr(p.parseExpr(lhs, false, false)))
list = append(list, p.checkExpr(p.parseExpr(lhs, false, false, false)))
}
return
}
Expand Down Expand Up @@ -1406,21 +1406,21 @@ func (p *parser) parseOperand(lhs, allowTuple, allowCmd bool) ast.Expr {
p.next()
if allowTuple && p.tok == token.RPAREN { // () => expr
p.next()
return &tupleExpr{}
return &tupleExpr{Opening: lparen, Closing: p.pos}
}
p.exprLev++
x := p.parseRHSOrType() // types may be parenthesized: (some type)
x := p.parseRHSOrType(false) // types may be parenthesized: (some type)
if allowTuple && p.tok == token.COMMA {
// (x, y, ...) => expr
items := make([]*ast.Ident, 1, 2)
items[0] = p.toIdent(x)
items := make([]ast.Expr, 1, 2)
items[0] = x
for p.tok == token.COMMA {
p.next()
items = append(items, p.parseIdent())
items = append(items, p.parseRHSOrType(false))
}
p.exprLev--
p.expect(token.RPAREN)
return &tupleExpr{items: items}
return &tupleExpr{Opening: lparen, Items: items, Closing: p.pos}
}
p.exprLev--
rparen := p.expect(token.RPAREN)
Expand Down Expand Up @@ -1568,7 +1568,6 @@ func (p *parser) parseCallOrConversion(fun ast.Expr, isCmd bool) *ast.CallExpr {
if p.trace {
defer un(trace(p, "CallOrConversion"))
}

var lparen, rparen token.Pos
var endTok token.Token
if isCmd {
Expand All @@ -1580,7 +1579,14 @@ func (p *parser) parseCallOrConversion(fun ast.Expr, isCmd bool) *ast.CallExpr {
var list []ast.Expr
var ellipsis token.Pos
for p.tok != endTok && p.tok != token.EOF && !ellipsis.IsValid() {
list = append(list, p.parseRHSOrType()) // builtins may expect a type: make(some type, ...)
expr := p.parseRHSOrType(isCmd && len(list) == 0)
if tuple, ok := expr.(*tupleExpr); ok {
list = tuple.Items
rparen = tuple.Closing
isCmd = false
break
}
list = append(list, expr) // builtins may expect a type: make(some type, ...)
if p.tok == token.ELLIPSIS {
ellipsis = p.pos
p.next()
Expand All @@ -1600,7 +1606,7 @@ func (p *parser) parseCallOrConversion(fun ast.Expr, isCmd bool) *ast.CallExpr {
var noParenEnd token.Pos
if isCmd {
noParenEnd = p.pos
} else {
} else if rparen == token.NoPos {
rparen = p.expectClosing(token.RPAREN, "argument list")
}
if debugParseOutput {
Expand Down Expand Up @@ -1635,7 +1641,7 @@ func (p *parser) parseValue(keyOk bool) ast.Expr {
// undeclared; or b) it is a struct field. In the former case, the type
// checker can do a top-level lookup, and in the latter case it will do
// a separate field lookup.
x := p.checkExpr(p.parseExpr(keyOk, false, false))
x := p.checkExpr(p.parseExpr(keyOk, false, false, false))
if keyOk {
if p.tok == token.COLON {
// Try to resolve the key but don't collect it
Expand Down Expand Up @@ -1859,6 +1865,9 @@ func (p *parser) parsePrimaryExpr(lhs, allowTuple, allowCmd bool) ast.Expr {
}

x := p.parseOperand(lhs, allowTuple, allowCmd)
if _, ok := x.(*tupleExpr); ok {
return x
}
L:
for {
switch p.tok {
Expand Down Expand Up @@ -1898,6 +1907,9 @@ L:
}
isCmd := allowCmd && x.End() != p.pos // println ()
x = p.parseCallOrConversion(p.checkExprOrType(x), isCmd)
if isCmd && !x.(*ast.CallExpr).IsCommand() {
allowCmd = false
}
case token.LBRACE: // {
if allowCmd && x.End() != p.pos { // println {}
x = p.parseCallOrConversion(p.checkExprOrType(x), true)
Expand Down Expand Up @@ -2024,6 +2036,9 @@ func (p *parser) parseBinaryExpr(lhs bool, prec1 int, allowTuple, allowCmd bool)
}

x := p.parseUnaryExpr(lhs, allowTuple, allowCmd)
if _, ok := x.(*tupleExpr); ok {
return x
}
for {
op, oprec := p.tokPrec()
if oprec < prec1 {
Expand Down Expand Up @@ -2065,10 +2080,12 @@ func (p *parser) parseRangeExpr(allowCmd bool) ast.Expr {

type tupleExpr struct {
ast.Expr
items []*ast.Ident
Opening token.Pos
Items []ast.Expr
Closing token.Pos
}

func (p *parser) parseLambdaExpr(allowCmd, allowRangeExpr bool) ast.Expr {
func (p *parser) parseLambdaExpr(allowTuple bool, allowCmd, allowRangeExpr bool) ast.Expr {
var x ast.Expr
var first = p.pos
if p.tok != token.RARROW {
Expand All @@ -2089,7 +2106,7 @@ func (p *parser) parseLambdaExpr(allowCmd, allowRangeExpr bool) ast.Expr {
rhsHasParen = true
p.next()
for {
item := p.parseExpr(false, false, false)
item := p.parseExpr(false, false, false, false)
rhs = append(rhs, item)
if p.tok != token.COMMA {
break
Expand All @@ -2100,15 +2117,19 @@ func (p *parser) parseLambdaExpr(allowCmd, allowRangeExpr bool) ast.Expr {
case token.LBRACE: // {
body = p.parseBlockStmt()
default:
rhs = []ast.Expr{p.parseExpr(false, false, false)}
rhs = []ast.Expr{p.parseExpr(false, false, false, false)}
}
var lhs []*ast.Ident
if x != nil {
e := x
retry:
switch v := e.(type) {
case *tupleExpr:
lhs, lhsHasParen = v.items, true
items := make([]*ast.Ident, len(v.Items), len(v.Items))
for i, item := range v.Items {
items[i] = p.toIdent(item)
}
lhs, lhsHasParen = items, true
case *ast.ParenExpr:
e, lhsHasParen = v.X, true
goto retry
Expand Down Expand Up @@ -2138,8 +2159,10 @@ func (p *parser) parseLambdaExpr(allowCmd, allowRangeExpr bool) ast.Expr {
RhsHasParen: rhsHasParen,
}
}
if _, ok := x.(*tupleExpr); ok {
panic("TODO: tupleExpr")
if !allowTuple {
if tuple, ok := x.(*tupleExpr); ok {
p.error(tuple.Opening, "tuple is not supported")
}
}
return x
}
Expand All @@ -2148,14 +2171,14 @@ func (p *parser) parseLambdaExpr(allowCmd, allowRangeExpr bool) ast.Expr {
// The result may be a type or even a raw type ([...]int). Callers must
// check the result (using checkExpr or checkExprOrType), depending on
// context.
func (p *parser) parseExpr(lhs, allowCmd, allowRangeExpr bool) ast.Expr {
func (p *parser) parseExpr(lhs, allowTuple, allowCmd, allowRangeExpr bool) ast.Expr {
if p.trace {
defer un(trace(p, "Expression"))
}
if lhs {
return p.parseBinaryExpr(true, token.LowestPrec+1, false, allowCmd)
}
return p.parseLambdaExpr(allowCmd, allowRangeExpr)
return p.parseLambdaExpr(allowTuple, allowCmd, allowRangeExpr)
}

func (p *parser) parseRHS() ast.Expr {
Expand All @@ -2165,15 +2188,15 @@ func (p *parser) parseRHS() ast.Expr {
func (p *parser) parseRHSEx(allowRangeExpr bool) ast.Expr {
old := p.inRHS
p.inRHS = true
x := p.checkExpr(p.parseExpr(false, false, allowRangeExpr))
x := p.checkExpr(p.parseExpr(false, false, false, allowRangeExpr))
p.inRHS = old
return x
}

func (p *parser) parseRHSOrType() ast.Expr {
func (p *parser) parseRHSOrType(allowTuple bool) ast.Expr {
old := p.inRHS
p.inRHS = true
x := p.checkExprOrType(p.parseExpr(false, false, false))
x := p.checkExprOrType(p.parseExpr(false, allowTuple, false, false))
p.inRHS = old
return x
}
Expand Down Expand Up @@ -2275,7 +2298,7 @@ func (p *parser) parseSimpleStmt(mode int, allowCmd bool) (ast.Stmt, bool) {
}

func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
x := p.parseRHSOrType() // could be a conversion: (some type)(x)
x := p.parseRHSOrType(false) // could be a conversion: (some type)(x)
if call, isCall := x.(*ast.CallExpr); isCall {
return call
}
Expand Down Expand Up @@ -2740,13 +2763,13 @@ func (p *parser) parseForPhrases() (phrases []*ast.ForPhrase) {

func (p *parser) parseForPhraseStmtPart(lhs []ast.Expr) *ast.ForPhraseStmt {
tokPos := p.expect(token.ARROW) // <-
x := p.parseExpr(false, false, true)
x := p.parseExpr(false, false, false, true)
var cond ast.Expr
var ifPos token.Pos
if p.tok == token.IF || p.tok == token.COMMA {
ifPos = p.pos
p.next()
cond = p.parseExpr(false, false, false)
cond = p.parseExpr(false, false, false, false)
}

stmt := &ast.ForPhraseStmt{ForPhrase: &ast.ForPhrase{TokPos: tokPos, X: x, IfPos: ifPos, Cond: cond}}
Expand Down Expand Up @@ -2790,7 +2813,7 @@ func (p *parser) parseForPhrase() *ast.ForPhrase { // for k, v <- container if c
}

tokPos := p.expect(token.ARROW) // <- container
x := p.parseExpr(false, false, true)
x := p.parseExpr(false, false, false, true)
var init ast.Stmt
var cond ast.Expr
var ifPos token.Pos
Expand Down

0 comments on commit 94eb724

Please sign in to comment.