Skip to content

Commit

Permalink
Merge pull request #1513 from visualfc/parser_literal
Browse files Browse the repository at this point in the history
parser: fix parsePrimaryExpr check literal value
  • Loading branch information
xushiwei authored Nov 2, 2023
2 parents 1972a4e + 7faaeb3 commit 17a67a2
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 39 deletions.
9 changes: 7 additions & 2 deletions parser/_instance/instance5/cmd.gop
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
var a [2]int

if 0 < a[0] {
println a
println T[int]{1}
println (T[int]){a:1,b:2}
println M[int]{1}
println T[int]{a: 1, b: 2}
}

for _, i := range []int{7, 42} {
println i
}
50 changes: 41 additions & 9 deletions parser/_instance/instance5/parser.expect
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ ast.FuncDecl:
ast.IndexExpr:
X:
ast.Ident:
Name: T
Name: M
Index:
ast.Ident:
Name: int
Expand All @@ -87,15 +87,13 @@ ast.FuncDecl:
Args:
ast.CompositeLit:
Type:
ast.ParenExpr:
ast.IndexExpr:
X:
ast.IndexExpr:
X:
ast.Ident:
Name: T
Index:
ast.Ident:
Name: int
ast.Ident:
Name: T
Index:
ast.Ident:
Name: int
Elts:
ast.KeyValueExpr:
Key:
Expand All @@ -113,3 +111,37 @@ ast.FuncDecl:
ast.BasicLit:
Kind: INT
Value: 2
ast.RangeStmt:
Key:
ast.Ident:
Name: _
Value:
ast.Ident:
Name: i
Tok: :=
X:
ast.CompositeLit:
Type:
ast.ArrayType:
Elt:
ast.Ident:
Name: int
Elts:
ast.BasicLit:
Kind: INT
Value: 7
ast.BasicLit:
Kind: INT
Value: 42
Body:
ast.BlockStmt:
List:
ast.ExprStmt:
X:
ast.CallExpr:
Fun:
ast.Ident:
Name: println
Args:
ast.Ident:
Name: i
50 changes: 22 additions & 28 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2068,29 +2068,6 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr {
return x
}

// isLiteralType reports whether x is a legal composite literal type.
func isLiteralType(x ast.Expr) bool {
switch t := unparen(x).(type) {
case *ast.BadExpr:
case *ast.Ident:
case *ast.IndexExpr:
_, isIdent := t.X.(*ast.Ident)
return isIdent
case *ast.IndexListExpr:
_, isIdent := t.X.(*ast.Ident)
return isIdent
case *ast.SelectorExpr:
_, isIdent := t.X.(*ast.Ident)
return isIdent
case *ast.ArrayType:
case *ast.StructType:
case *ast.MapType:
default:
return false // all other nodes are not legal composite literal types
}
return true
}

/*
// If x is of the form *T, deref returns T, otherwise it returns x.
func deref(x ast.Expr) ast.Expr {
Expand Down Expand Up @@ -2174,13 +2151,30 @@ L:
case token.LBRACE: // {
if allowCmd && p.isCmd(x) { // println {...}
x = p.parseCallOrConversion(p.checkExprOrType(x), true)
} else if isLiteralType(x) && p.exprLev >= 0 {
if lhs {
p.resolve(x)
} else {
t := unparen(x)
// determine if '{' belongs to a composite literal or a block statement
switch t.(type) {
case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
if p.exprLev < 0 {
break L
}
// x is possibly a composite literal type
case *ast.IndexExpr, *ast.IndexListExpr:
if p.exprLev < 0 {
break L
}
// x is possibly a composite literal type
case *ast.ArrayType, *ast.StructType, *ast.MapType:
// x is a composite literal type
default:
break L
}
if t != x {
p.error(t.Pos(), "cannot parenthesize type in composite literal")
// already progressed, no need to advance
}
x = p.parseLiteralValue(x)
} else {
break L
}
case token.NOT:
if allowCmd && p.isCmd(x) {
Expand Down
5 changes: 5 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,4 +513,9 @@ func TestErrGlobal(t *testing.T) {
}`, `/foo/bar.gop:2:1: expected statement, found '}'`, ``)
}

func TestErrCompositeLiteral(t *testing.T) {
testErrCode(t, `println (T[int]){a: 1, b: 2}
`, `/foo/bar.gop:1:10: cannot parenthesize type in composite literal`, ``)
}

// -----------------------------------------------------------------------------

0 comments on commit 17a67a2

Please sign in to comment.