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 | |
| 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
| -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;  } | 
