summaryrefslogtreecommitdiff
path: root/src/lib/go/parser/parser.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-05-15 18:59:09 -0700
committerRobert Griesemer <gri@golang.org>2009-05-15 18:59:09 -0700
commit279a8ecef1d69d8349ddc04aa46c7b2a2cc2a32c (patch)
tree14aa8800e6aa915ddfa26e1aaa20375867e1763b /src/lib/go/parser/parser.go
parentda090d345e35f3a290dbbbd13d2aec68041e0aeb (diff)
downloadgolang-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.go57
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;
}