]> Cypherpunks repositories - gostls13.git/commitdiff
adjustments matching updated ast
authorRobert Griesemer <gri@golang.org>
Wed, 25 Mar 2009 19:45:06 +0000 (12:45 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 25 Mar 2009 19:45:06 +0000 (12:45 -0700)
R=r
OCL=26746
CL=26746

usr/gri/pretty/parser.go
usr/gri/pretty/printer.go

index 5c13e59987f4914b7aa5ab9dfc97c062e38a4ced..d8984a97be0cff8d9d331fd86528836656c4f2ab 100644 (file)
@@ -219,7 +219,7 @@ func (P *Parser) getDoc() ast.Comments {
 
 func (P *Parser) tryType() ast.Expr;
 func (P *Parser) parseExpression(prec int) ast.Expr;
-func (P *Parser) parseStatement() ast.Stat;
+func (P *Parser) parseStatement() ast.Stmt;
 func (P *Parser) parseDeclaration() ast.Decl;
 
 
@@ -489,18 +489,18 @@ func (P *Parser) parseResult() []*ast.Field {
                defer un(trace(P, "Result"));
        }
 
-       var result []*ast.Field;
+       var results []*ast.Field;
        if P.tok == token.LPAREN {
-               result = P.parseParameters(false);
+               results = P.parseParameters(false);
        } else if P.tok != token.FUNC {
                typ := P.tryType();
                if typ != nil {
-                       result = make([]*ast.Field, 1);
-                       result[0] = &ast.Field{nil, nil, typ, nil};
+                       results = make([]*ast.Field, 1);
+                       results[0] = &ast.Field{nil, nil, typ, nil};
                }
        }
 
-       return result;
+       return results;
 }
 
 
@@ -510,16 +510,15 @@ func (P *Parser) parseResult() []*ast.Field {
 // (params) type
 // (params) (results)
 
-func (P *Parser) parseSignature() *ast.Signature {
+func (P *Parser) parseSignature() (params []*ast.Field, results []*ast.Field) {
        if P.trace {
                defer un(trace(P, "Signature"));
        }
 
-       params := P.parseParameters(true);  // TODO find better solution
-       //t.End = P.pos;
-       result := P.parseResult();
+       params = P.parseParameters(true);  // TODO find better solution
+       results = P.parseResult();
 
-       return &ast.Signature{params, result};
+       return params, results;
 }
 
 
@@ -529,9 +528,9 @@ func (P *Parser) parseFunctionType() *ast.FunctionType {
        }
 
        pos := P.expect(token.FUNC);
-       sig := P.parseSignature();
+       params, results := P.parseSignature();
 
-       return &ast.FunctionType{pos, sig};
+       return &ast.FunctionType{pos, params, results};
 }
 
 
@@ -547,7 +546,8 @@ func (P *Parser) parseMethodSpec() *ast.Field {
        if tmp, is_ident := x.(*ast.Ident); is_ident && (P.tok == token.COMMA || P.tok == token.LPAREN) {
                // method(s)
                idents = P.parseIdentList(x);
-               typ = &ast.FunctionType{nopos, P.parseSignature()};
+               params, results := P.parseSignature();
+               typ = &ast.FunctionType{nopos, params, results};
        } else {
                // embedded interface
                typ = x;
@@ -606,7 +606,7 @@ func (P *Parser) parseMapType() *ast.MapType {
 }
 
 
-func (P *Parser) parseStringLit(x *ast.BasicLit) *ast.StringLit
+func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit
 
 func (P *Parser) parseFieldDecl() *ast.Field {
        if P.trace {
@@ -631,9 +631,9 @@ func (P *Parser) parseFieldDecl() *ast.Field {
        typ := P.tryType();
 
        // optional tag
-       var tag ast.Expr;
+       var tag []*ast.StringLit;
        if P.tok == token.STRING {
-               tag = P.parseStringLit(nil);
+               tag = P.parseStringList(nil);
        }
 
        // analyze case
@@ -743,16 +743,16 @@ func (P *Parser) tryType() ast.Expr {
 // ----------------------------------------------------------------------------
 // Blocks
 
-func asStatList(list *vector.Vector) []ast.Stat {
-       stats := make([]ast.Stat, list.Len());
+func asStmtList(list *vector.Vector) []ast.Stmt {
+       stats := make([]ast.Stmt, list.Len());
        for i := 0; i < list.Len(); i++ {
-               stats[i] = list.At(i).(ast.Stat);
+               stats[i] = list.At(i).(ast.Stmt);
        }
        return stats;
 }
 
 
-func (P *Parser) parseStatementList() []ast.Stat {
+func (P *Parser) parseStatementList() []ast.Stmt {
        if P.trace {
                defer un(trace(P, "StatementList"));
        }
@@ -774,24 +774,21 @@ func (P *Parser) parseStatementList() []ast.Stat {
                }
        }
        
-       return asStatList(list);
+       return asStmtList(list);
 }
 
 
-func (P *Parser) parseBlock(tok int) *ast.Block {
+func (P *Parser) parseBlockStmt() *ast.BlockStmt {
        if P.trace {
-               defer un(trace(P, "Block"));
+               defer un(trace(P, "compositeStmt"));
        }
 
-       pos := P.expect(tok);
+       lbrace := P.expect(token.LBRACE);
        list := P.parseStatementList();
-       var end scanner.Location;
-       if tok == token.LBRACE {
-               end = P.expect(token.RBRACE);
-               P.opt_semi = true;
-       }
+       rbrace := P.expect(token.RBRACE);
+       P.opt_semi = true;
 
-       return &ast.Block{pos, tok, list, end};
+       return &ast.BlockStmt{lbrace, list, rbrace};
 }
 
 
@@ -803,19 +800,18 @@ func (P *Parser) parseFunctionLit() ast.Expr {
                defer un(trace(P, "FunctionLit"));
        }
 
-       pos := P.expect(token.FUNC);
-       typ := P.parseSignature();
+       typ := P.parseFunctionType();
        P.expr_lev++;
-       body := P.parseBlock(token.LBRACE);
+       body := P.parseBlockStmt();
        P.expr_lev--;
 
-       return &ast.FunctionLit{pos, typ, body};
+       return &ast.FunctionLit{typ, body};
 }
 
 
-func (P *Parser) parseStringLit(x *ast.BasicLit) *ast.StringLit {
+func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit {
        if P.trace {
-               defer un(trace(P, "StringLit"));
+               defer un(trace(P, "StringList"));
        }
 
        list := vector.New(0);
@@ -824,17 +820,17 @@ func (P *Parser) parseStringLit(x *ast.BasicLit) *ast.StringLit {
        }
        
        for P.tok == token.STRING {
-               list.Push(&ast.BasicLit{P.pos, token.STRING, P.val});
+               list.Push(&ast.StringLit{P.pos, P.val});
                P.next();
        }
 
        // convert list
-       strings := make([]*ast.BasicLit, list.Len());
+       strings := make([]*ast.StringLit, list.Len());
        for i := 0; i < list.Len(); i++ {
-               strings[i] = list.At(i).(*ast.BasicLit);
+               strings[i] = list.At(i).(*ast.StringLit);
        }
        
-       return &ast.StringLit{strings};
+       return strings;
 }
 
 
@@ -847,16 +843,26 @@ func (P *Parser) parseOperand() ast.Expr {
        case token.IDENT:
                return P.parseIdent();
 
-       case token.INT, token.FLOAT, token.CHAR:
-               x := &ast.BasicLit{P.pos, P.tok, P.val};
+       case token.INT:
+               x := &ast.IntLit{P.pos, P.val};
+               P.next();
+               return x;
+
+       case token.FLOAT:
+               x := &ast.FloatLit{P.pos, P.val};
+               P.next();
+               return x;
+
+       case token.CHAR:
+               x := &ast.CharLit{P.pos, P.val};
                P.next();
                return x;
 
        case token.STRING:
-               x := &ast.BasicLit{P.pos, token.STRING, P.val};
+               x := &ast.StringLit{P.pos, P.val};
                P.next();
                if P.tok == token.STRING {
-                       return P.parseStringLit(x);
+                       return &ast.StringList{P.parseStringList(x)};
                }
                return x;
 
@@ -1106,9 +1112,9 @@ func (P *Parser) parseExpression(prec int) ast.Expr {
 // Statements
 
 
-func (P *Parser) parseSimpleStat() ast.Stat {
+func (P *Parser) parseSimpleStmt() ast.Stmt {
        if P.trace {
-               defer un(trace(P, "SimpleStat"));
+               defer un(trace(P, "SimpleStmt"));
        }
 
        x := P.parseExpressionList();
@@ -1119,86 +1125,85 @@ func (P *Parser) parseSimpleStat() ast.Stat {
                P.expect(token.COLON);
                if len(x) == 1 {
                        if label, is_ident := x[0].(*ast.Ident); is_ident {
-                               return &ast.LabeledStat{label, P.parseStatement()};
+                               return &ast.LabeledStmt{label, P.parseStatement()};
                        }
                }
                P.error(x[0].Pos(), "illegal label declaration");
-               return nil;
+               return &ast.BadStmt{x[0].Pos()};
 
        case
                token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
                token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
                token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
                token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN:
-               // assignment statement or range clause
+               // assignment statement
                pos, tok := P.pos, P.tok;
                P.next();
-               /*
-               if mode & range_ok != 0 && P.tok == token.RANGE {
-                       // range clause
-                       P.next();
-                       if len(x) != 1 && len(x) != 2 {
-                               P.error(x[0].Pos(), "expected 1 or 2 expressions on lhs of range clause");
-                       }
-                       if tok != token.DEFINE && tok != token.ASSIGN {
-                               P.error(pos, "expected '=' or ':=', found '" + token.TokenString(tok) + "'");
-                       }
-                       y := P.parseExpression(1);
-                       return &ast.RangeClause{x, pos, tok, y};
-               } else {
-               */
-               // assignment statement
                y := P.parseExpressionList();
-               xl, yl := len(x), len(y);
-               if xl > 1 && yl > 1 && xl != yl {
-                       P.error(x[0].Pos(), "arity of lhs doesn't match rhs");  // TODO use better loc for error
-               }
-               return &ast.AssignmentStat{x, pos, tok, y};
-
-       default:
-               if len(x) > 1 {
-                       P.error(x[0].Pos(), "only one expression allowed");
+               if len(x) > 1 && len(y) > 1 && len(x) != len(y) {
+                       P.error(x[0].Pos(), "arity of lhs doesn't match rhs");
                }
+               return &ast.AssignStmt{x, pos, tok, y};
+       }
 
-               if P.tok == token.INC || P.tok == token.DEC {
-                       s := &ast.IncDecStat{x[0], P.tok};
-                       P.next();  // consume "++" or "--"
-                       return s;
-               }
+       if len(x) > 1 {
+               P.error(x[0].Pos(), "only one expression allowed");
+               // continue with first expression
+       }
 
-               return &ast.ExprStat{x[0]};
+       if P.tok == token.INC || P.tok == token.DEC {
+               // increment or decrement
+               s := &ast.IncDecStmt{x[0], P.tok};
+               P.next();  // consume "++" or "--"
+               return s;
        }
 
-       unreachable();
+       // expression
+       return &ast.ExprStmt{x[0]};
+}
+
+
+func (P *Parser) parseCallExpr() *ast.CallExpr {
+       x := P.parseExpression(1);
+       if call, is_call := x.(*ast.CallExpr); is_call {
+               return call;
+       }
+       P.error(x.Pos(), "expected function/method call");
        return nil;
 }
 
 
-func (P *Parser) parseGoStat() *ast.GoStat {
+func (P *Parser) parseGoStmt() ast.Stmt {
        if P.trace {
-               defer un(trace(P, "GoStat"));
+               defer un(trace(P, "GoStmt"));
        }
 
        pos := P.expect(token.GO);
-       call := P.parseExpression(1);
-       return &ast.GoStat{pos, call};
+       call := P.parseCallExpr();
+       if call != nil {
+               return &ast.GoStmt{pos, call};
+       }
+       return &ast.BadStmt{pos};
 }
 
 
-func (P *Parser) parseDeferStat() *ast.DeferStat {
+func (P *Parser) parseDeferStmt() ast.Stmt {
        if P.trace {
-               defer un(trace(P, "DeferStat"));
+               defer un(trace(P, "DeferStmt"));
        }
 
        pos := P.expect(token.DEFER);
-       call := P.parseExpression(1);
-       return &ast.DeferStat{pos, call};
+       call := P.parseCallExpr();
+       if call != nil {
+               return &ast.DeferStmt{pos, call};
+       }
+       return &ast.BadStmt{pos};
 }
 
 
-func (P *Parser) parseReturnStat() *ast.ReturnStat {
+func (P *Parser) parseReturnStmt() *ast.ReturnStmt {
        if P.trace {
-               defer un(trace(P, "ReturnStat"));
+               defer un(trace(P, "ReturnStmt"));
        }
 
        loc := P.pos;
@@ -1208,16 +1213,16 @@ func (P *Parser) parseReturnStat() *ast.ReturnStat {
                x = P.parseExpressionList();
        }
 
-       return &ast.ReturnStat{loc, x};
+       return &ast.ReturnStmt{loc, x};
 }
 
 
-func (P *Parser) parseControlFlowStat(tok int) *ast.ControlFlowStat {
+func (P *Parser) parseBranchStmt(tok int) *ast.BranchStmt {
        if P.trace {
-               defer un(trace(P, "ControlFlowStat"));
+               defer un(trace(P, "BranchStmt"));
        }
 
-       s := &ast.ControlFlowStat{P.pos, tok, nil};
+       s := &ast.BranchStmt{P.pos, tok, nil};
        P.expect(tok);
        if tok != token.FALLTHROUGH && P.tok == token.IDENT {
                s.Label = P.parseIdent();
@@ -1227,33 +1232,28 @@ func (P *Parser) parseControlFlowStat(tok int) *ast.ControlFlowStat {
 }
 
 
-/*
-func (P *Parser) asIdent(x ast.Expr) *ast.Ident {
-       if name, ok := x.(*ast.Ident); ok {
-               return name;
+func (P *Parser) isExpr(s ast.Stmt) bool {
+       if s == nil {
+               return true;
        }
-       P.error(x.Pos(), "identifier expected");
-       return &ast.Ident{x.Pos(), [...]byte{'B', 'A', 'D'}};
+       dummy, is_expr := s.(*ast.ExprStmt);
+       return is_expr;
 }
 
 
-func (P *Parser) isTypeSwitch(init ast.Stat) (lhs *ast.Ident, rhs ast.Expr) {
-       if assign, ok := init.(*ast.AssignmentStat); ok {
-               if guard, ok := assign.Rhs.(*ast.TypeAssertion); ok {
-                       if tmp, ok := guard.Typ.(*ast.TypeType); ok {
-                               // we appear to have a type switch
-                               // TODO various error checks
-                               return P.asIdent(assign.Lhs), guard.X;
-                       }
-               }
+func (P *Parser) asExpr(s ast.Stmt) ast.Expr {
+       if s == nil {
+               return nil;
+       }
+       if es, is_expr := s.(*ast.ExprStmt); is_expr {
+               return es.X;
        }
-       return nil, nil;
+       P.error(s.Pos(), "condition expected; found simple statement");
+       return &ast.BadExpr{s.Pos()};
 }
-*/
 
 
-
-func (P *Parser) parseControlClause(isForStat bool) (s1, s2, s3 ast.Stat) {
+func (P *Parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) {
        if P.trace {
                defer un(trace(P, "ControlClause"));
        }
@@ -1263,18 +1263,18 @@ func (P *Parser) parseControlClause(isForStat bool) (s1, s2, s3 ast.Stat) {
                P.expr_lev = -1;
 
                if P.tok != token.SEMICOLON {
-                       s1 = P.parseSimpleStat();
+                       s1 = P.parseSimpleStmt();
                }
                if P.tok == token.SEMICOLON {
                        P.next();
                        if P.tok != token.LBRACE && P.tok != token.SEMICOLON {
-                               s2 = P.parseSimpleStat();
+                               s2 = P.parseSimpleStmt();
                        }
-                       if isForStat {
+                       if isForStmt {
                                // for statements have a 3rd section
                                P.expect(token.SEMICOLON);
                                if P.tok != token.LBRACE {
-                                       s3 = P.parseSimpleStat();
+                                       s3 = P.parseSimpleStmt();
                                }
                        }
                } else {
@@ -1288,42 +1288,21 @@ func (P *Parser) parseControlClause(isForStat bool) (s1, s2, s3 ast.Stat) {
 }
 
 
-func (P *Parser) isExpr(s ast.Stat) bool {
-       if s == nil {
-               return true;
-       }
-       dummy, is_expr := s.(*ast.ExprStat);
-       return is_expr;
-}
-
-
-func (P *Parser) asExpr(s ast.Stat) ast.Expr {
-       if s == nil {
-               return nil;
-       }
-       if es, is_expr := s.(*ast.ExprStat); is_expr {
-               return es.X;
-       }
-       P.error(s.Pos(), "condition expected; found simple statement");
-       return &ast.BadExpr{s.Pos()};
-}
-
-
-func (P *Parser) parseIfStat() *ast.IfStat {
+func (P *Parser) parseIfStmt() *ast.IfStmt {
        if P.trace {
-               defer un(trace(P, "IfStat"));
+               defer un(trace(P, "IfStmt"));
        }
 
        pos := P.expect(token.IF);
        s1, s2, dummy := P.parseControlClause(false);
-       body := P.parseBlock(token.LBRACE);
-       var else_ ast.Stat;
+       body := P.parseBlockStmt();
+       var else_ ast.Stmt;
        if P.tok == token.ELSE {
                P.next();
                else_ = P.parseStatement();
        }
 
-       return &ast.IfStat{pos, s1, P.asExpr(s2), body, else_};
+       return &ast.IfStmt{pos, s1, P.asExpr(s2), body, else_};
 }
 
 
@@ -1341,8 +1320,11 @@ func (P *Parser) parseCaseClause() *ast.CaseClause {
        } else {
                P.expect(token.DEFAULT);
        }
+       
+       colon := P.expect(token.COLON);
+       body := P.parseStatementList();
 
-       return &ast.CaseClause{loc, x, P.parseBlock(token.COLON)};
+       return &ast.CaseClause{loc, x, colon, body};
 }
 
 
@@ -1361,13 +1343,16 @@ func (P *Parser) parseTypeCaseClause() *ast.TypeCaseClause {
                P.expect(token.DEFAULT);
        }
 
-       return &ast.TypeCaseClause{pos, typ, P.parseBlock(token.COLON)};
+       colon := P.expect(token.COLON);
+       body := P.parseStatementList();
+
+       return &ast.TypeCaseClause{pos, typ, colon, body};
 }
 
 
-func (P *Parser) parseSwitchStat() ast.Stat {
+func (P *Parser) parseSwitchStmt() ast.Stmt {
        if P.trace {
-               defer un(trace(P, "SwitchStat"));
+               defer un(trace(P, "SwitchStmt"));
        }
 
        pos := P.expect(token.SWITCH);
@@ -1382,8 +1367,8 @@ func (P *Parser) parseSwitchStat() ast.Stat {
                }
                rbrace := P.expect(token.RBRACE);
                P.opt_semi = true;
-               body := &ast.Block{lbrace, token.LBRACE, asStatList(cases), rbrace};
-               return &ast.SwitchStat{pos, s1, P.asExpr(s2), body};
+               body := &ast.BlockStmt{lbrace, asStmtList(cases), rbrace};
+               return &ast.SwitchStmt{pos, s1, P.asExpr(s2), body};
 
        } else {
                // type switch
@@ -1395,8 +1380,8 @@ func (P *Parser) parseSwitchStat() ast.Stat {
                }
                rbrace := P.expect(token.RBRACE);
                P.opt_semi = true;
-               body := &ast.Block{lbrace, token.LBRACE, asStatList(cases), rbrace};
-               return &ast.TypeSwitchStat{pos, s1, s2, body};
+               body := &ast.BlockStmt{lbrace, asStmtList(cases), rbrace};
+               return &ast.TypeSwitchStmt{pos, s1, s2, body};
        }
 
        unreachable();
@@ -1438,13 +1423,16 @@ func (P *Parser) parseCommClause() *ast.CommClause {
                P.expect(token.DEFAULT);
        }
 
-       return &ast.CommClause{loc, tok, lhs, rhs, P.parseBlock(token.COLON)};
+       colon := P.expect(token.COLON);
+       body := P.parseStatementList();
+
+       return &ast.CommClause{loc, tok, lhs, rhs, colon, body};
 }
 
 
-func (P *Parser) parseSelectStat() *ast.SelectStat {
+func (P *Parser) parseSelectStmt() *ast.SelectStmt {
        if P.trace {
-               defer un(trace(P, "SelectStat"));
+               defer un(trace(P, "SelectStmt"));
        }
 
        pos := P.expect(token.SELECT);
@@ -1455,28 +1443,54 @@ func (P *Parser) parseSelectStat() *ast.SelectStat {
        }
        rbrace := P.expect(token.RBRACE);
        P.opt_semi = true;
-       body := &ast.Block{lbrace, token.LBRACE, asStatList(cases), rbrace};
+       body := &ast.BlockStmt{lbrace, asStmtList(cases), rbrace};
 
-       return &ast.SelectStat{pos, body};
+       return &ast.SelectStmt{pos, body};
 }
 
 
-func (P *Parser) parseForStat() ast.Stat {
+func (P *Parser) parseForStmt() ast.Stmt {
        if P.trace {
-               defer un(trace(P, "ForStat"));
+               defer un(trace(P, "ForStmt"));
        }
 
        pos := P.expect(token.FOR);
        s1, s2, s3 := P.parseControlClause(true);
-       body := P.parseBlock(token.LBRACE);
+       body := P.parseBlockStmt();
 
-       if as, is_as := s2.(*ast.AssignmentStat); is_as {
-               // probably a for statement with a range clause
-               // TODO do all the checks!
-               return &ast.RangeStat{pos, s2, body};
+       if as, is_as := s2.(*ast.AssignStmt); is_as {
+               // possibly a for statement with a range clause; check assignment operator
+               if as.Tok != token.ASSIGN && as.Tok != token.DEFINE {
+                       P.error(as.Pos_, "'=' or ':=' expected");
+                       return &ast.BadStmt{pos};
+               }
+               // check lhs
+               var key, value ast.Expr;
+               switch len(as.Lhs) {
+               case 2:
+                       value = as.Lhs[1];
+                       fallthrough;
+               case 1:
+                       key = as.Lhs[0];
+               default:
+                       P.error(as.Lhs[0].Pos(), "expected 1 or 2 expressions");
+                       return &ast.BadStmt{pos};
+               }
+               // check rhs
+               if len(as.Rhs) != 1 {
+                       P.error(as.Rhs[0].Pos(), "expected 1 expressions");
+                       return &ast.BadStmt{pos};
+               }
+               if rhs, is_unary := as.Rhs[0].(*ast.UnaryExpr); is_unary && rhs.Tok == token.RANGE {
+                       // rhs is range expression; check lhs
+                       return &ast.RangeStmt{pos, key, value, as.Pos_, as.Tok, rhs.X, body}
+               } else {
+                       P.error(s2.Pos(), "range clause expected");
+                       return &ast.BadStmt{pos};
+               }
        } else {
                // regular for statement
-               return &ast.ForStat{pos, s1, P.asExpr(s2), s3, body};
+               return &ast.ForStmt{pos, s1, P.asExpr(s2), s3, body};
        }
        
        unreachable();
@@ -1484,46 +1498,46 @@ func (P *Parser) parseForStat() ast.Stat {
 }
 
 
-func (P *Parser) parseStatement() ast.Stat {
+func (P *Parser) parseStatement() ast.Stmt {
        if P.trace {
                defer un(trace(P, "Statement"));
        }
 
        switch P.tok {
        case token.CONST, token.TYPE, token.VAR:
-               return &ast.DeclStat{P.parseDeclaration()};
+               return &ast.DeclStmt{P.parseDeclaration()};
        case
                // tokens that may start a top-level expression
                token.IDENT, token.INT, token.FLOAT, token.CHAR, token.STRING, token.FUNC, token.LPAREN,  // operand
                token.LBRACK, token.STRUCT,  // composite type
                token.MUL, token.AND, token.ARROW:  // unary operators
-               return P.parseSimpleStat();
+               return P.parseSimpleStmt();
        case token.GO:
-               return P.parseGoStat();
+               return P.parseGoStmt();
        case token.DEFER:
-               return P.parseDeferStat();
+               return P.parseDeferStmt();
        case token.RETURN:
-               return P.parseReturnStat();
+               return P.parseReturnStmt();
        case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
-               return P.parseControlFlowStat(P.tok);
+               return P.parseBranchStmt(P.tok);
        case token.LBRACE:
-               return &ast.CompositeStat{P.parseBlock(token.LBRACE)};
+               return P.parseBlockStmt();
        case token.IF:
-               return P.parseIfStat();
+               return P.parseIfStmt();
        case token.FOR:
-               return P.parseForStat();
+               return P.parseForStmt();
        case token.SWITCH:
-               return P.parseSwitchStat();
+               return P.parseSwitchStmt();
        case token.SELECT:
-               return P.parseSelectStat();
+               return P.parseSelectStmt();
        case token.SEMICOLON, token.RBRACE:
                // don't consume the ";", it is the separator following the empty statement
-               return &ast.EmptyStat{P.pos};
+               return &ast.EmptyStmt{P.pos};
        }
 
        // no statement found
        P.error(P.pos, "statement expected");
-       return &ast.BadStat{P.pos};
+       return &ast.BadStmt{P.pos};
 }
 
 
@@ -1543,9 +1557,9 @@ func (P *Parser) parseImportSpec(pos Position, doc ast.Comments) *ast.ImportDecl
                ident = P.parseIdent();
        }
 
-       var path *ast.StringLit;
+       var path []*ast.StringLit;
        if P.tok == token.STRING {
-               path = P.parseStringLit(nil);
+               path = P.parseStringList(nil);
        } else {
                P.expect(token.STRING);  // use expect() error handling
        }
@@ -1677,14 +1691,14 @@ func (P *Parser) parseFunctionDecl() *ast.FuncDecl {
        }
 
        ident := P.parseIdent();
-       sig := P.parseSignature();
+       params, results := P.parseSignature();
 
-       var body *ast.Block;
+       var body *ast.BlockStmt;
        if P.tok == token.LBRACE {
-               body = P.parseBlock(token.LBRACE);
+               body = P.parseBlockStmt();
        }
 
-       return &ast.FuncDecl{doc, pos, recv, ident, sig, body};
+       return &ast.FuncDecl{doc, recv, ident, &ast.FunctionType{pos, params, results}, body};
 }
 
 
index 49f77386fbcba00d93d20ff45f1686387f51931b..a7f823c4b536159e83a09ba09e83b73d6664f7ed 100644 (file)
@@ -486,7 +486,7 @@ func (P *Printer) Parameters(list []*ast.Field) {
                        if n > 0 {
                                P.separator = blank
                        };
-                       P.Expr(par.Typ);
+                       P.Expr(par.Type);
                }
        }
        P.Token(nopos, token.RPAREN);
@@ -495,22 +495,22 @@ func (P *Printer) Parameters(list []*ast.Field) {
 
 // Returns the separator (semicolon or none) required if
 // the type is terminating a declaration or statement.
-func (P *Printer) Signature(sig *ast.Signature) {
-       P.Parameters(sig.Params);
-       if sig.Result != nil {
+func (P *Printer) Signature(params, result []*ast.Field) {
+       P.Parameters(params);
+       if result != nil {
                P.separator = blank;
 
-               if len(sig.Result) == 1 && sig.Result[0].Names == nil {
+               if len(result) == 1 && result[0].Names == nil {
                        // single anonymous result
                        // => no parentheses needed unless it's a function type
-                       fld := sig.Result[0];
-                       if dummy, is_ftyp := fld.Typ.(*ast.FunctionType); !is_ftyp {
-                               P.Expr(fld.Typ);
+                       fld := result[0];
+                       if dummy, is_ftyp := fld.Type.(*ast.FunctionType); !is_ftyp {
+                               P.Expr(fld.Type);
                                return;
                        }
                }
                
-               P.Parameters(sig.Result);
+               P.Parameters(result);
        }
 }
 
@@ -535,16 +535,16 @@ func (P *Printer) Fields(lbrace scanner.Location, list []*ast.Field, rbrace scan
                        if n > 0 || len(fld.Names) == 0 {
                                // at least one identifier or anonymous field
                                if is_interface {
-                                       if ftyp, is_ftyp := fld.Typ.(*ast.FunctionType); is_ftyp {
-                                               P.Signature(ftyp.Sig);
+                                       if ftyp, is_ftyp := fld.Type.(*ast.FunctionType); is_ftyp {
+                                               P.Signature(ftyp.Params, ftyp.Results);
                                        } else {
-                                               P.Expr(fld.Typ);
+                                               P.Expr(fld.Type);
                                        }
                                } else {
-                                       P.Expr(fld.Typ);
+                                       P.Expr(fld.Type);
                                        if fld.Tag != nil {
                                                P.separator = tab;
-                                               P.Expr(fld.Tag);
+                                               P.Expr(&ast.StringList{fld.Tag});
                                        }
                                }
                        }
@@ -561,8 +561,8 @@ func (P *Printer) Fields(lbrace scanner.Location, list []*ast.Field, rbrace scan
 // ----------------------------------------------------------------------------
 // Expressions
 
-func (P *Printer) Block(b *ast.Block, indent bool)
 func (P *Printer) Expr1(x ast.Expr, prec1 int)
+func (P *Printer) Stmt(s ast.Stmt)
 
 
 func (P *Printer) DoBadExpr(x *ast.BadExpr) {
@@ -613,27 +613,46 @@ func (P *Printer) DoUnaryExpr(x *ast.UnaryExpr) {
 }
 
 
-func (P *Printer) DoBasicLit(x *ast.BasicLit) {
+func (P *Printer) DoIntLit(x *ast.IntLit) {
+       // TODO get rid of string conversion here
+       P.String(x.Pos_, string(x.Lit));
+}
+
+
+func (P *Printer) DoFloatLit(x *ast.FloatLit) {
+       // TODO get rid of string conversion here
+       P.String(x.Pos_, string(x.Lit));
+}
+
+
+func (P *Printer) DoCharLit(x *ast.CharLit) {
        // TODO get rid of string conversion here
        P.String(x.Pos_, string(x.Lit));
 }
 
 
 func (P *Printer) DoStringLit(x *ast.StringLit) {
+       // TODO get rid of string conversion here
+       P.String(x.Pos_, string(x.Lit));
+}
+
+
+func (P *Printer) DoStringList(x *ast.StringList) {
        for i, x := range x.Strings {
                if i > 0 {
                        P.separator = blank;
                }
-               P.DoBasicLit(x);
+               P.DoStringLit(x);
        }
 }
 
 
+func (P *Printer) DoFunctionType(x *ast.FunctionType)
+
 func (P *Printer) DoFunctionLit(x *ast.FunctionLit) {
-       P.Token(x.Func, token.FUNC);
-       P.Signature(x.Typ);
+       P.DoFunctionType(x.Type);
        P.separator = blank;
-       P.Block(x.Body, true);
+       P.Stmt(x.Body);
        P.newlines = 0;
 }
 
@@ -656,7 +675,7 @@ func (P *Printer) DoTypeAssertExpr(x *ast.TypeAssertExpr) {
        P.Expr1(x.X, token.HighestPrec);
        P.Token(nopos, token.PERIOD);
        P.Token(nopos, token.LPAREN);
-       P.Expr(x.Typ);
+       P.Expr(x.Type);
        P.Token(nopos, token.RPAREN);
 }
 
@@ -688,7 +707,7 @@ func (P *Printer) DoCallExpr(x *ast.CallExpr) {
 
 
 func (P *Printer) DoCompositeLit(x *ast.CompositeLit) {
-       P.Expr1(x.Typ, token.HighestPrec);
+       P.Expr1(x.Type, token.HighestPrec);
        P.Token(x.Lbrace, token.LBRACE);
        P.Exprs(x.Elts);
        P.Token(x.Rbrace, token.RBRACE);
@@ -720,7 +739,7 @@ func (P *Printer) DoStructType(x *ast.StructType) {
 
 func (P *Printer) DoFunctionType(x *ast.FunctionType) {
        P.Token(x.Func, token.FUNC);
-       P.Signature(x.Sig);
+       P.Signature(x.Params, x.Results);
 }
 
 
@@ -784,51 +803,51 @@ func (P *Printer) Expr(x ast.Expr) {
 // ----------------------------------------------------------------------------
 // Statements
 
-func (P *Printer) Stat(s ast.Stat) {
+func (P *Printer) Stmt(s ast.Stmt) {
        s.Visit(P);
 }
 
 
-func (P *Printer) DoBadStat(s *ast.BadStat) {
+func (P *Printer) DoBadStmt(s *ast.BadStmt) {
        panic();
 }
 
 
 func (P *Printer) Decl(d ast.Decl);
 
-func (P *Printer) DoDeclStat(s *ast.DeclStat) {
+func (P *Printer) DoDeclStmt(s *ast.DeclStmt) {
        P.Decl(s.Decl);
 }
 
 
-func (P *Printer) DoEmptyStat(s *ast.EmptyStat) {
+func (P *Printer) DoEmptyStmt(s *ast.EmptyStmt) {
        P.String(s.Semicolon, "");
 }
 
 
-func (P *Printer) DoLabeledStat(s *ast.LabeledStat) {
+func (P *Printer) DoLabeledStmt(s *ast.LabeledStmt) {
        P.indentation--;
        P.Expr(s.Label);
        P.Token(nopos, token.COLON);
        P.indentation++;
-       // TODO be more clever if s.Stat is a labeled stat as well
+       // TODO be more clever if s.Stmt is a labeled stat as well
        P.separator = tab;
-       P.Stat(s.Stat);
+       P.Stmt(s.Stmt);
 }
 
 
-func (P *Printer) DoExprStat(s *ast.ExprStat) {
+func (P *Printer) DoExprStmt(s *ast.ExprStmt) {
        P.Expr(s.X);
 }
 
 
-func (P *Printer) DoIncDecStat(s *ast.IncDecStat) {
+func (P *Printer) DoIncDecStmt(s *ast.IncDecStmt) {
        P.Expr(s.X);
        P.Token(nopos, s.Tok);
 }
 
 
-func (P *Printer) DoAssignmentStat(s *ast.AssignmentStat) {
+func (P *Printer) DoAssignStmt(s *ast.AssignStmt) {
        P.Exprs(s.Lhs);
        P.separator = blank;
        P.Token(s.Pos_, s.Tok);
@@ -837,28 +856,28 @@ func (P *Printer) DoAssignmentStat(s *ast.AssignmentStat) {
 }
 
 
-func (P *Printer) DoGoStat(s *ast.GoStat) {
+func (P *Printer) DoGoStmt(s *ast.GoStmt) {
        P.Token(s.Go, token.GO);
        P.separator = blank;
        P.Expr(s.Call);
 }
 
 
-func (P *Printer) DoDeferStat(s *ast.DeferStat) {
+func (P *Printer) DoDeferStmt(s *ast.DeferStmt) {
        P.Token(s.Defer, token.DEFER);
        P.separator = blank;
        P.Expr(s.Call);
 }
 
 
-func (P *Printer) DoReturnStat(s *ast.ReturnStat) {
+func (P *Printer) DoReturnStmt(s *ast.ReturnStmt) {
        P.Token(s.Return, token.RETURN);
        P.separator = blank;
        P.Exprs(s.Results);
 }
 
 
-func (P *Printer) DoControlFlowStat(s *ast.ControlFlowStat) {
+func (P *Printer) DoBranchStmt(s *ast.BranchStmt) {
        P.Token(s.Pos_, s.Tok);
        if s.Label != nil {
                P.separator = blank;
@@ -867,24 +886,27 @@ func (P *Printer) DoControlFlowStat(s *ast.ControlFlowStat) {
 }
 
 
-func (P *Printer) StatementList(list []ast.Stat) {
-       for i, s := range list {
-               if i == 0 {
-                       P.newlines = 1;
-               } else {  // i > 0
-                       if !P.opt_semi || *optsemicolons {
-                               // semicolon is required
-                               P.separator = semicolon;
+func (P *Printer) StatementList(list []ast.Stmt) {
+       if list != nil {
+               for i, s := range list {
+                       if i == 0 {
+                               P.newlines = 1;
+                       } else {  // i > 0
+                               if !P.opt_semi || *optsemicolons {
+                                       // semicolon is required
+                                       P.separator = semicolon;
+                               }
                        }
+                       P.Stmt(s);
+                       P.newlines = 1;
+                       P.state = inside_list;
                }
-               P.Stat(s);
-               P.newlines = 1;
-               P.state = inside_list;
        }
 }
 
 
-func (P *Printer) Block(b *ast.Block, indent bool) {
+/*
+func (P *Printer) Block(list []ast.Stmt, indent bool) {
        P.state = opening_scope;
        P.Token(b.Pos_, b.Tok);
        if !indent {
@@ -899,20 +921,29 @@ func (P *Printer) Block(b *ast.Block, indent bool) {
        }
        P.state = closing_scope;
        if b.Tok == token.LBRACE {
-               P.Token(b.Rparen, token.RBRACE);
+               P.Token(b.Rbrace, token.RBRACE);
                P.opt_semi = true;
        } else {
                P.String(nopos, "");  // process closing_scope state transition!
        }
 }
+*/
 
 
-func (P *Printer) DoCompositeStat(s *ast.CompositeStat) {
-       P.Block(s.Body, true);
+func (P *Printer) DoBlockStmt(s *ast.BlockStmt) {
+       P.state = opening_scope;
+       P.Token(s.Lbrace, token.LBRACE);
+       P.StatementList(s.List);
+       if !*optsemicolons {
+               P.separator = none;
+       }
+       P.state = closing_scope;
+       P.Token(s.Rbrace, token.RBRACE);
+       P.opt_semi = true;
 }
 
 
-func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, post ast.Stat) {
+func (P *Printer) ControlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, post ast.Stmt) {
        P.separator = blank;
        if init == nil && post == nil {
                // no semicolons required
@@ -923,7 +954,7 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
                // all semicolons required
                // (they are not separators, print them explicitly)
                if init != nil {
-                       P.Stat(init);
+                       P.Stmt(init);
                        P.separator = none;
                }
                P.Token(nopos, token.SEMICOLON);
@@ -932,11 +963,11 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
                        P.Expr(expr);
                        P.separator = none;
                }
-               if isForStat {
+               if isForStmt {
                        P.Token(nopos, token.SEMICOLON);
                        P.separator = blank;
                        if post != nil {
-                               P.Stat(post);
+                               P.Stmt(post);
                        }
                }
        }
@@ -944,15 +975,15 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
 }
 
 
-func (P *Printer) DoIfStat(s *ast.IfStat) {
+func (P *Printer) DoIfStmt(s *ast.IfStmt) {
        P.Token(s.If, token.IF);
        P.ControlClause(false, s.Init, s.Cond, nil);
-       P.Block(s.Body, true);
+       P.Stmt(s.Body);
        if s.Else != nil {
                P.separator = blank;
                P.Token(nopos, token.ELSE);
                P.separator = blank;
-               P.Stat(s.Else);
+               P.Stmt(s.Else);
        }
 }
 
@@ -965,53 +996,49 @@ func (P *Printer) DoCaseClause(s *ast.CaseClause) {
        } else {
                P.Token(s.Case, token.DEFAULT);
        }
-       // TODO: try to use P.Block instead
-       // P.Block(s.Body, true);
-       P.Token(s.Body.Pos_, token.COLON);
+       P.Token(s.Colon, token.COLON);
        P.indentation++;
-       P.StatementList(s.Body.List);
+       P.StatementList(s.Body);
        P.indentation--;
        P.newlines = 1;
 }
 
 
-func (P *Printer) DoSwitchStat(s *ast.SwitchStat) {
+func (P *Printer) DoSwitchStmt(s *ast.SwitchStmt) {
        P.Token(s.Switch, token.SWITCH);
        P.ControlClause(false, s.Init, s.Tag, nil);
-       P.Block(s.Body, false);
+       P.Stmt(s.Body);
 }
 
 
 func (P *Printer) DoTypeCaseClause(s *ast.TypeCaseClause) {
-       if s.Typ != nil {
+       if s.Type != nil {
                P.Token(s.Case, token.CASE);
                P.separator = blank;
-               P.Expr(s.Typ);
+               P.Expr(s.Type);
        } else {
                P.Token(s.Case, token.DEFAULT);
        }
-       // TODO: try to use P.Block instead
-       // P.Block(s.Body, true);
-       P.Token(s.Body.Pos_, token.COLON);
+       P.Token(s.Colon, token.COLON);
        P.indentation++;
-       P.StatementList(s.Body.List);
+       P.StatementList(s.Body);
        P.indentation--;
        P.newlines = 1;
 }
 
 
-func (P *Printer) DoTypeSwitchStat(s *ast.TypeSwitchStat) {
+func (P *Printer) DoTypeSwitchStmt(s *ast.TypeSwitchStmt) {
        P.Token(s.Switch, token.SWITCH);
        P.separator = blank;
        if s.Init != nil {
-               P.Stat(s.Init);
+               P.Stmt(s.Init);
                P.separator = none;
                P.Token(nopos, token.SEMICOLON);
        }
        P.separator = blank;
-       P.Stat(s.Assign);
+       P.Stmt(s.Assign);
        P.separator = blank;
-       P.Block(s.Body, false);
+       P.Stmt(s.Body);
 }
 
 
@@ -1029,36 +1056,46 @@ func (P *Printer) DoCommClause(s *ast.CommClause) {
        } else {
                P.Token(s.Case, token.DEFAULT);
        }
-       // TODO: try to use P.Block instead
-       // P.Block(s.Body, true);
-       P.Token(s.Body.Pos_, token.COLON);
+       P.Token(s.Colon, token.COLON);
        P.indentation++;
-       P.StatementList(s.Body.List);
+       P.StatementList(s.Body);
        P.indentation--;
        P.newlines = 1;
 }
 
 
-func (P *Printer) DoSelectStat(s *ast.SelectStat) {
+func (P *Printer) DoSelectStmt(s *ast.SelectStmt) {
        P.Token(s.Select, token.SELECT);
        P.separator = blank;
-       P.Block(s.Body, false);
+       P.Stmt(s.Body);
 }
 
 
-func (P *Printer) DoForStat(s *ast.ForStat) {
+func (P *Printer) DoForStmt(s *ast.ForStmt) {
        P.Token(s.For, token.FOR);
        P.ControlClause(true, s.Init, s.Cond, s.Post);
-       P.Block(s.Body, true);
+       P.Stmt(s.Body);
 }
 
 
-func (P *Printer) DoRangeStat(s *ast.RangeStat) {
+func (P *Printer) DoRangeStmt(s *ast.RangeStmt) {
        P.Token(s.For, token.FOR);
        P.separator = blank;
-       P.Stat(s.Range);
+       P.Expr(s.Key);
+       if s.Value != nil {
+               P.Token(nopos, token.COMMA);
+               P.separator = blank;
+               P.state = inside_list;
+               P.Expr(s.Value);
+       }
+       P.separator = blank;
+       P.Token(s.Pos_, s.Tok);
+       P.separator = blank;
+       P.Token(nopos, token.RANGE);
+       P.separator = blank;
+       P.Expr(s.X);
        P.separator = blank;
-       P.Block(s.Body, true);
+       P.Stmt(s.Body);
 }
 
 
@@ -1078,14 +1115,14 @@ func (P *Printer) DoImportDecl(d *ast.ImportDecl) {
        if d.Name != nil {
                P.Expr(d.Name);
        } else {
-               P.String(d.Path.Pos(), "");  // flush pending ';' separator/newlines
+               P.String(d.Path[0].Pos(), "");  // flush pending ';' separator/newlines
        }
        P.separator = tab;
        // TODO fix for longer package names
-       if len(d.Path.Strings) > 1 {
+       if len(d.Path) > 1 {
                panic();
        }
-       P.HtmlPackageName(d.Path.Pos(), string(d.Path.Strings[0].Lit));
+       P.HtmlPackageName(d.Path[0].Pos(), string(d.Path[0].Lit));
        P.newlines = 2;
 }
 
@@ -1096,9 +1133,9 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) {
                P.separator = blank;
        }
        P.Idents(d.Names, P.full);
-       if d.Typ != nil {
+       if d.Type != nil {
                P.separator = blank;  // TODO switch to tab? (indentation problem with structs)
-               P.Expr(d.Typ);
+               P.Expr(d.Type);
        }
        if d.Values != nil {
                P.separator = tab;
@@ -1111,13 +1148,13 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) {
 
 
 func (P *Printer) DoTypeDecl(d *ast.TypeDecl) {
-       if d.Type.Pos > 0 {
-               P.Token(d.Type, token.TYPE);
+       if d.Pos_.Pos > 0 {
+               P.Token(d.Pos_, token.TYPE);
                P.separator = blank;
        }
        P.Expr(d.Name);
        P.separator = blank;  // TODO switch to tab? (but indentation problem with structs)
-       P.Expr(d.Typ);
+       P.Expr(d.Type);
        P.newlines = 2;
 }
 
@@ -1128,10 +1165,10 @@ func (P *Printer) DoVarDecl(d *ast.VarDecl) {
                P.separator = blank;
        }
        P.Idents(d.Names, P.full);
-       if d.Typ != nil {
+       if d.Type != nil {
                P.separator = blank;  // TODO switch to tab? (indentation problem with structs)
-               P.Expr(d.Typ);
-               //P.separator = P.Type(d.Typ);
+               P.Expr(d.Type);
+               //P.separator = P.Type(d.Type);
        }
        if d.Values != nil {
                P.separator = tab;
@@ -1144,7 +1181,7 @@ func (P *Printer) DoVarDecl(d *ast.VarDecl) {
 
 
 func (P *Printer) DoFuncDecl(d *ast.FuncDecl) {
-       P.Token(d.Func, token.FUNC);
+       P.Token(d.Type.Func, token.FUNC);
        P.separator = blank;
        if recv := d.Recv; recv != nil {
                // method: print receiver
@@ -1153,15 +1190,15 @@ func (P *Printer) DoFuncDecl(d *ast.FuncDecl) {
                        P.Expr(recv.Names[0]);
                        P.separator = blank;
                }
-               P.Expr(recv.Typ);
+               P.Expr(recv.Type);
                P.Token(nopos, token.RPAREN);
                P.separator = blank;
        }
        P.Expr(d.Name);
-       P.Signature(d.Sig);
+       P.Signature(d.Type.Params, d.Type.Results);
        if P.full && d.Body != nil {
                P.separator = blank;
-               P.Block(d.Body, true);
+               P.Stmt(d.Body);
        }
        P.newlines = 3;
 }
@@ -1288,7 +1325,7 @@ func (P *Printer) Interface(p *ast.Package) {
                        if isExported(d.Name) {
                                if d.Recv != nil {
                                        P.Printf("<h3>func (");
-                                       P.Expr(d.Recv.Typ);
+                                       P.Expr(d.Recv.Type);
                                        P.Printf(") %s</h3>\n", d.Name.Lit);
                                } else {
                                        P.Printf("<h2>func %s</h2>\n", d.Name.Lit);