diff options
author | Robert Griesemer <gri@golang.org> | 2009-05-15 18:59:09 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2009-05-15 18:59:09 -0700 |
commit | 279a8ecef1d69d8349ddc04aa46c7b2a2cc2a32c (patch) | |
tree | 14aa8800e6aa915ddfa26e1aaa20375867e1763b /src/lib/go/parser/parser.go | |
parent | da090d345e35f3a290dbbbd13d2aec68041e0aeb (diff) | |
download | golang-279a8ecef1d69d8349ddc04aa46c7b2a2cc2a32c.tar.gz |
don't require ()'s around composite literals if the
literal type is not a type name
R=rsc
DELTA=41 (2 added, 7 deleted, 32 changed)
OCL=28955
CL=28957
Diffstat (limited to 'src/lib/go/parser/parser.go')
-rw-r--r-- | src/lib/go/parser/parser.go | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/src/lib/go/parser/parser.go b/src/lib/go/parser/parser.go index 4b733d7b1..c766526af 100644 --- a/src/lib/go/parser/parser.go +++ b/src/lib/go/parser/parser.go @@ -1070,40 +1070,34 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { } -// checkTypeName checks that x is type name. -func (p *parser) checkTypeName(x ast.Expr) ast.Expr { +// isTypeName returns true iff x is type name. +func isTypeName(x ast.Expr) bool { // TODO should provide predicate in AST nodes switch t := x.(type) { case *ast.BadExpr: case *ast.Ident: - case *ast.ParenExpr: p.checkTypeName(t.X); // TODO should (TypeName) be illegal? - case *ast.SelectorExpr: p.checkTypeName(t.X); - default: - // all other nodes are not type names - p.error_expected(x.Pos(), "type name"); - x = &ast.BadExpr{x.Pos()}; + case *ast.ParenExpr: return isTypeName(t.X); // TODO should (TypeName) be illegal? + case *ast.SelectorExpr: return isTypeName(t.X); + default: return false; // all other nodes are not type names } - return x; + return true; } -// checkCompositeLitType checks that x is a legal composite literal type. -func (p *parser) checkCompositeLitType(x ast.Expr) ast.Expr { +// isCompositeLitType returns true iff x is a legal composite literal type. +func isCompositeLitType(x ast.Expr) bool { // TODO should provide predicate in AST nodes switch t := x.(type) { - case *ast.BadExpr: return x; - case *ast.Ident: return x; - case *ast.ParenExpr: p.checkCompositeLitType(t.X); - case *ast.SelectorExpr: p.checkTypeName(t.X); - case *ast.ArrayType: return x; - case *ast.StructType: return x; - case *ast.MapType: return x; - default: - // all other nodes are not legal composite literal types - p.error_expected(x.Pos(), "composite literal type"); - x = &ast.BadExpr{x.Pos()}; + case *ast.BadExpr: + case *ast.Ident: + case *ast.ParenExpr: return isCompositeLitType(t.X); + case *ast.SelectorExpr: return isTypeName(t.X); + case *ast.ArrayType: + case *ast.StructType: + case *ast.MapType: + default: return false; // all other nodes are not legal composite literal types } - return x; + return true; } @@ -1137,24 +1131,23 @@ func (p *parser) parsePrimaryExpr() ast.Expr { } x := p.parseOperand(); - for { +L: for { switch p.tok { case token.PERIOD: x = p.parseSelectorOrTypeAssertion(p.checkExpr(x)); case token.LBRACK: x = p.parseIndex(p.checkExpr(x)); case token.LPAREN: x = p.parseCallOrConversion(p.checkExprOrType(x)); case token.LBRACE: - if p.expr_lev >= 0 { - x = p.parseCompositeLit(p.checkCompositeLitType(x)); + if isCompositeLitType(x) && (p.expr_lev >= 0 || !isTypeName(x)) { + x = p.parseCompositeLit(x); } else { - return p.checkExprOrType(x); + break L; } default: - return p.checkExprOrType(x); + break L; } } - panic(); // unreachable - return nil; + return p.checkExprOrType(x); } @@ -1768,7 +1761,9 @@ func (p *parser) parseReceiver() *ast.Field { if ptr, is_ptr := base.(*ast.StarExpr); is_ptr { base = ptr.X; } - p.checkTypeName(base); + if !isTypeName(base) { + p.error_expected(base.Pos(), "type name"); + } return recv; } |