summaryrefslogtreecommitdiff
path: root/usr/gri/pretty/parser.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-02-03 17:44:01 -0800
committerRobert Griesemer <gri@golang.org>2009-02-03 17:44:01 -0800
commit6cf98e2fac82bf23405d65e9f12ff8ef4d9eccbd (patch)
tree7623ee690fee937783d444c5c81aed4e4733d552 /usr/gri/pretty/parser.go
parent0c7951cc9ca7792155bd78bd8bbb5220281cb6f1 (diff)
downloadgolang-6cf98e2fac82bf23405d65e9f12ff8ef4d9eccbd.tar.gz
- converted expr representation of ast into a new representation
using interfaces properly => much cleaner code - converted tracing code to use 'defer' statement - next steps: convert rest of ast as well R=r OCL=24277 CL=24277
Diffstat (limited to 'usr/gri/pretty/parser.go')
-rw-r--r--usr/gri/pretty/parser.go714
1 files changed, 391 insertions, 323 deletions
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index 8f08bcb30..ae904a651 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -64,26 +64,22 @@ func assert(pred bool) {
func (P *Parser) PrintIndent() {
for i := P.indent; i > 0; i-- {
- print(". ");
+ fmt.Printf(". ");
}
}
func (P *Parser) Trace(msg string) {
- if P.verbose {
- P.PrintIndent();
- print(msg, " {\n");
- }
- P.indent++; // always check proper identation
+ P.PrintIndent();
+ fmt.Printf("%s {\n", msg);
+ P.indent++;
}
func (P *Parser) Ecart() {
- P.indent--; // always check proper identation
- if P.verbose {
- P.PrintIndent();
- print("}\n");
- }
+ P.indent--;
+ P.PrintIndent();
+ fmt.Printf("}\n");
}
@@ -105,7 +101,7 @@ func (P *Parser) Next0() {
case "{": s = "LBRACE";
case "}": s = "RBRACE";
}
- print("[", P.pos, "] ", s, "\n");
+ fmt.Printf("[%d] %s\n", P.pos, s);
}
}
@@ -171,13 +167,12 @@ func (P *Parser) CloseScope() {
}
-func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int, typ *AST.Type) {
+func (P *Parser) DeclareInScope(scope *AST.Scope, x AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
}
- if x.Tok != Scanner.ILLEGAL { // ignore bad exprs
- assert(x.Tok == Scanner.IDENT);
- obj := x.Obj;
+ if ident, ok := x.(*AST.Ident); ok { // ignore bad exprs
+ obj := ident.Obj;
obj.Kind = kind;
obj.Typ = typ;
obj.Pnolev = P.scope_lev;
@@ -196,47 +191,54 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int, typ *AS
// Declare a comma-separated list of idents or a single ident.
-func (P *Parser) Declare(p *AST.Expr, kind int, typ *AST.Type) {
- for p.Tok == Scanner.COMMA {
- P.DeclareInScope(P.top_scope, p.X, kind, typ);
- p = p.Y;
+func (P *Parser) Declare(x AST.Expr, kind int, typ *AST.Type) {
+ for {
+ p, ok := x.(*AST.BinaryExpr);
+ if ok && p.Tok == Scanner.COMMA {
+ P.DeclareInScope(P.top_scope, p.X, kind, typ);
+ x = p.Y;
+ } else {
+ break;
+ }
}
- P.DeclareInScope(P.top_scope, p, kind, typ);
+ P.DeclareInScope(P.top_scope, x, kind, typ);
}
// ----------------------------------------------------------------------------
// AST support
-func exprType(x *AST.Expr) *AST.Type {
- var t *AST.Type;
- if x.Tok == Scanner.TYPE {
- t = x.Typ;
- } else if x.Tok == Scanner.IDENT {
+func exprType(x AST.Expr) *AST.Type {
+ var typ *AST.Type;
+ if t, is_type := x.(*AST.TypeLit); is_type {
+ typ = t.Typ
+ } else if t, is_ident := x.(*AST.Ident); is_ident {
// assume a type name
- t = AST.NewType(x.Pos, AST.TYPENAME);
- t.Expr = x;
- } else if x.Tok == Scanner.PERIOD && x.Y != nil && exprType(x.X) != nil {
+ typ = AST.NewType(t.Pos(), AST.TYPENAME);
+ typ.Expr = x;
+ } else if t, is_selector := x.(*AST.Selector); is_selector && exprType(t.Sel) != nil {
// possibly a qualified (type) identifier
- t = AST.NewType(x.Pos, AST.TYPENAME);
- t.Expr = x;
+ typ = AST.NewType(t.Pos(), AST.TYPENAME);
+ typ.Expr = x;
}
- return t;
+ return typ;
}
-func (P *Parser) NoType(x *AST.Expr) *AST.Expr {
- if x != nil && x.Tok == Scanner.TYPE {
- P.Error(x.Pos, "expected expression, found type");
- val := AST.NewObject(x.Pos, AST.NONE, "0");
- x = AST.NewLit(Scanner.INT, val);
+func (P *Parser) NoType(x AST.Expr) AST.Expr {
+ if x != nil {
+ lit, ok := x.(*AST.TypeLit);
+ if ok {
+ P.Error(lit.Typ.Pos, "expected expression, found type");
+ x = &AST.BasicLit{lit.Typ.Pos, Scanner.STRING, ""};
+ }
}
return x;
}
-func (P *Parser) NewExpr(pos, tok int, x, y *AST.Expr) *AST.Expr {
- return AST.NewExpr(pos, tok, P.NoType(x), P.NoType(y));
+func (P *Parser) NewBinary(pos, tok int, x, y AST.Expr) *AST.BinaryExpr {
+ return &AST.BinaryExpr{pos, tok, P.NoType(x), P.NoType(y)};
}
@@ -244,16 +246,18 @@ func (P *Parser) NewExpr(pos, tok int, x, y *AST.Expr) *AST.Expr {
// Common productions
func (P *Parser) TryType() *AST.Type;
-func (P *Parser) ParseExpression(prec int) *AST.Expr;
+func (P *Parser) ParseExpression(prec int) AST.Expr;
func (P *Parser) ParseStatement() *AST.Stat;
func (P *Parser) ParseDeclaration() *AST.Decl;
// If scope != nil, lookup identifier in scope. Otherwise create one.
-func (P *Parser) ParseIdent(scope *AST.Scope) *AST.Expr {
- P.Trace("Ident");
+func (P *Parser) ParseIdent(scope *AST.Scope) *AST.Ident {
+ if P.verbose {
+ P.Trace("Ident");
+ defer P.Ecart();
+ }
- x := AST.BadExpr;
if P.tok == Scanner.IDENT {
var obj *AST.Object;
if scope != nil {
@@ -264,41 +268,41 @@ func (P *Parser) ParseIdent(scope *AST.Scope) *AST.Expr {
} else {
assert(obj.Kind != AST.NONE);
}
- x = AST.NewLit(Scanner.IDENT, obj);
- x.Pos = P.pos; // override obj.pos (incorrect if object was looked up!)
+ x := &AST.Ident{P.pos, obj};
if P.verbose {
P.PrintIndent();
- print("Ident = \"", P.val, "\"\n");
+ fmt.Printf("ident = \"%s\"\n", P.val);
}
P.Next();
- } else {
- P.Expect(Scanner.IDENT); // use Expect() error handling
+ return x;
}
-
- P.Ecart();
- return x;
+
+ P.Expect(Scanner.IDENT); // use Expect() error handling
+ return &AST.Ident{P.pos, nil};
}
-func (P *Parser) ParseIdentList() *AST.Expr {
- P.Trace("IdentList");
+func (P *Parser) ParseIdentList() AST.Expr {
+ if P.verbose {
+ P.Trace("IdentList");
+ defer P.Ecart();
+ }
- var last *AST.Expr;
- x := P.ParseIdent(nil);
+ var last *AST.BinaryExpr;
+ var x AST.Expr = P.ParseIdent(nil);
for P.tok == Scanner.COMMA {
pos := P.pos;
P.Next();
y := P.ParseIdent(nil);
if last == nil {
- x = P.NewExpr(pos, Scanner.COMMA, x, y);
- last = x;
+ last = P.NewBinary(pos, Scanner.COMMA, x, y);
+ x = last;
} else {
- last.Y = P.NewExpr(pos, Scanner.COMMA, last.Y, y);
+ last.Y = P.NewBinary(pos, Scanner.COMMA, last.Y, y);
last = last.Y;
}
}
- P.Ecart();
return x;
}
@@ -307,7 +311,10 @@ func (P *Parser) ParseIdentList() *AST.Expr {
// Types
func (P *Parser) ParseType() *AST.Type {
- P.Trace("Type");
+ if P.verbose {
+ P.Trace("Type");
+ defer P.Ecart();
+ }
t := P.TryType();
if t == nil {
@@ -315,56 +322,61 @@ func (P *Parser) ParseType() *AST.Type {
t = AST.BadType;
}
- P.Ecart();
return t;
}
func (P *Parser) ParseVarType() *AST.Type {
- P.Trace("VarType");
-
- typ := P.ParseType();
+ if P.verbose {
+ P.Trace("VarType");
+ defer P.Ecart();
+ }
- P.Ecart();
- return typ;
+ return P.ParseType();
}
-func (P *Parser) ParseQualifiedIdent() *AST.Expr {
- P.Trace("QualifiedIdent");
+func (P *Parser) ParseQualifiedIdent() AST.Expr {
+ if P.verbose {
+ P.Trace("QualifiedIdent");
+ defer P.Ecart();
+ }
- x := P.ParseIdent(P.top_scope);
+ var x AST.Expr = P.ParseIdent(P.top_scope);
for P.tok == Scanner.PERIOD {
pos := P.pos;
P.Next();
y := P.ParseIdent(nil);
- x = P.NewExpr(pos, Scanner.PERIOD, x, y);
+ x = &AST.Selector{pos, x, y};
}
- P.Ecart();
return x;
}
func (P *Parser) ParseTypeName() *AST.Type {
- P.Trace("TypeName");
+ if P.verbose {
+ P.Trace("TypeName");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.TYPENAME);
t.Expr = P.ParseQualifiedIdent();
- t.Elt = t.Expr.Typ;
- P.Ecart();
return t;
}
func (P *Parser) ParseArrayType() *AST.Type {
- P.Trace("ArrayType");
+ if P.verbose {
+ P.Trace("ArrayType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.ARRAY);
P.Expect(Scanner.LBRACK);
if P.tok == Scanner.ELLIPSIS {
- t.Expr = P.NewExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
+ t.Expr = P.NewBinary(P.pos, Scanner.ELLIPSIS, nil, nil);
P.Next();
} else if P.tok != Scanner.RBRACK {
t.Expr = P.ParseExpression(1);
@@ -372,13 +384,15 @@ func (P *Parser) ParseArrayType() *AST.Type {
P.Expect(Scanner.RBRACK);
t.Elt = P.ParseType();
- P.Ecart();
return t;
}
func (P *Parser) ParseChannelType() *AST.Type {
- P.Trace("ChannelType");
+ if P.verbose {
+ P.Trace("ChannelType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.CHANNEL);
t.Mode = AST.FULL;
@@ -395,7 +409,6 @@ func (P *Parser) ParseChannelType() *AST.Type {
}
t.Elt = P.ParseVarType();
- P.Ecart();
return t;
}
@@ -404,7 +417,7 @@ func (P *Parser) ParseVar(expect_ident bool) *AST.Type {
t := AST.BadType;
if expect_ident {
x := P.ParseIdent(nil);
- t = AST.NewType(x.Pos, AST.TYPENAME);
+ t = AST.NewType(x.Pos(), AST.TYPENAME);
t.Expr = x;
} else if P.tok == Scanner.ELLIPSIS {
t = AST.NewType(P.pos, AST.ELLIPSIS);
@@ -417,7 +430,10 @@ func (P *Parser) ParseVar(expect_ident bool) *AST.Type {
func (P *Parser) ParseVarList(list *array.Array, ellipsis_ok bool) {
- P.Trace("VarList");
+ if P.verbose {
+ P.Trace("VarList");
+ defer P.Ecart();
+ }
// assume a list of types
// (a list of identifiers looks like a list of type names)
@@ -450,31 +466,34 @@ func (P *Parser) ParseVarList(list *array.Array, ellipsis_ok bool) {
// convert the type entries into identifiers
for i, n := i0, list.Len(); i < n; i++ {
t := list.At(i).(*AST.Type);
- if t.Form == AST.TYPENAME && t.Expr.Tok == Scanner.IDENT {
- list.Set(i, t.Expr);
- } else {
- list.Set(i, AST.BadExpr);
- P.Error(t.Pos, "identifier expected");
+ if t.Form == AST.TYPENAME {
+ if ident, ok := t.Expr.(*AST.Ident); ok {
+ list.Set(i, ident);
+ continue;
+ }
}
+ list.Set(i, &AST.BadExpr{0});
+ P.Error(t.Pos, "identifier expected");
}
// add type
- list.Push(AST.NewTypeExpr(typ));
+ list.Push(&AST.TypeLit{typ});
} else {
// all list entries are types
// convert all type entries into type expressions
for i, n := i0, list.Len(); i < n; i++ {
t := list.At(i).(*AST.Type);
- list.Set(i, AST.NewTypeExpr(t));
+ list.Set(i, &AST.TypeLit{t});
}
}
-
- P.Ecart();
}
func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array {
- P.Trace("ParameterList");
+ if P.verbose {
+ P.Trace("ParameterList");
+ defer P.Ecart();
+ }
list := array.New(0);
P.ParseVarList(list, ellipsis_ok);
@@ -483,13 +502,15 @@ func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array {
P.ParseVarList(list, ellipsis_ok);
}
- P.Ecart();
return list;
}
func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type {
- P.Trace("Parameters");
+ if P.verbose {
+ P.Trace("Parameters");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.STRUCT);
P.Expect(Scanner.LPAREN);
@@ -499,13 +520,15 @@ func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type {
t.End = P.pos;
P.Expect(Scanner.RPAREN);
- P.Ecart();
return t;
}
func (P *Parser) ParseResultList() {
- P.Trace("ResultList");
+ if P.verbose {
+ P.Trace("ResultList");
+ defer P.Ecart();
+ }
P.ParseType();
for P.tok == Scanner.COMMA {
@@ -515,13 +538,14 @@ func (P *Parser) ParseResultList() {
if P.tok != Scanner.RPAREN {
P.ParseType();
}
-
- P.Ecart();
}
func (P *Parser) ParseResult(ftyp *AST.Type) *AST.Type {
- P.Trace("Result");
+ if P.verbose {
+ P.Trace("Result");
+ defer P.Ecart();
+ }
var t *AST.Type;
if P.tok == Scanner.LPAREN {
@@ -531,12 +555,11 @@ func (P *Parser) ParseResult(ftyp *AST.Type) *AST.Type {
if typ != nil {
t = AST.NewType(P.pos, AST.STRUCT);
t.List = array.New(0);
- t.List.Push(AST.NewTypeExpr(typ));
+ t.List.Push(&AST.TypeLit{typ});
t.End = P.pos;
}
}
- P.Ecart();
return t;
}
@@ -548,7 +571,10 @@ func (P *Parser) ParseResult(ftyp *AST.Type) *AST.Type {
// (params) (results)
func (P *Parser) ParseSignature() *AST.Type {
- P.Trace("Signature");
+ if P.verbose {
+ P.Trace("Signature");
+ defer P.Ecart();
+ }
P.OpenScope();
P.scope_lev++;
@@ -562,35 +588,38 @@ func (P *Parser) ParseSignature() *AST.Type {
P.scope_lev--;
P.CloseScope();
- P.Ecart();
return t;
}
func (P *Parser) ParseFunctionType() *AST.Type {
- P.Trace("FunctionType");
+ if P.verbose {
+ P.Trace("FunctionType");
+ defer P.Ecart();
+ }
P.Expect(Scanner.FUNC);
- t := P.ParseSignature();
-
- P.Ecart();
- return t;
+ return P.ParseSignature();
}
func (P *Parser) ParseMethodSpec(list *array.Array) {
- P.Trace("MethodDecl");
+ if P.verbose {
+ P.Trace("MethodDecl");
+ defer P.Ecart();
+ }
list.Push(P.ParseIdentList());
t := P.ParseSignature();
- list.Push(AST.NewTypeExpr(t));
-
- P.Ecart();
+ list.Push(&AST.TypeLit{t});
}
func (P *Parser) ParseInterfaceType() *AST.Type {
- P.Trace("InterfaceType");
+ if P.verbose {
+ P.Trace("InterfaceType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.INTERFACE);
P.Expect(Scanner.INTERFACE);
@@ -613,13 +642,15 @@ func (P *Parser) ParseInterfaceType() *AST.Type {
P.Expect(Scanner.RBRACE);
}
- P.Ecart();
return t;
}
func (P *Parser) ParseMapType() *AST.Type {
- P.Trace("MapType");
+ if P.verbose {
+ P.Trace("MapType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.MAP);
P.Expect(Scanner.MAP);
@@ -628,15 +659,17 @@ func (P *Parser) ParseMapType() *AST.Type {
P.Expect(Scanner.RBRACK);
t.Elt = P.ParseVarType();
- P.Ecart();
return t;
}
-func (P *Parser) ParseOperand() *AST.Expr
+func (P *Parser) ParseOperand() AST.Expr
func (P *Parser) ParseStructType() *AST.Type {
- P.Trace("StructType");
+ if P.verbose {
+ P.Trace("StructType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.STRUCT);
P.Expect(Scanner.STRUCT);
@@ -664,32 +697,35 @@ func (P *Parser) ParseStructType() *AST.Type {
// enter fields into struct scope
for i, n := 0, t.List.Len(); i < n; i++ {
- x := t.List.At(i).(*AST.Expr);
- if x.Tok == Scanner.IDENT {
+ if x, ok := t.List.At(i).(*AST.Ident); ok {
P.DeclareInScope(t.Scope, x, AST.FIELD, nil);
}
}
}
- P.Ecart();
return t;
}
func (P *Parser) ParsePointerType() *AST.Type {
- P.Trace("PointerType");
+ if P.verbose {
+ P.Trace("PointerType");
+ defer P.Ecart();
+ }
t := AST.NewType(P.pos, AST.POINTER);
P.Expect(Scanner.MUL);
t.Elt = P.ParseType();
- P.Ecart();
return t;
}
func (P *Parser) TryType() *AST.Type {
- P.Trace("Type (try)");
+ if P.verbose {
+ P.Trace("Type (try)");
+ defer P.Ecart();
+ }
t := AST.BadType;
switch P.tok {
@@ -703,8 +739,6 @@ func (P *Parser) TryType() *AST.Type {
case Scanner.MUL: t = P.ParsePointerType();
default: t = nil; // no type found
}
-
- P.Ecart();
return t;
}
@@ -713,7 +747,10 @@ func (P *Parser) TryType() *AST.Type {
// Blocks
func (P *Parser) ParseStatementList(list *array.Array) {
- P.Trace("StatementList");
+ if P.verbose {
+ P.Trace("StatementList");
+ defer P.Ecart();
+ }
for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s := P.ParseStatement();
@@ -734,13 +771,14 @@ func (P *Parser) ParseStatementList(list *array.Array) {
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.Error(P.pos, "expected end of statement list (semicolon missing?)");
}
-
- P.Ecart();
}
func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
- P.Trace("Block");
+ if P.verbose {
+ P.Trace("Block");
+ defer P.Ecart();
+ }
b := AST.NewBlock(P.pos, tok);
P.Expect(tok);
@@ -753,8 +791,7 @@ func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
}
if ftyp.List != nil {
for i, n := 0, ftyp.List.Len(); i < n; i++ {
- x := ftyp.List.At(i).(*AST.Expr);
- if x.Tok == Scanner.IDENT {
+ if x, ok := ftyp.List.At(i).(*AST.Ident); ok {
P.DeclareInScope(P.top_scope, x, AST.VAR, nil);
}
}
@@ -770,7 +807,6 @@ func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
P.opt_semi = true;
}
- P.Ecart();
return b;
}
@@ -778,8 +814,11 @@ func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
// ----------------------------------------------------------------------------
// Expressions
-func (P *Parser) ParseExpressionList() *AST.Expr {
- P.Trace("ExpressionList");
+func (P *Parser) ParseExpressionList() AST.Expr {
+ if P.verbose {
+ P.Trace("ExpressionList");
+ defer P.Ecart();
+ }
x := P.ParseExpression(1);
for first := true; P.tok == Scanner.COMMA; {
@@ -787,111 +826,112 @@ func (P *Parser) ParseExpressionList() *AST.Expr {
P.Next();
y := P.ParseExpression(1);
if first {
- x = P.NewExpr(pos, Scanner.COMMA, x, y);
+ x = P.NewBinary(pos, Scanner.COMMA, x, y);
first = false;
} else {
- x.Y = P.NewExpr(pos, Scanner.COMMA, x.Y, y);
+ x.(*AST.BinaryExpr).Y = P.NewBinary(pos, Scanner.COMMA, x.(*AST.BinaryExpr).Y, y);
}
}
- P.Ecart();
return x;
}
-func (P *Parser) ParseFunctionLit() *AST.Expr {
- P.Trace("FunctionLit");
+func (P *Parser) ParseFunctionLit() AST.Expr {
+ if P.verbose {
+ P.Trace("FunctionLit");
+ defer P.Ecart();
+ }
- f := AST.NewObject(P.pos, AST.FUNC, "");
+ pos := P.pos;
P.Expect(Scanner.FUNC);
- f.Typ = P.ParseSignature();
+ typ := P.ParseSignature();
P.expr_lev++;
P.scope_lev++;
- f.Body = P.ParseBlock(f.Typ, Scanner.LBRACE);
+ body := P.ParseBlock(typ, Scanner.LBRACE);
P.scope_lev--;
P.expr_lev--;
- P.Ecart();
- return AST.NewLit(Scanner.FUNC, f);
+ return &AST.FunctionLit{pos, typ, body};
}
-func (P *Parser) ParseOperand() *AST.Expr {
- P.Trace("Operand");
+func (P *Parser) ParseOperand() AST.Expr {
+ if P.verbose {
+ P.Trace("Operand");
+ defer P.Ecart();
+ }
- x := AST.BadExpr;
switch P.tok {
case Scanner.IDENT:
- x = P.ParseIdent(P.top_scope);
+ return P.ParseIdent(P.top_scope);
case Scanner.LPAREN:
// TODO we could have a function type here as in: new(())
// (currently not working)
P.Next();
P.expr_lev++;
- x = P.ParseExpression(1);
+ x := P.ParseExpression(1);
P.expr_lev--;
P.Expect(Scanner.RPAREN);
+ return x;
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
- val := AST.NewObject(P.pos, AST.NONE, P.val);
- x = AST.NewLit(P.tok, val);
+ x := &AST.BasicLit{P.pos, P.tok, P.val};
P.Next();
if x.Tok == Scanner.STRING {
// TODO should remember the list instead of
// concatenate the strings here
for ; P.tok == Scanner.STRING; P.Next() {
- x.Obj.Ident += P.val;
+ x.Val += P.val;
}
}
+ return x;
case Scanner.FUNC:
- x = P.ParseFunctionLit();
+ return P.ParseFunctionLit();
default:
t := P.TryType();
if t != nil {
- x = AST.NewTypeExpr(t);
+ return &AST.TypeLit{t};
} else {
P.Error(P.pos, "operand expected");
P.Next(); // make progress
}
}
- P.Ecart();
- return x;
+ return &AST.BadExpr{P.pos};
}
-func (P *Parser) ParseSelectorOrTypeGuard(x *AST.Expr) *AST.Expr {
- P.Trace("SelectorOrTypeGuard");
+func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr {
+ if P.verbose {
+ P.Trace("SelectorOrTypeGuard");
+ defer P.Ecart();
+ }
- x = P.NewExpr(P.pos, Scanner.PERIOD, x, nil);
+ pos := P.pos;
P.Expect(Scanner.PERIOD);
if P.tok == Scanner.IDENT {
- // TODO should always guarantee x.Typ != nil
- var scope *AST.Scope;
- if x.X.Typ != nil {
- scope = x.X.Typ.Scope;
- }
- x.Y = P.ParseIdent(scope);
- x.Typ = x.Y.Obj.Typ;
+ x = &AST.Selector{pos, x, P.ParseIdent(nil)};
} else {
P.Expect(Scanner.LPAREN);
- x.Y = AST.NewTypeExpr(P.ParseType());
- x.Typ = x.Y.Typ;
+ x = &AST.TypeGuard{pos, x, P.ParseType()};
P.Expect(Scanner.RPAREN);
}
- P.Ecart();
return x;
}
-func (P *Parser) ParseIndex(x *AST.Expr) *AST.Expr {
- P.Trace("IndexOrSlice");
+func (P *Parser) ParseIndex(x AST.Expr) AST.Expr {
+ if P.verbose {
+ P.Trace("IndexOrSlice");
+ defer P.Ecart();
+ }
pos := P.pos;
P.Expect(Scanner.LBRACK);
@@ -900,51 +940,51 @@ func (P *Parser) ParseIndex(x *AST.Expr) *AST.Expr {
P.expr_lev--;
P.Expect(Scanner.RBRACK);
- P.Ecart();
- return P.NewExpr(pos, Scanner.LBRACK, x, i);
+ return &AST.Index{pos, x, i};
}
-func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr
+func (P *Parser) ParseBinaryExpr(prec1 int) AST.Expr
-func (P *Parser) ParseCall(x0 *AST.Expr) *AST.Expr {
- P.Trace("Call");
+func (P *Parser) ParseCall(f AST.Expr) AST.Expr {
+ if P.verbose {
+ P.Trace("Call");
+ defer P.Ecart();
+ }
- x := P.NewExpr(P.pos, Scanner.LPAREN, x0, nil);
+ call := &AST.Call{P.pos, f, nil};
P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
P.expr_lev++;
var t *AST.Type;
- if x0.Tok == Scanner.IDENT && (x0.Obj.Ident == "new" || x0.Obj.Ident == "make") {
+ if x0, ok := f.(*AST.Ident); ok && (x0.Obj.Ident == "new" || x0.Obj.Ident == "make") {
// heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
t = P.TryType();
}
if t != nil {
// we found a type
- x.Y = AST.NewTypeExpr(t);
+ args := &AST.TypeLit{t};
if P.tok == Scanner.COMMA {
pos := P.pos;
P.Next();
y := P.ParseExpressionList();
// create list manually because NewExpr checks for type expressions
- z := AST.NewExpr(pos, Scanner.COMMA, nil, y);
- z.X = x.Y;
- x.Y = z;
+ args := &AST.BinaryExpr{pos, Scanner.COMMA, args, y};
}
+ call.Args = args;
} else {
// normal argument list
- x.Y = P.ParseExpressionList();
+ call.Args = P.ParseExpressionList();
}
P.expr_lev--;
}
P.Expect(Scanner.RPAREN);
- P.Ecart();
- return x;
+ return call;
}
-func (P *Parser) ParseCompositeElements() *AST.Expr {
+func (P *Parser) ParseCompositeElements() AST.Expr {
x := P.ParseExpression(0);
if P.tok == Scanner.COMMA {
pos := P.pos;
@@ -952,29 +992,29 @@ func (P *Parser) ParseCompositeElements() *AST.Expr {
// first element determines mode
singles := true;
- if x.Tok == Scanner.COLON {
+ if t, is_binary := x.(*AST.BinaryExpr); is_binary && t.Tok == Scanner.COLON {
singles = false;
}
- var last *AST.Expr;
+ var last *AST.BinaryExpr;
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
y := P.ParseExpression(0);
if singles {
- if y.Tok == Scanner.COLON {
- P.Error(y.X.Pos, "single value expected; found pair");
+ if t, is_binary := y.(*AST.BinaryExpr); is_binary && t.Tok == Scanner.COLON {
+ P.Error(t.X.Pos(), "single value expected; found pair");
}
} else {
- if y.Tok != Scanner.COLON {
- P.Error(y.Pos, "key:value pair expected; found single value");
+ if t, is_binary := y.(*AST.BinaryExpr); !is_binary || t.Tok != Scanner.COLON {
+ P.Error(y.Pos(), "key:value pair expected; found single value");
}
}
if last == nil {
- x = P.NewExpr(pos, Scanner.COMMA, x, y);
- last = x;
+ last = P.NewBinary(pos, Scanner.COMMA, x, y);
+ x = last;
} else {
- last.Y = P.NewExpr(pos, Scanner.COMMA, last.Y, y);
+ last.Y = P.NewBinary(pos, Scanner.COMMA, last.Y, y);
last = last.Y;
}
@@ -991,25 +1031,29 @@ func (P *Parser) ParseCompositeElements() *AST.Expr {
}
-func (P *Parser) ParseCompositeLit(t *AST.Type) *AST.Expr {
- P.Trace("CompositeLit");
+func (P *Parser) ParseCompositeLit(t *AST.Type) AST.Expr {
+ if P.verbose {
+ P.Trace("CompositeLit");
+ defer P.Ecart();
+ }
- x := P.NewExpr(P.pos, Scanner.LBRACE, nil, nil);
- x.Obj = AST.NewObject(t.Pos, AST.TYPE, "");
- x.Obj.Typ = t;
+ pos := P.pos;
P.Expect(Scanner.LBRACE);
+ var elts AST.Expr;
if P.tok != Scanner.RBRACE {
- x.Y = P.ParseCompositeElements();
+ elts = P.ParseCompositeElements();
}
P.Expect(Scanner.RBRACE);
- P.Ecart();
- return x;
+ return &AST.CompositeLit{pos, t, elts};
}
-func (P *Parser) ParsePrimaryExpr() *AST.Expr {
- P.Trace("PrimaryExpr");
+func (P *Parser) ParsePrimaryExpr() AST.Expr {
+ if P.verbose {
+ P.Trace("PrimaryExpr");
+ defer P.Ecart();
+ }
x := P.ParseOperand();
for {
@@ -1028,47 +1072,48 @@ func (P *Parser) ParsePrimaryExpr() *AST.Expr {
if t != nil {
x = P.ParseCompositeLit(t);
} else {
- goto exit;
+ return x;
}
- default: goto exit;
+ default:
+ return x;
}
}
-exit:
- P.Ecart();
- return x;
+ unreachable();
+ return nil;
}
-func (P *Parser) ParseUnaryExpr() *AST.Expr {
- P.Trace("UnaryExpr");
+func (P *Parser) ParseUnaryExpr() AST.Expr {
+ if P.verbose {
+ P.Trace("UnaryExpr");
+ defer P.Ecart();
+ }
- x := AST.BadExpr;
switch P.tok {
case Scanner.ADD, Scanner.SUB, Scanner.MUL, Scanner.NOT, Scanner.XOR, Scanner.ARROW, Scanner.AND:
pos, tok := P.pos, P.tok;
P.Next();
y := P.ParseUnaryExpr();
- if tok == Scanner.MUL && y.Tok == Scanner.TYPE {
+ if lit, ok := y.(*AST.TypeLit); ok && tok == Scanner.MUL {
// pointer type
t := AST.NewType(pos, AST.POINTER);
- t.Elt = y.Obj.Typ;
- x = AST.NewTypeExpr(t);
+ t.Elt = lit.Typ;
+ return &AST.TypeLit{t};
} else {
- x = P.NewExpr(pos, tok, nil, y);
+ return &AST.UnaryExpr{pos, tok, y};
}
-
- default:
- x = P.ParsePrimaryExpr();
}
- P.Ecart();
- return x;
+ return P.ParsePrimaryExpr();
}
-func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
- P.Trace("BinaryExpr");
+func (P *Parser) ParseBinaryExpr(prec1 int) AST.Expr {
+ if P.verbose {
+ P.Trace("BinaryExpr");
+ defer P.Ecart();
+ }
x := P.ParseUnaryExpr();
for prec := Scanner.Precedence(P.tok); prec >= prec1; prec-- {
@@ -1076,28 +1121,29 @@ func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
pos, tok := P.pos, P.tok;
P.Next();
y := P.ParseBinaryExpr(prec + 1);
- x = P.NewExpr(pos, tok, x, y);
+ x = P.NewBinary(pos, tok, x, y);
}
}
- P.Ecart();
return x;
}
-func (P *Parser) ParseExpression(prec int) *AST.Expr {
- P.Trace("Expression");
- indent := P.indent;
+func (P *Parser) ParseExpression(prec int) AST.Expr {
+ if P.verbose {
+ P.Trace("Expression");
+ defer P.Ecart();
+ }
+ indent := P.indent;
if prec < 0 {
panic("precedence must be >= 0");
}
x := P.NoType(P.ParseBinaryExpr(prec));
-
if indent != P.indent {
panic("imbalanced tracing code (Expression)");
}
- P.Ecart();
+
return x;
}
@@ -1106,35 +1152,25 @@ func (P *Parser) ParseExpression(prec int) *AST.Expr {
// Statements
func (P *Parser) ParseSimpleStat(range_ok bool) *AST.Stat {
- P.Trace("SimpleStat");
+ if P.verbose {
+ P.Trace("SimpleStat");
+ defer P.Ecart();
+ }
s := AST.BadStat;
x := P.ParseExpressionList();
- is_range := false;
- if range_ok && P.tok == Scanner.COLON {
- pos := P.pos;
- P.Next();
- y := P.ParseExpression(1);
- if x.Len() == 1 {
- x = P.NewExpr(pos, Scanner.COLON, x, y);
- is_range = true;
- } else {
- P.Error(pos, "expected initialization, found ':'");
- }
- }
-
switch P.tok {
case Scanner.COLON:
// label declaration
s = AST.NewStat(P.pos, Scanner.COLON);
s.Expr = x;
- if x.Len() != 1 {
- P.Error(x.Pos, "illegal label declaration");
+ if AST.ExprLen(x) != 1 {
+ P.Error(x.Pos(), "illegal label declaration");
}
P.Next(); // consume ":"
P.opt_semi = true;
-
+
case
Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN,
Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN,
@@ -1143,34 +1179,31 @@ func (P *Parser) ParseSimpleStat(range_ok bool) *AST.Stat {
// declaration/assignment
pos, tok := P.pos, P.tok;
P.Next();
- y := AST.BadExpr;
+ var y AST.Expr = &AST.BadExpr{pos};
if P.tok == Scanner.RANGE {
range_pos := P.pos;
P.Next();
y = P.ParseExpression(1);
- y = P.NewExpr(range_pos, Scanner.RANGE, nil, y);
+ y = P.NewBinary(range_pos, Scanner.RANGE, nil, y);
if tok != Scanner.DEFINE && tok != Scanner.ASSIGN {
P.Error(pos, "expected '=' or ':=', found '" + Scanner.TokenString(tok) + "'");
}
} else {
y = P.ParseExpressionList();
- if is_range {
- P.Error(y.Pos, "expected 'range', found expression");
- }
- if xl, yl := x.Len(), y.Len(); xl > 1 && yl > 1 && xl != yl {
- P.Error(x.Pos, "arity of lhs doesn't match rhs");
+ if xl, yl := AST.ExprLen(x), AST.ExprLen(y); xl > 1 && yl > 1 && xl != yl {
+ P.Error(x.Pos(), "arity of lhs doesn't match rhs");
}
}
- s = AST.NewStat(x.Pos, Scanner.EXPRSTAT);
- s.Expr = AST.NewExpr(pos, tok, x, y);
-
+ s = AST.NewStat(x.Pos(), Scanner.EXPRSTAT);
+ s.Expr = P.NewBinary(pos, tok, x, y);
+
case Scanner.RANGE:
pos := P.pos;
P.Next();
y := P.ParseExpression(1);
- y = P.NewExpr(pos, Scanner.RANGE, nil, y);
- s = AST.NewStat(x.Pos, Scanner.EXPRSTAT);
- s.Expr = AST.NewExpr(pos, Scanner.DEFINE, x, y);
+ y = &AST.UnaryExpr{pos, Scanner.RANGE, y};
+ s = AST.NewStat(x.Pos(), Scanner.EXPRSTAT);
+ s.Expr = P.NewBinary(pos, Scanner.DEFINE, x, y);
default:
var pos, tok int;
@@ -1178,34 +1211,39 @@ func (P *Parser) ParseSimpleStat(range_ok bool) *AST.Stat {
pos, tok = P.pos, P.tok;
P.Next();
} else {
- pos, tok = x.Pos, Scanner.EXPRSTAT;
+ pos, tok = x.Pos(), Scanner.EXPRSTAT;
}
s = AST.NewStat(pos, tok);
s.Expr = x;
- if x.Len() != 1 {
- P.Error(x.Pos, "only one expression allowed");
+ if AST.ExprLen(x) != 1 {
+ P.Error(pos, "only one expression allowed");
+ panic(); // fix position
}
}
- P.Ecart();
return s;
}
func (P *Parser) ParseInvocationStat(keyword int) *AST.Stat {
- P.Trace("InvocationStat");
+ if P.verbose {
+ P.Trace("InvocationStat");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, keyword);
P.Expect(keyword);
s.Expr = P.ParseExpression(1);
- P.Ecart();
return s;
}
func (P *Parser) ParseReturnStat() *AST.Stat {
- P.Trace("ReturnStat");
+ if P.verbose {
+ P.Trace("ReturnStat");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, Scanner.RETURN);
P.Expect(Scanner.RETURN);
@@ -1213,13 +1251,15 @@ func (P *Parser) ParseReturnStat() *AST.Stat {
s.Expr = P.ParseExpressionList();
}
- P.Ecart();
return s;
}
func (P *Parser) ParseControlFlowStat(tok int) *AST.Stat {
- P.Trace("ControlFlowStat");
+ if P.verbose {
+ P.Trace("ControlFlowStat");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, tok);
P.Expect(tok);
@@ -1227,13 +1267,15 @@ func (P *Parser) ParseControlFlowStat(tok int) *AST.Stat {
s.Expr = P.ParseIdent(P.top_scope);
}
- P.Ecart();
return s;
}
func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
- P.Trace("ControlClause");
+ if P.verbose {
+ P.Trace("ControlClause");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, keyword);
P.Expect(keyword);
@@ -1263,13 +1305,15 @@ func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
P.expr_lev = prev_lev;
}
- P.Ecart();
return s;
}
func (P *Parser) ParseIfStat() *AST.Stat {
- P.Trace("IfStat");
+ if P.verbose {
+ P.Trace("IfStat");
+ defer P.Ecart();
+ }
P.OpenScope();
s := P.ParseControlClause(Scanner.IF);
@@ -1297,26 +1341,30 @@ func (P *Parser) ParseIfStat() *AST.Stat {
}
P.CloseScope();
- P.Ecart();
return s;
}
func (P *Parser) ParseForStat() *AST.Stat {
- P.Trace("ForStat");
+ if P.verbose {
+ P.Trace("ForStat");
+ defer P.Ecart();
+ }
P.OpenScope();
s := P.ParseControlClause(Scanner.FOR);
s.Body = P.ParseBlock(nil, Scanner.LBRACE);
P.CloseScope();
- P.Ecart();
return s;
}
func (P *Parser) ParseSwitchCase() *AST.Stat {
- P.Trace("SwitchCase");
+ if P.verbose {
+ P.Trace("SwitchCase");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, P.tok);
if P.tok == Scanner.CASE {
@@ -1326,24 +1374,28 @@ func (P *Parser) ParseSwitchCase() *AST.Stat {
P.Expect(Scanner.DEFAULT);
}
- P.Ecart();
return s;
}
func (P *Parser) ParseCaseClause() *AST.Stat {
- P.Trace("CaseClause");
+ if P.verbose {
+ P.Trace("CaseClause");
+ defer P.Ecart();
+ }
s := P.ParseSwitchCase();
s.Body = P.ParseBlock(nil, Scanner.COLON);
- P.Ecart();
return s;
}
func (P *Parser) ParseSwitchStat() *AST.Stat {
- P.Trace("SwitchStat");
+ if P.verbose {
+ P.Trace("SwitchStat");
+ defer P.Ecart();
+ }
P.OpenScope();
s := P.ParseControlClause(Scanner.SWITCH);
@@ -1358,13 +1410,15 @@ func (P *Parser) ParseSwitchStat() *AST.Stat {
P.CloseScope();
s.Body = b;
- P.Ecart();
return s;
}
func (P *Parser) ParseCommCase() *AST.Stat {
- P.Trace("CommCase");
+ if P.verbose {
+ P.Trace("CommCase");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, P.tok);
if P.tok == Scanner.CASE {
@@ -1375,7 +1429,7 @@ func (P *Parser) ParseCommCase() *AST.Stat {
P.Next();
if P.tok == Scanner.ARROW {
y := P.ParseExpression(1);
- x = AST.NewExpr(pos, tok, x, y);
+ x = P.NewBinary(pos, tok, x, y);
} else {
P.Expect(Scanner.ARROW); // use Expect() error handling
}
@@ -1385,24 +1439,28 @@ func (P *Parser) ParseCommCase() *AST.Stat {
P.Expect(Scanner.DEFAULT);
}
- P.Ecart();
return s;
}
func (P *Parser) ParseCommClause() *AST.Stat {
- P.Trace("CommClause");
+ if P.verbose {
+ P.Trace("CommClause");
+ defer P.Ecart();
+ }
s := P.ParseCommCase();
s.Body = P.ParseBlock(nil, Scanner.COLON);
- P.Ecart();
return s;
}
func (P *Parser) ParseSelectStat() *AST.Stat {
- P.Trace("SelectStat");
+ if P.verbose {
+ P.Trace("SelectStat");
+ defer P.Ecart();
+ }
s := AST.NewStat(P.pos, Scanner.SELECT);
P.Expect(Scanner.SELECT);
@@ -1416,13 +1474,15 @@ func (P *Parser) ParseSelectStat() *AST.Stat {
P.opt_semi = true;
s.Body = b;
- P.Ecart();
return s;
}
func (P *Parser) ParseStatement() *AST.Stat {
- P.Trace("Statement");
+ if P.verbose {
+ P.Trace("Statement");
+ defer P.Ecart();
+ }
indent := P.indent;
s := AST.BadStat;
@@ -1465,7 +1525,6 @@ func (P *Parser) ParseStatement() *AST.Stat {
if indent != P.indent {
panic("imbalanced tracing code (Statement)");
}
- P.Ecart();
return s;
}
@@ -1474,7 +1533,10 @@ func (P *Parser) ParseStatement() *AST.Stat {
// Declarations
func (P *Parser) ParseImportSpec(d *AST.Decl) {
- P.Trace("ImportSpec");
+ if P.verbose {
+ P.Trace("ImportSpec");
+ defer P.Ecart();
+ }
if P.tok == Scanner.PERIOD {
P.Error(P.pos, `"import ." not yet handled properly`);
@@ -1485,19 +1547,19 @@ func (P *Parser) ParseImportSpec(d *AST.Decl) {
if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
- val := AST.NewObject(P.pos, AST.NONE, P.val);
- d.Val = AST.NewLit(Scanner.STRING, val);
+ d.Val = &AST.BasicLit{P.pos, Scanner.STRING, P.val};
P.Next();
} else {
P.Expect(Scanner.STRING); // use Expect() error handling
}
-
- P.Ecart();
}
func (P *Parser) ParseConstSpec(d *AST.Decl) {
- P.Trace("ConstSpec");
+ if P.verbose {
+ P.Trace("ConstSpec");
+ defer P.Ecart();
+ }
d.Ident = P.ParseIdentList();
d.Typ = P.TryType();
@@ -1505,24 +1567,26 @@ func (P *Parser) ParseConstSpec(d *AST.Decl) {
P.Next();
d.Val = P.ParseExpressionList();
}
-
- P.Ecart();
}
func (P *Parser) ParseTypeSpec(d *AST.Decl) {
- P.Trace("TypeSpec");
+ if P.verbose {
+ P.Trace("TypeSpec");
+ defer P.Ecart();
+ }
d.Ident = P.ParseIdent(nil);
d.Typ = P.ParseType();
P.opt_semi = true;
-
- P.Ecart();
}
func (P *Parser) ParseVarSpec(d *AST.Decl) {
- P.Trace("VarSpec");
+ if P.verbose {
+ P.Trace("VarSpec");
+ defer P.Ecart();
+ }
d.Ident = P.ParseIdentList();
if P.tok == Scanner.ASSIGN {
@@ -1535,8 +1599,6 @@ func (P *Parser) ParseVarSpec(d *AST.Decl) {
d.Val = P.ParseExpressionList();
}
}
-
- P.Ecart();
}
@@ -1560,17 +1622,17 @@ func (P *Parser) ParseSpec(d *AST.Decl) {
P.Declare(d.Ident, kind, d.Typ);
if d.Val != nil {
// initialization/assignment
- llen := d.Ident.Len();
- rlen := d.Val.Len();
+ llen := AST.ExprLen(d.Ident);
+ rlen := AST.ExprLen(d.Val);
if llen == rlen {
// TODO
} else if rlen == 1 {
// TODO
} else {
if llen < rlen {
- P.Error(d.Val.At(llen).Pos, "more expressions than variables");
+ P.Error(AST.ExprAt(d.Val, llen).Pos(), "more expressions than variables");
} else {
- P.Error(d.Ident.At(rlen).Pos, "more variables than expressions");
+ P.Error(AST.ExprAt(d.Ident, rlen).Pos(), "more variables than expressions");
}
}
} else {
@@ -1581,7 +1643,10 @@ func (P *Parser) ParseSpec(d *AST.Decl) {
func (P *Parser) ParseDecl(keyword int) *AST.Decl {
- P.Trace("Decl");
+ if P.verbose {
+ P.Trace("Decl");
+ defer P.Ecart();
+ }
d := AST.NewDecl(P.pos, keyword);
P.Expect(keyword);
@@ -1606,7 +1671,6 @@ func (P *Parser) ParseDecl(keyword int) *AST.Decl {
P.ParseSpec(d);
}
- P.Ecart();
return d;
}
@@ -1621,7 +1685,10 @@ func (P *Parser) ParseDecl(keyword int) *AST.Decl {
// func (recv) ident (params) (results)
func (P *Parser) ParseFunctionDecl() *AST.Decl {
- P.Trace("FunctionDecl");
+ if P.verbose {
+ P.Trace("FunctionDecl");
+ defer P.Ecart();
+ }
d := AST.NewDecl(P.pos, Scanner.FUNC);
P.Expect(Scanner.FUNC);
@@ -1635,24 +1702,24 @@ func (P *Parser) ParseFunctionDecl() *AST.Decl {
}
}
- d.Ident = P.ParseIdent(nil);
+ ident := P.ParseIdent(nil);
+ d.Ident = ident;
d.Typ = P.ParseSignature();
d.Typ.Key = recv;
if P.tok == Scanner.LBRACE {
- f := AST.NewObject(d.Pos, AST.FUNC, d.Ident.Obj.Ident);
- f.Typ = d.Typ;
- f.Body = P.ParseBlock(d.Typ, Scanner.LBRACE);
- d.Val = AST.NewLit(Scanner.FUNC, f);
+ d.Body = P.ParseBlock(d.Typ, Scanner.LBRACE);
}
- P.Ecart();
return d;
}
func (P *Parser) ParseDeclaration() *AST.Decl {
- P.Trace("Declaration");
+ if P.verbose {
+ P.Trace("Declaration");
+ defer P.Ecart();
+ }
indent := P.indent;
d := AST.BadDecl;
@@ -1670,7 +1737,6 @@ func (P *Parser) ParseDeclaration() *AST.Decl {
if indent != P.indent {
panic("imbalanced tracing code (Declaration)");
}
- P.Ecart();
return d;
}
@@ -1679,7 +1745,10 @@ func (P *Parser) ParseDeclaration() *AST.Decl {
// Program
func (P *Parser) ParseProgram() *AST.Program {
- P.Trace("Program");
+ if P.verbose {
+ P.Trace("Program");
+ defer P.Ecart();
+ }
P.OpenScope();
p := AST.NewProgram(P.pos);
@@ -1705,6 +1774,5 @@ func (P *Parser) ParseProgram() *AST.Program {
p.Comments = P.comments;
P.CloseScope();
- P.Ecart();
return p;
}