}
-// Signatures
+// Function types
//
// (params)
// (params) type
// (params) (results)
-func (P *Parser) ParseSignature() {
- P.Trace("Signature");
+func (P *Parser) ParseFunctionType() {
+ P.Trace("FunctionType");
P.OpenScope();
P.level--;
}
-// Named signatures
-//
-// ident (params)
-// ident (params) type
-// ident (params) (results)
-// (recv) ident (params)
-// (recv) ident (params) type
-// (recv) ident (params) (results)
-
-func (P *Parser) ParseNamedSignature() *AST.Ident {
- P.Trace("NamedSignature");
-
- P.OpenScope();
- P.level--;
-
- if P.tok == Scanner.LPAREN {
- recv_pos := P.pos;
- n := P.ParseParameters();
- if n != 1 {
- P.Error(recv_pos, "must have exactly one receiver");
- panic("UNIMPLEMENTED (ParseNamedSignature)");
- // TODO do something useful here
- }
- }
-
- ident := P.ParseIdent();
-
- P.ParseParameters();
-
- P.ParseResult();
- P.level++;
- P.CloseScope();
-
- P.Ecart();
- return ident;
-}
-
-
-func (P *Parser) ParseFunctionType() {
- P.Trace("FunctionType");
-
- typ := P.ParseSignature();
-
- P.Ecart();
-}
-
-
func (P *Parser) ParseMethodDecl() {
P.Trace("MethodDecl");
ident := P.ParseIdent();
- P.OpenScope();
- P.level--;
-
- P.ParseParameters();
-
- //r0 := sig.entries.len;
- P.ParseResult();
- P.level++;
- P.CloseScope();
+ P.ParseFunctionType();
P.Optional(Scanner.SEMICOLON);
P.Ecart();
case Scanner.LBRACK: P.ParseArrayType();
case Scanner.CHAN, Scanner.ARROW: P.ParseChannelType();
case Scanner.INTERFACE: P.ParseInterfaceType();
- case Scanner.LPAREN: P.ParseSignature();
+ case Scanner.LPAREN: P.ParseFunctionType();
case Scanner.MAP: P.ParseMapType();
case Scanner.STRUCT: P.ParseStructType();
case Scanner.MUL: P.ParsePointerType();
P.Trace("FunctionLit");
P.Expect(Scanner.FUNC);
- P.ParseSignature(); // replace this with ParseFunctionType() and it won't work - 6g bug?
+ P.ParseFunctionType();
P.ParseBlock();
P.Ecart();
}
-func (P *Parser) ParseSelectorOrTypeAssertion(x AST.Expr) AST.Expr {
- P.Trace("SelectorOrTypeAssertion");
+func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr {
+ P.Trace("SelectorOrTypeGuard");
P.Expect(Scanner.PERIOD);
pos := P.pos;
// first arguments could be a type if the call is to "new"
// - exclude type names because they could be expression starts
// - exclude "("'s because function types are not allowed and they indicate an expression
+ // - still a problem for "new(*T)" (the "*")
+ // - possibility: make "new" a keyword again (or disallow "*" types in new)
if P.tok != Scanner.IDENT && P.tok != Scanner.LPAREN && P.TryType() {
if P.tok == Scanner.COMMA {
P.Next();
x := P.ParseOperand(ident);
for {
switch P.tok {
- case Scanner.PERIOD: x = P.ParseSelectorOrTypeAssertion(x);
+ case Scanner.PERIOD: x = P.ParseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.ParseIndexOrSlice(x);
case Scanner.LPAREN: x = P.ParseCall(x);
default: goto exit;
}
+// Function declarations
+//
+// func ident (params)
+// func ident (params) type
+// func ident (params) (results)
+// func (recv) ident (params)
+// func (recv) ident (params) type
+// func (recv) ident (params) (results)
+
func (P *Parser) ParseFuncDecl(exported bool) {
P.Trace("FuncDecl");
P.Expect(Scanner.FUNC);
- ident := P.ParseNamedSignature();
+
+
+ P.OpenScope();
+ P.level--;
+
+ if P.tok == Scanner.LPAREN {
+ recv_pos := P.pos;
+ n := P.ParseParameters();
+ if n != 1 {
+ P.Error(recv_pos, "must have exactly one receiver");
+ }
+ }
+
+ ident := P.ParseIdent();
+
+ P.ParseFunctionType();
+
+ P.level++;
+ P.CloseScope();
+
+
if P.tok == Scanner.SEMICOLON {
// forward declaration
P.Next();