1
0
mirror of https://github.com/golang/go synced 2024-11-25 13:07:57 -07:00

- permit ()'s in types (TODO: update spec)

- accept embedded interfaces in interfaces
- missing: output incorrect, but at least all source code is accepted again

R=r
OCL=25223
CL=25223
This commit is contained in:
Robert Griesemer 2009-02-19 16:47:58 -08:00
parent 3d50b1e0e8
commit 4137f02bb7

View File

@ -194,7 +194,7 @@ func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int,
} }
// declare a comma-separated list of idents or a single ident. // Declare a comma-separated list of idents or a single ident.
func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) { func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
for { for {
p, ok := x.(*AST.BinaryExpr); p, ok := x.(*AST.BinaryExpr);
@ -244,13 +244,15 @@ func (P *Parser) parseIdent(scope *SymbolTable.Scope) *AST.Ident {
} }
func (P *Parser) parseIdentList() AST.Expr { func (P *Parser) parseIdentList(x AST.Expr) AST.Expr {
if P.trace { if P.trace {
defer un(trace(P, "IdentList")); defer un(trace(P, "IdentList"));
} }
var last *AST.BinaryExpr; var last *AST.BinaryExpr;
var x AST.Expr = P.parseIdent(nil); if x == nil {
x = P.parseIdent(nil);
}
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
pos := P.pos; pos := P.pos;
P.next(); P.next();
@ -551,14 +553,20 @@ func (P *Parser) parseFunctionType() *AST.Type {
} }
func (P *Parser) parseMethodSpec(list *vector.Vector) { func (P *Parser) parseMethodOrInterfaceSpec(list *vector.Vector) {
if P.trace { if P.trace {
defer un(trace(P, "MethodDecl")); defer un(trace(P, "MethodOrInterfaceSpec"));
} }
list.Push(P.parseIdentList()); x := P.parseQualifiedIdent();
t := P.parseSignature(); if tmp, is_ident := x.(*AST.Ident); is_ident && (P.tok == Scanner.COMMA || P.tok == Scanner.LPAREN) {
list.Push(&AST.TypeLit(t)); // method(s)
list.Push(P.parseIdentList(x));
list.Push(&AST.TypeLit(P.parseSignature()));
} else {
// embedded interface
list.Push(x);
}
} }
@ -576,7 +584,7 @@ func (P *Parser) parseInterfaceType() *AST.Type {
t.List = vector.New(0); t.List = vector.New(0);
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.parseMethodSpec(t.List); P.parseMethodOrInterfaceSpec(t.List);
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.expect(Scanner.SEMICOLON); P.expect(Scanner.SEMICOLON);
} }
@ -678,6 +686,11 @@ func (P *Parser) tryType() *AST.Type {
case Scanner.MAP: return P.parseMapType(); case Scanner.MAP: return P.parseMapType();
case Scanner.STRUCT: return P.parseStructType(); case Scanner.STRUCT: return P.parseStructType();
case Scanner.MUL: return P.parsePointerType(); case Scanner.MUL: return P.parsePointerType();
case Scanner.LPAREN:
P.next();
t := P.parseType();
P.expect(Scanner.RPAREN);
return t;
} }
// no type found // no type found
@ -1374,7 +1387,7 @@ func (P *Parser) parseConstSpec(d *AST.Decl) {
defer un(trace(P, "ConstSpec")); defer un(trace(P, "ConstSpec"));
} }
d.Ident = P.parseIdentList(); d.Ident = P.parseIdentList(nil);
d.Typ = P.tryType(); d.Typ = P.tryType();
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.next(); P.next();
@ -1399,7 +1412,7 @@ func (P *Parser) parseVarSpec(d *AST.Decl) {
defer un(trace(P, "VarSpec")); defer un(trace(P, "VarSpec"));
} }
d.Ident = P.parseIdentList(); d.Ident = P.parseIdentList(nil);
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.next(); P.next();
d.Val = P.parseExpressionList(); d.Val = P.parseExpressionList();