Commit 433e0597 authored by Robert Griesemer's avatar Robert Griesemer

- allow parenthesized [...]T types as in: ([...]int){}

- added extra tests

R=rsc
DELTA=55  (37 added, 0 deleted, 18 changed)
OCL=35250
CL=35276
parent 3e5a817d
...@@ -439,7 +439,7 @@ func (p *parser) parseFieldDecl() *ast.Field { ...@@ -439,7 +439,7 @@ func (p *parser) parseFieldDecl() *ast.Field {
// a list of identifiers looks like a list of type names // a list of identifiers looks like a list of type names
list := vector.New(0); list := vector.New(0);
for { for {
// TODO do not allow ()'s here // TODO(gri): do not allow ()'s here
list.Push(p.parseType()); list.Push(p.parseType());
if p.tok == token.COMMA { if p.tok == token.COMMA {
p.next(); p.next();
...@@ -465,7 +465,7 @@ func (p *parser) parseFieldDecl() *ast.Field { ...@@ -465,7 +465,7 @@ func (p *parser) parseFieldDecl() *ast.Field {
} else { } else {
// Type (anonymous field) // Type (anonymous field)
if list.Len() == 1 { if list.Len() == 1 {
// TODO check that this looks like a type // TODO(gri): check that this looks like a type
typ = list.At(0).(ast.Expr); typ = list.At(0).(ast.Expr);
} else { } else {
p.errorExpected(p.pos, "anonymous field"); p.errorExpected(p.pos, "anonymous field");
...@@ -554,7 +554,7 @@ func (p *parser) parseParameterDecl(ellipsisOk bool) (*vector.Vector, ast.Expr) ...@@ -554,7 +554,7 @@ func (p *parser) parseParameterDecl(ellipsisOk bool) (*vector.Vector, ast.Expr)
// a list of identifiers looks like a list of type names // a list of identifiers looks like a list of type names
list := vector.New(0); list := vector.New(0);
for { for {
// TODO do not allow ()'s here // TODO(gri): do not allow ()'s here
list.Push(p.parseParameterType(ellipsisOk)); list.Push(p.parseParameterType(ellipsisOk));
if p.tok == token.COMMA { if p.tok == token.COMMA {
p.next(); p.next();
...@@ -1050,14 +1050,14 @@ func (p *parser) parseCompositeLit(typ ast.Expr) ast.Expr { ...@@ -1050,14 +1050,14 @@ func (p *parser) parseCompositeLit(typ ast.Expr) ast.Expr {
} }
// TODO Consider different approach to checking syntax after parsing: // TODO(gri): Consider different approach to checking syntax after parsing:
// Provide a arguments (set of flags) to parsing functions // Provide a arguments (set of flags) to parsing functions
// restricting what they are supposed to accept depending // restricting what they are supposed to accept depending
// on context. // on context.
// checkExpr checks that x is an expression (and not a type). // checkExpr checks that x is an expression (and not a type).
func (p *parser) checkExpr(x ast.Expr) ast.Expr { func (p *parser) checkExpr(x ast.Expr) ast.Expr {
// TODO should provide predicate in AST nodes // TODO(gri): should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.BadExpr: case *ast.BadExpr:
case *ast.Ident: case *ast.Ident:
...@@ -1094,11 +1094,11 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { ...@@ -1094,11 +1094,11 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr {
// isTypeName returns true iff x is type name. // isTypeName returns true iff x is type name.
func isTypeName(x ast.Expr) bool { func isTypeName(x ast.Expr) bool {
// TODO should provide predicate in AST nodes // TODO(gri): should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.BadExpr: case *ast.BadExpr:
case *ast.Ident: case *ast.Ident:
case *ast.ParenExpr: return isTypeName(t.X); // TODO should (TypeName) be illegal? case *ast.ParenExpr: return isTypeName(t.X); // TODO(gri): should (TypeName) be illegal?
case *ast.SelectorExpr: return isTypeName(t.X); case *ast.SelectorExpr: return isTypeName(t.X);
default: return false; // all other nodes are not type names default: return false; // all other nodes are not type names
} }
...@@ -1108,7 +1108,7 @@ func isTypeName(x ast.Expr) bool { ...@@ -1108,7 +1108,7 @@ func isTypeName(x ast.Expr) bool {
// isCompositeLitType returns true iff x is a legal composite literal type. // isCompositeLitType returns true iff x is a legal composite literal type.
func isCompositeLitType(x ast.Expr) bool { func isCompositeLitType(x ast.Expr) bool {
// TODO should provide predicate in AST nodes // TODO(gri): should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.BadExpr: case *ast.BadExpr:
case *ast.Ident: case *ast.Ident:
...@@ -1127,7 +1127,7 @@ func isCompositeLitType(x ast.Expr) bool { ...@@ -1127,7 +1127,7 @@ func isCompositeLitType(x ast.Expr) bool {
// (and not a raw type such as [...]T). // (and not a raw type such as [...]T).
// //
func (p *parser) checkExprOrType(x ast.Expr) ast.Expr { func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
// TODO should provide predicate in AST nodes // TODO(gri): should provide predicate in AST nodes
switch t := x.(type) { switch t := x.(type) {
case *ast.UnaryExpr: case *ast.UnaryExpr:
if t.Op == token.RANGE { if t.Op == token.RANGE {
...@@ -1169,7 +1169,7 @@ L: for { ...@@ -1169,7 +1169,7 @@ L: for {
} }
} }
return p.checkExprOrType(x); return x;
} }
...@@ -1216,6 +1216,8 @@ func (p *parser) parseBinaryExpr(prec1 int) ast.Expr { ...@@ -1216,6 +1216,8 @@ func (p *parser) parseBinaryExpr(prec1 int) ast.Expr {
} }
// TODO(gri): parseExpr may return a type or even a raw type ([..]int) -
// should reject when a type/raw type is obviously not allowed
func (p *parser) parseExpr() ast.Expr { func (p *parser) parseExpr() ast.Expr {
if p.trace { if p.trace {
defer un(trace(p, "Expression")); defer un(trace(p, "Expression"));
...@@ -1523,7 +1525,7 @@ func (p *parser) parseSwitchStmt() ast.Stmt { ...@@ -1523,7 +1525,7 @@ func (p *parser) parseSwitchStmt() ast.Stmt {
} }
// type switch // type switch
// TODO do all the checks! // TODO(gri): do all the checks!
lbrace := p.expect(token.LBRACE); lbrace := p.expect(token.LBRACE);
cases := vector.New(0); cases := vector.New(0);
for p.tok == token.CASE || p.tok == token.DEFAULT { for p.tok == token.CASE || p.tok == token.DEFAULT {
......
...@@ -13,9 +13,11 @@ var ( ...@@ -13,9 +13,11 @@ var (
longIdentifier1, longIdentifier2, longIdentifier3 int; longIdentifier1, longIdentifier2, longIdentifier3 int;
t0, t1, t2 T; t0, t1, t2 T;
s string; s string;
p *int;
) )
func main() {
func _() {
// no spaces around simple or parenthesized expressions // no spaces around simple or parenthesized expressions
_ = a+b; _ = a+b;
_ = a+b+c; _ = a+b+c;
...@@ -36,7 +38,7 @@ func main() { ...@@ -36,7 +38,7 @@ func main() {
// spaces around expressions of different precedence or expressions containing spaces // spaces around expressions of different precedence or expressions containing spaces
_ = a + -b; _ = a + -b;
_ = a - ^b; _ = a - ^b;
_ = a / *b; _ = a / *p;
_ = a + b*c; _ = a + b*c;
_ = 1 + b*c; _ = 1 + b*c;
_ = a + 2*c; _ = a + 2*c;
...@@ -72,3 +74,20 @@ func main() { ...@@ -72,3 +74,20 @@ func main() {
_ = (a+b+c)*2; _ = (a+b+c)*2;
_ = a - b + c - d + (a+b+c) + d&e; _ = a - b + c - d + (a+b+c) + d&e;
} }
func _() {
_ = T{};
_ = struct{}{};
_ = [10]T{};
_ = [...]T{};
_ = []T{};
_ = map[int]T{};
_ = (T){};
_ = (struct{}){};
_ = ([10]T){};
_ = ([...]T){};
_ = ([]T){};
_ = (map[int]T){};
}
...@@ -13,9 +13,10 @@ var ( ...@@ -13,9 +13,10 @@ var (
longIdentifier1, longIdentifier2, longIdentifier3 int; longIdentifier1, longIdentifier2, longIdentifier3 int;
t0, t1, t2 T; t0, t1, t2 T;
s string; s string;
p *int;
) )
func main() { func _() {
// no spaces around simple or parenthesized expressions // no spaces around simple or parenthesized expressions
_ = a+b; _ = a+b;
_ = a+b+c; _ = a+b+c;
...@@ -36,7 +37,7 @@ func main() { ...@@ -36,7 +37,7 @@ func main() {
// spaces around expressions of different precedence or expressions containing spaces // spaces around expressions of different precedence or expressions containing spaces
_ = a + -b; _ = a + -b;
_ = a - ^b; _ = a - ^b;
_ = a / *b; _ = a / *p;
_ = a + b*c; _ = a + b*c;
_ = 1 + b*c; _ = 1 + b*c;
_ = a + 2*c; _ = a + 2*c;
...@@ -72,3 +73,18 @@ func main() { ...@@ -72,3 +73,18 @@ func main() {
_ = (a+b+c)*2; _ = (a+b+c)*2;
_ = a - b + c - d + (a+b+c) + d&e; _ = a - b + c - d + (a+b+c) + d&e;
} }
func _() {
_ = T{};
_ = struct{}{};
_ = [10]T{};
_ = [...]T{};
_ = []T{};
_ = map[int]T{};
_ = (T){};
_ = (struct{}){};
_ = ([10]T){};
_ = ([...]T){};
_ = ([]T){};
_ = (map[int]T){};
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment