mirror of
https://github.com/golang/go.git
synced 2024-09-30 06:47:04 +00:00
snapshot of pretty printer:
- almost there, receivers, labels, composites, comments are not yet printed - runs through 18KLOC of Go code and prints it again R=r OCL=17237 CL=17237
This commit is contained in:
parent
13508ceabe
commit
6b49713df5
@ -36,18 +36,26 @@ test: pretty
|
||||
testnoisy: pretty
|
||||
pretty *.go
|
||||
pretty ../gosrc/*.go
|
||||
#pretty $(GOROOT)/test/*.go # contains incorrect programs
|
||||
pretty $(GOROOT)/test/235.go
|
||||
pretty $(GOROOT)/test/args.go
|
||||
pretty $(GOROOT)/test/bufiolib.go
|
||||
pretty $(GOROOT)/test/char_lit.go
|
||||
pretty $(GOROOT)/test/sieve.go
|
||||
pretty $(GOROOT)/test/complit.go
|
||||
pretty $(GOROOT)/test/const.go
|
||||
pretty $(GOROOT)/test/dialgoogle.go
|
||||
pretty $(GOROOT)/test/empty.go
|
||||
pretty $(GOROOT)/test/env.go
|
||||
pretty $(GOROOT)/test/float_lit.go
|
||||
pretty $(GOROOT)/test/fmt_test.go
|
||||
pretty $(GOROOT)/test/for.go
|
||||
pretty $(GOROOT)/test/func.go
|
||||
pretty $(GOROOT)/test/func1.go
|
||||
pretty $(GOROOT)/test/func2.go
|
||||
pretty $(GOROOT)/src/pkg/*.go
|
||||
pretty $(GOROOT)/src/lib/flag.go
|
||||
pretty $(GOROOT)/src/lib/fmt.go
|
||||
pretty $(GOROOT)/src/lib/rand.go
|
||||
pretty $(GOROOT)/src/lib/math/*.go
|
||||
pretty $(GOROOT)/src/lib/container/*.go
|
||||
pretty $(GOROOT)/src/lib/syscall/*.go
|
||||
pretty $(GOROOT)/src/lib/*.go
|
||||
pretty $(GOROOT)/src/lib/*/*.go
|
||||
pretty $(GOROOT)/usr/r/*/*.go
|
||||
echo "DONE"
|
||||
|
||||
# These tests don't work yet
|
||||
|
@ -38,6 +38,11 @@ func (p *List) at(i int) Node {
|
||||
}
|
||||
|
||||
|
||||
func (p *List) set(i int, x Node) {
|
||||
p.a[i] = x;
|
||||
}
|
||||
|
||||
|
||||
func (p *List) Add (x Node) {
|
||||
a := p.a;
|
||||
n := len(a);
|
||||
@ -100,7 +105,7 @@ export type Expr struct {
|
||||
pos, tok int;
|
||||
x, y *Expr; // binary (x, y) and unary (y) expressions
|
||||
s string; // identifiers and literals
|
||||
t *Type; // declarations and composite literals
|
||||
t *Type; // operands that are types
|
||||
}
|
||||
|
||||
|
||||
@ -130,6 +135,13 @@ export func NewLit(pos, tok int, s string) *Expr {
|
||||
}
|
||||
|
||||
|
||||
export func NewTypeExpr(pos int, t *Type) *Expr {
|
||||
e := new(Expr);
|
||||
e.pos, e.tok, e.t = pos, Scanner.TYPE, t;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Statements
|
||||
|
||||
|
@ -238,10 +238,10 @@ func (P *Parser) ParseChannelType() *Node.Type {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseVarDeclList() {
|
||||
func (P *Parser) ParseVarDeclList(list *Node.List) {
|
||||
P.Trace("VarDeclList");
|
||||
|
||||
list := Node.NewList();
|
||||
i0 := list.len();
|
||||
list.Add(P.ParseType());
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
@ -251,19 +251,31 @@ func (P *Parser) ParseVarDeclList() {
|
||||
typ := P.TryType();
|
||||
|
||||
if typ != nil {
|
||||
// all list entries must be identifiers;
|
||||
// convert the list into an expression list of identifiers
|
||||
for i, n := 0, list.len(); i < n; i++ {
|
||||
// all list entries must be identifiers
|
||||
// convert the type entries into identifiers
|
||||
for i, n := i0, list.len(); i < n; i++ {
|
||||
t := list.at(i).(*Node.Type);
|
||||
if t.tok == Scanner.IDENT && t.expr.tok == Scanner.IDENT {
|
||||
x := t.expr;
|
||||
list.set(i, t.expr);
|
||||
} else {
|
||||
list.set(i, Node.NewLit(t.pos, Scanner.IDENT, "bad"));
|
||||
P.Error(t.pos, "identifier expected");
|
||||
}
|
||||
}
|
||||
// add type
|
||||
list.Add(Node.NewTypeExpr(typ.pos, typ));
|
||||
|
||||
} else {
|
||||
// all list entries are types
|
||||
// convert all type entries into type expressions
|
||||
for i, n := i0, list.len(); i < n; i++ {
|
||||
t := list.at(i).(*Node.Type);
|
||||
list.set(i, Node.NewTypeExpr(t.pos, t));
|
||||
}
|
||||
|
||||
if P.tok == Scanner.COMMA {
|
||||
panic("internal parser error");
|
||||
}
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
@ -274,10 +286,10 @@ func (P *Parser) ParseParameterList() *Node.List {
|
||||
P.Trace("ParameterList");
|
||||
|
||||
list := Node.NewList();
|
||||
P.ParseVarDeclList();
|
||||
P.ParseVarDeclList(list);
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
P.ParseVarDeclList();
|
||||
P.ParseVarDeclList(list);
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
@ -285,18 +297,18 @@ func (P *Parser) ParseParameterList() *Node.List {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameters() *Node.List {
|
||||
func (P *Parser) ParseParameters() *Node.Type {
|
||||
P.Trace("Parameters");
|
||||
|
||||
var list *Node.List;
|
||||
t := Node.NewType(P.pos, Scanner.STRUCT);
|
||||
P.Expect(Scanner.LPAREN);
|
||||
if P.tok != Scanner.RPAREN {
|
||||
list = P.ParseParameterList();
|
||||
t.list = P.ParseParameterList();
|
||||
}
|
||||
P.Expect(Scanner.RPAREN);
|
||||
|
||||
P.Ecart();
|
||||
return list;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@ -316,18 +328,23 @@ func (P *Parser) ParseResultList() {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseResult() *Node.List {
|
||||
func (P *Parser) ParseResult() *Node.Type {
|
||||
P.Trace("Result");
|
||||
|
||||
var list *Node.List;
|
||||
var t *Node.Type;
|
||||
if P.tok == Scanner.LPAREN {
|
||||
list = P.ParseParameters();
|
||||
t = P.ParseParameters();
|
||||
} else {
|
||||
typ := P.TryType();
|
||||
if typ != nil {
|
||||
t = Node.NewType(P.pos, Scanner.STRUCT);
|
||||
t.list = Node.NewList();
|
||||
t.list.Add(Node.NewTypeExpr(typ.pos, typ));
|
||||
}
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
return list;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@ -341,8 +358,8 @@ func (P *Parser) ParseFunctionType() *Node.Type {
|
||||
P.Trace("FunctionType");
|
||||
|
||||
t := Node.NewType(P.pos, Scanner.LPAREN);
|
||||
t.list = P.ParseParameters();
|
||||
P.ParseResult();
|
||||
t.list = P.ParseParameters().list; // TODO find better solution
|
||||
t.elt = P.ParseResult();
|
||||
|
||||
P.Ecart();
|
||||
return t;
|
||||
@ -405,7 +422,7 @@ func (P *Parser) ParseStructType() *Node.Type {
|
||||
P.Next();
|
||||
t.list = Node.NewList();
|
||||
for P.tok == Scanner.IDENT {
|
||||
P.ParseVarDeclList();
|
||||
P.ParseVarDeclList(t.list);
|
||||
if P.tok != Scanner.RBRACE {
|
||||
P.Expect(Scanner.SEMICOLON);
|
||||
}
|
||||
@ -521,7 +538,7 @@ func (P *Parser) ParseFunctionLit() *Node.Expr {
|
||||
P.scope_lev--;
|
||||
|
||||
P.Ecart();
|
||||
return nil;
|
||||
return Node.NewLit(P.pos, Scanner.INT, "0"); // "null" expr
|
||||
}
|
||||
|
||||
|
||||
@ -550,16 +567,17 @@ func (P *Parser) ParseOperand() *Node.Expr {
|
||||
}
|
||||
|
||||
case Scanner.FUNC:
|
||||
P.ParseFunctionLit();
|
||||
x = P.ParseFunctionLit();
|
||||
|
||||
default:
|
||||
typ := P.TryType();
|
||||
if typ != nil {
|
||||
break;
|
||||
t := P.TryType();
|
||||
if t != nil {
|
||||
x = Node.NewTypeExpr(t.pos, t);
|
||||
} else {
|
||||
P.Error(P.pos, "operand expected");
|
||||
P.Next(); // make progress
|
||||
x = Node.NewLit(P.pos, Scanner.INT, "0"); // "null" expr
|
||||
}
|
||||
|
||||
P.Error(P.pos, "operand expected");
|
||||
P.Next(); // make progress
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
@ -635,7 +653,7 @@ func (P *Parser) ParseCall(x *Node.Expr) *Node.Expr {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseCompositeLit() {
|
||||
func (P *Parser) ParseCompositeLit(t *Node.Type) *Node.Expr {
|
||||
P.Trace("CompositeLit");
|
||||
|
||||
mode := 0;
|
||||
@ -659,6 +677,7 @@ func (P *Parser) ParseCompositeLit() {
|
||||
P.Expect(Scanner.RBRACE);
|
||||
|
||||
P.Ecart();
|
||||
return Node.NewLit(P.pos, Scanner.INT, "0"); // "null" expr
|
||||
}
|
||||
|
||||
|
||||
@ -673,8 +692,19 @@ func (P *Parser) ParsePrimaryExpr() *Node.Expr {
|
||||
case Scanner.LPAREN: x = P.ParseCall(x);
|
||||
case Scanner.LBRACE:
|
||||
if P.expr_lev > 0 {
|
||||
P.ParseCompositeLit();
|
||||
var t *Node.Type;
|
||||
if x.tok == Scanner.TYPE {
|
||||
t = x.t;
|
||||
} else if x.tok == Scanner.IDENT {
|
||||
// assume a type name
|
||||
t = Node.NewType(x.pos, Scanner.IDENT);
|
||||
t.expr = x;
|
||||
} else {
|
||||
P.Error(x.pos, "type expected for composite literal");
|
||||
}
|
||||
x = P.ParseCompositeLit(t);
|
||||
} else {
|
||||
// composites inside control clauses must be parenthesized
|
||||
goto exit;
|
||||
}
|
||||
default: goto exit;
|
||||
@ -1100,6 +1130,7 @@ func (P *Parser) ParseImportSpec() *Node.Decl {
|
||||
|
||||
if P.tok == Scanner.STRING {
|
||||
// TODO eventually the scanner should strip the quotes
|
||||
d.val = Node.NewLit(P.pos, Scanner.STRING, P.val);
|
||||
P.Next();
|
||||
} else {
|
||||
P.Expect(Scanner.STRING); // use Expect() error handling
|
||||
@ -1218,15 +1249,11 @@ func (P *Parser) ParseFunctionDecl(exported bool) *Node.Decl {
|
||||
P.Expect(Scanner.FUNC);
|
||||
if P.tok == Scanner.LPAREN {
|
||||
pos := P.pos;
|
||||
P.ParseParameters();
|
||||
recv := P.ParseParameters();
|
||||
// TODO: fix this
|
||||
/*
|
||||
if tmp.len() > 0 {
|
||||
//recv = tmp.at(0);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if recv.idents.len() != 1 {
|
||||
//P.Error(pos, "must have exactly one receiver");
|
||||
if recv.list.len() != 1 {
|
||||
P.Error(pos, "must have exactly one receiver");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ export type Printer struct {
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) String(s string) {
|
||||
func (P *Printer) String(pos int, s string) {
|
||||
if P.semi && P.level > 0 { // no semicolons at level 0
|
||||
print(";");
|
||||
}
|
||||
@ -31,8 +31,13 @@ func (P *Printer) String(s string) {
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) Token(tok int) {
|
||||
P.String(Scanner.TokenString(tok));
|
||||
func (P *Printer) Blank() {
|
||||
P.String(0, " ");
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) Token(pos int, tok int) {
|
||||
P.String(pos, Scanner.TokenString(tok));
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +49,7 @@ func (P *Printer) NewLine() { // explicit "\n"
|
||||
|
||||
func (P *Printer) OpenScope(paren string) {
|
||||
P.semi, P.newl = false, false;
|
||||
P.String(paren);
|
||||
P.String(0, paren);
|
||||
P.level++;
|
||||
P.indent++;
|
||||
P.newl = true;
|
||||
@ -54,7 +59,7 @@ func (P *Printer) OpenScope(paren string) {
|
||||
func (P *Printer) CloseScope(paren string) {
|
||||
P.indent--;
|
||||
P.semi = false;
|
||||
P.String(paren);
|
||||
P.String(0, paren);
|
||||
P.level--;
|
||||
P.semi, P.newl = false, true;
|
||||
}
|
||||
@ -63,50 +68,91 @@ func (P *Printer) CloseScope(paren string) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
func (P *Printer) Type(t *Node.Type)
|
||||
func (P *Printer) Expr(x *Node.Expr)
|
||||
|
||||
func (P *Printer) Parameters(list *Node.List) {
|
||||
var prev int;
|
||||
for i, n := 0, list.len(); i < n; i++ {
|
||||
x := list.at(i).(*Node.Expr);
|
||||
if i > 0 {
|
||||
if prev == x.tok || prev == Scanner.TYPE {
|
||||
P.String(0, ", ");
|
||||
} else {
|
||||
P.Blank();
|
||||
}
|
||||
}
|
||||
P.Expr(x);
|
||||
prev = x.tok;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) Fields(list *Node.List) {
|
||||
var prev int;
|
||||
for i, n := 0, list.len(); i < n; i++ {
|
||||
x := list.at(i).(*Node.Expr);
|
||||
if i > 0 {
|
||||
if prev == Scanner.TYPE {
|
||||
P.String(0, ";");
|
||||
P.newl = true;
|
||||
} else if prev == x.tok {
|
||||
P.String(0, ", ");
|
||||
} else {
|
||||
P.Blank();
|
||||
}
|
||||
}
|
||||
P.Expr(x);
|
||||
prev = x.tok;
|
||||
}
|
||||
P.newl = true;
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) Type(t *Node.Type) {
|
||||
if t == nil { // TODO remove this check
|
||||
P.String(0, "<nil type>");
|
||||
return;
|
||||
}
|
||||
|
||||
switch t.tok {
|
||||
case Scanner.IDENT:
|
||||
P.Expr(t.expr);
|
||||
|
||||
case Scanner.LBRACK:
|
||||
P.String("[");
|
||||
P.String(t.pos, "[");
|
||||
if t.expr != nil {
|
||||
P.Expr(t.expr);
|
||||
}
|
||||
P.String("] ");
|
||||
P.String(0, "] ");
|
||||
P.Type(t.elt);
|
||||
|
||||
case Scanner.STRUCT:
|
||||
P.String("struct");
|
||||
P.String(t.pos, "struct");
|
||||
if t.list != nil {
|
||||
P.OpenScope(" {");
|
||||
/*
|
||||
for i := 0; i < x.fields.len(); i++ {
|
||||
P.Print(x.fields.at(i));
|
||||
P.newl, P.semi = true, true;
|
||||
}
|
||||
*/
|
||||
P.Fields(t.list);
|
||||
P.CloseScope("}");
|
||||
}
|
||||
|
||||
case Scanner.MAP:
|
||||
P.String("[");
|
||||
P.String(t.pos, "[");
|
||||
P.Type(t.key);
|
||||
P.String("] ");
|
||||
P.String(0, "] ");
|
||||
P.Type(t.elt);
|
||||
|
||||
case Scanner.CHAN:
|
||||
var m string;
|
||||
switch t.mode {
|
||||
case Node.FULL: P.String("chan ");
|
||||
case Node.RECV: P.String("<-chan ");
|
||||
case Node.SEND: P.String("chan <- ");
|
||||
case Node.FULL: m = "chan ";
|
||||
case Node.RECV: m = "<-chan ";
|
||||
case Node.SEND: m = "chan <- ";
|
||||
}
|
||||
P.String(t.pos, m);
|
||||
P.Type(t.elt);
|
||||
|
||||
case Scanner.INTERFACE:
|
||||
P.String("interface");
|
||||
P.String(t.pos, "interface");
|
||||
if t.list != nil {
|
||||
P.OpenScope(" {");
|
||||
/*
|
||||
@ -119,20 +165,18 @@ func (P *Printer) Type(t *Node.Type) {
|
||||
}
|
||||
|
||||
case Scanner.MUL:
|
||||
P.String("*");
|
||||
P.String(t.pos, "*");
|
||||
P.Type(t.elt);
|
||||
|
||||
case Scanner.LPAREN:
|
||||
P.String("(");
|
||||
//P.PrintList(x.params);
|
||||
P.String(")");
|
||||
/*
|
||||
if x.result != nil {
|
||||
P.String(" (");
|
||||
P.PrintList(x.result);
|
||||
P.String(")");
|
||||
P.String(t.pos, "(");
|
||||
P.Parameters(t.list);
|
||||
P.String(0, ")");
|
||||
if t.elt != nil {
|
||||
P.String(0, " (");
|
||||
P.Parameters(t.elt.list);
|
||||
P.String(0, ")");
|
||||
}
|
||||
*/
|
||||
|
||||
default:
|
||||
panic("UNREACHABLE");
|
||||
@ -149,49 +193,55 @@ func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
|
||||
}
|
||||
|
||||
switch x.tok {
|
||||
case Scanner.VAR:
|
||||
panic("UNIMPLEMENTED (VAR)");
|
||||
|
||||
case Scanner.TYPE:
|
||||
P.Type(x.t);
|
||||
|
||||
case Scanner.IDENT, Scanner.INT, Scanner.STRING, Scanner.FLOAT:
|
||||
P.String(x.s);
|
||||
P.String(x.pos, x.s);
|
||||
|
||||
case Scanner.COMMA:
|
||||
P.Expr1(x.x, 0);
|
||||
P.String(", ");
|
||||
P.String(x.pos, ", ");
|
||||
P.Expr1(x.y, 0);
|
||||
|
||||
case Scanner.PERIOD:
|
||||
P.Expr1(x.x, 8);
|
||||
P.String(".");
|
||||
P.Expr1(x.x, 8); // 8 == highest precedence
|
||||
P.String(x.pos, ".");
|
||||
P.Expr1(x.y, 8);
|
||||
|
||||
case Scanner.LBRACK:
|
||||
P.Expr1(x.x, 8);
|
||||
P.String("[");
|
||||
P.String(x.pos, "[");
|
||||
P.Expr1(x.y, 0);
|
||||
P.String("]");
|
||||
P.String(0, "]");
|
||||
|
||||
case Scanner.LPAREN:
|
||||
P.Expr1(x.x, 8);
|
||||
P.String("(");
|
||||
P.String(x.pos, "(");
|
||||
P.Expr1(x.y, 0);
|
||||
P.String(")");
|
||||
P.String(0, ")");
|
||||
|
||||
default:
|
||||
if x.x == nil {
|
||||
// unary expression
|
||||
P.Token(x.tok);
|
||||
P.Expr1(x.y, 7);
|
||||
P.Token(x.pos, x.tok);
|
||||
P.Expr1(x.y, 7); // 7 == unary operator precedence
|
||||
} else {
|
||||
// binary expression: print ()'s if necessary
|
||||
prec := Scanner.Precedence(x.tok);
|
||||
if prec < prec1 {
|
||||
print("(");
|
||||
P.String(0, "(");
|
||||
}
|
||||
P.Expr1(x.x, prec);
|
||||
P.String(" ");
|
||||
P.Token(x.tok);
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Token(x.pos, x.tok);
|
||||
P.Blank();
|
||||
P.Expr1(x.y, prec);
|
||||
if prec < prec1 {
|
||||
print(")");
|
||||
P.String(0, ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -231,31 +281,30 @@ func (P *Printer) Block(list *Node.List, indent bool) {
|
||||
|
||||
func (P *Printer) ControlClause(s *Node.Stat) {
|
||||
if s.init != nil {
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Stat(s.init);
|
||||
P.semi = true;
|
||||
P.String("");
|
||||
}
|
||||
if s.expr != nil {
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Expr(s.expr);
|
||||
P.semi = false;
|
||||
}
|
||||
if s.tok == Scanner.FOR && s.post != nil {
|
||||
P.semi = true;
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Stat(s.post);
|
||||
P.semi = false;
|
||||
}
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) Declaration(d *Node.Decl);
|
||||
func (P *Printer) Declaration(d *Node.Decl, parenthesized bool);
|
||||
|
||||
func (P *Printer) Stat(s *Node.Stat) {
|
||||
if s == nil { // TODO remove this check
|
||||
P.String("<nil stat>");
|
||||
P.String(0, "<nil stat>");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -265,66 +314,66 @@ func (P *Printer) Stat(s *Node.Stat) {
|
||||
P.semi = true;
|
||||
|
||||
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
|
||||
P.Declaration(s.decl);
|
||||
P.Declaration(s.decl, false);
|
||||
|
||||
case Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN,
|
||||
Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN,
|
||||
Scanner.REM_ASSIGN, Scanner.AND_ASSIGN, Scanner.OR_ASSIGN,
|
||||
Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
|
||||
P.Expr(s.lhs);
|
||||
P.String(" ");
|
||||
P.Token(s.tok);
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Token(s.pos, s.tok);
|
||||
P.Blank();
|
||||
P.Expr(s.expr);
|
||||
P.semi = true;
|
||||
|
||||
case Scanner.INC, Scanner.DEC:
|
||||
P.Expr(s.expr);
|
||||
P.Token(s.tok);
|
||||
P.Token(s.pos, s.tok);
|
||||
P.semi = true;
|
||||
|
||||
case Scanner.LBRACE:
|
||||
P.Block(s.block, true);
|
||||
|
||||
case Scanner.IF:
|
||||
P.String("if");
|
||||
P.String(s.pos, "if");
|
||||
P.ControlClause(s);
|
||||
P.Block(s.block, true);
|
||||
if s.post != nil {
|
||||
P.newl = false;
|
||||
P.String(" else ");
|
||||
P.String(0, " else ");
|
||||
P.Stat(s.post);
|
||||
}
|
||||
|
||||
case Scanner.FOR:
|
||||
P.String("for");
|
||||
P.String(s.pos, "for");
|
||||
P.ControlClause(s);
|
||||
P.Block(s.block, true);
|
||||
|
||||
case Scanner.SWITCH, Scanner.SELECT:
|
||||
P.Token(s.tok);
|
||||
P.Token(s.pos, s.tok);
|
||||
P.ControlClause(s);
|
||||
P.Block(s.block, false);
|
||||
|
||||
case Scanner.CASE, Scanner.DEFAULT:
|
||||
P.Token(s.tok);
|
||||
P.Token(s.pos, s.tok);
|
||||
if s.expr != nil {
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Expr(s.expr);
|
||||
}
|
||||
P.String(":");
|
||||
P.String(0, ":");
|
||||
P.OpenScope("");
|
||||
P.StatementList(s.block);
|
||||
P.CloseScope("");
|
||||
|
||||
case Scanner.GO, Scanner.RETURN, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
|
||||
P.Token(s.tok);
|
||||
P.String(" ");
|
||||
P.Token(s.pos, s.tok);
|
||||
P.Blank();
|
||||
P.Expr(s.expr);
|
||||
P.semi = true;
|
||||
|
||||
default:
|
||||
P.String("<stat>");
|
||||
P.String(s.pos, "<stat>");
|
||||
P.semi = true;
|
||||
}
|
||||
}
|
||||
@ -363,45 +412,47 @@ func (P *Printer) DoMethodDecl(x *AST.MethodDecl) {
|
||||
*/
|
||||
|
||||
|
||||
func (P *Printer) Declaration(d *Node.Decl) {
|
||||
if d.tok == Scanner.FUNC || d.ident == nil {
|
||||
func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
|
||||
if d == nil { // TODO remove this check
|
||||
P.String(0, "<nil decl>");
|
||||
return;
|
||||
}
|
||||
|
||||
if !parenthesized {
|
||||
if d.exported {
|
||||
P.String("export ");
|
||||
P.String(0, "export ");
|
||||
}
|
||||
P.Token(d.tok);
|
||||
P.String(" ");
|
||||
P.Token(d.pos, d.tok);
|
||||
P.Blank();
|
||||
}
|
||||
|
||||
if d.ident == nil {
|
||||
switch d.list.len() {
|
||||
case 0:
|
||||
P.String("()");
|
||||
case 1:
|
||||
P.Declaration(d.list.at(0).(*Node.Decl));
|
||||
default:
|
||||
P.OpenScope("(");
|
||||
for i := 0; i < d.list.len(); i++ {
|
||||
P.Declaration(d.list.at(i).(*Node.Decl));
|
||||
P.newl, P.semi = true, true;
|
||||
}
|
||||
P.CloseScope(")");
|
||||
P.OpenScope("(");
|
||||
for i := 0; i < d.list.len(); i++ {
|
||||
P.Declaration(d.list.at(i).(*Node.Decl), true);
|
||||
P.newl, P.semi = true, true;
|
||||
}
|
||||
P.CloseScope(")");
|
||||
|
||||
} else {
|
||||
P.Expr(d.ident);
|
||||
if d.typ != nil {
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Type(d.typ);
|
||||
}
|
||||
if d.val != nil {
|
||||
P.String(" = ");
|
||||
if d.tok == Scanner.IMPORT {
|
||||
P.Blank();
|
||||
} else {
|
||||
P.String(0, " = ");
|
||||
}
|
||||
P.Expr(d.val);
|
||||
}
|
||||
if d.list != nil {
|
||||
if d.tok != Scanner.FUNC {
|
||||
panic("must be a func declaration");
|
||||
}
|
||||
P.String(" ");
|
||||
P.Blank();
|
||||
P.Block(d.list, true);
|
||||
}
|
||||
}
|
||||
@ -419,12 +470,12 @@ func (P *Printer) Declaration(d *Node.Decl) {
|
||||
// Program
|
||||
|
||||
func (P *Printer) Program(p *Node.Program) {
|
||||
P.String("package ");
|
||||
P.String(p.pos, "package ");
|
||||
P.Expr(p.ident);
|
||||
P.NewLine();
|
||||
for i := 0; i < p.decls.len(); i++ {
|
||||
P.Declaration(p.decls.at(i));
|
||||
P.Declaration(p.decls.at(i), false);
|
||||
}
|
||||
P.newl = true;
|
||||
P.String("");
|
||||
P.String(0, ""); // flush
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user