1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:04:40 -07:00

adjustments matching updated ast

R=r
OCL=26746
CL=26746
This commit is contained in:
Robert Griesemer 2009-03-25 12:45:06 -07:00
parent bafd8c390a
commit ba620d5027
2 changed files with 340 additions and 289 deletions

View 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
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};
}

View 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.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("<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);