diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go index 5c13e59987f..d8984a97be0 100644 --- a/usr/gri/pretty/parser.go +++ b/usr/gri/pretty/parser.go @@ -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 + 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.AssignmentStat{x, pos, tok, y}; - - default: - if len(x) > 1 { - P.error(x[0].Pos(), "only one expression allowed"); - } - - if P.tok == token.INC || P.tok == token.DEC { - s := &ast.IncDecStat{x[0], P.tok}; - P.next(); // consume "++" or "--" - return s; - } - - return &ast.ExprStat{x[0]}; + return &ast.AssignStmt{x, pos, tok, y}; } - unreachable(); + if len(x) > 1 { + P.error(x[0].Pos(), "only one expression allowed"); + // continue with first expression + } + + 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; + } + + // 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; } - return nil, nil; + if es, is_expr := s.(*ast.ExprStmt); is_expr { + return es.X; + } + 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}; } diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go index 49f77386fbc..a7f823c4b53 100644 --- a/usr/gri/pretty/printer.go +++ b/usr/gri/pretty/printer.go @@ -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.Block(s.Body, true); + 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.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("

func ("); - P.Expr(d.Recv.Typ); + P.Expr(d.Recv.Type); P.Printf(") %s

\n", d.Name.Lit); } else { P.Printf("

func %s

\n", d.Name.Lit);