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;
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;
}
// (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;
}
}
pos := P.expect(token.FUNC);
- sig := P.parseSignature();
+ params, results := P.parseSignature();
- return &ast.FunctionType{pos, sig};
+ return &ast.FunctionType{pos, params, results};
}
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;
}
-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 {
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
// ----------------------------------------------------------------------------
// 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"));
}
}
}
- 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};
}
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);
}
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;
}
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;
// 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();
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;
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();
}
-/*
-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"));
}
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 {
}
-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_};
}
} 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};
}
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);
}
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
}
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();
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);
}
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();
}
-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};
}
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
}
}
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};
}
if n > 0 {
P.separator = blank
};
- P.Expr(par.Typ);
+ P.Expr(par.Type);
}
}
P.Token(nopos, token.RPAREN);
// 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);
}
}
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});
}
}
}
// ----------------------------------------------------------------------------
// 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) {
}
-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;
}
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);
}
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);
func (P *Printer) DoFunctionType(x *ast.FunctionType) {
P.Token(x.Func, token.FUNC);
- P.Signature(x.Sig);
+ P.Signature(x.Params, x.Results);
}
// ----------------------------------------------------------------------------
// 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);
}
-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;
}
-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 {
}
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
// 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);
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);
}
}
}
}
-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);
}
}
} 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);
}
} 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);
}
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;
}
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;
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;
}
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;
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
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;
}
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);