]> Cypherpunks repositories - gostls13.git/commitdiff
snapshot
authorRobert Griesemer <gri@golang.org>
Wed, 15 Oct 2008 18:48:18 +0000 (11:48 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 15 Oct 2008 18:48:18 +0000 (11:48 -0700)
- fixed expression and statement printing
- missing: declarations, comments

R=r
OCL=17207
CL=17207

usr/gri/pretty/Makefile
usr/gri/pretty/node.go
usr/gri/pretty/parser.go
usr/gri/pretty/printer.go
usr/gri/pretty/scanner.go

index d1d2c277b21c844d7521b054123a420cfdc5e91a..8fd88a0ce99944b8ca18ee288ac94d7d89a6b1a8 100644 (file)
@@ -11,7 +11,22 @@ pretty: pretty.6
 test: pretty
        pretty -s *.go
        pretty -s ../gosrc/*.go
-       pretty -s $(GOROOT)/test/*.go
+       #pretty -s $(GOROOT)/test/*.go  # contains incorrect programs
+       pretty -s $(GOROOT)/test/235.go
+       pretty -s $(GOROOT)/test/args.go
+       pretty -s $(GOROOT)/test/bufiolib.go
+       pretty -s $(GOROOT)/test/char_lit.go
+       pretty -s $(GOROOT)/test/complit.go
+       pretty -s $(GOROOT)/test/const.go
+       pretty -s $(GOROOT)/test/dialgoogle.go
+       pretty -s $(GOROOT)/test/empty.go
+       pretty -s $(GOROOT)/test/env.go
+       pretty -s $(GOROOT)/test/float_lit.go
+       pretty -s $(GOROOT)/test/fmt_test.go
+       pretty -s $(GOROOT)/test/for.go
+       pretty -s $(GOROOT)/test/func.go
+       pretty -s $(GOROOT)/test/func1.go
+       pretty -s $(GOROOT)/test/func2.go
        pretty -s $(GOROOT)/src/pkg/*.go
        pretty -s $(GOROOT)/src/lib/*.go
        pretty -s $(GOROOT)/src/lib/*/*.go
index 93f646b53098fdf1ddab97fcd5d073329b963af2..51ea1e68136a7e09e251f49fdee39775f86d0aca 100644 (file)
@@ -6,9 +6,9 @@ package Node
 
 import Scanner "scanner"
 
-type Node interface {}
 
 type (
+       Node interface {};
        Type struct;
        Expr struct;
        Stat struct;
@@ -56,20 +56,6 @@ func (p *List) Add (x Node) {
 }
 
 
-/*
-func (p *List) Print() {
-       print("(");
-       for i, n := 0, p.len(); i < n; i++ {
-               if i > 0 {
-                       print(", ");
-               }
-               p.at(i).Print();
-       }
-       print(")");
-}
-*/
-
-
 export func NewList() *List {
        p := new(List);
        p.a = new([] Node, 10) [0 : 0];
@@ -110,19 +96,11 @@ export func NewType(pos, tok int) *Type {
 // Expression pairs are represented as binary expressions with operator ":"
 // Expression lists are represented as binary expressions with operator ","
 
-export type Val struct {
-       i int;
-       f float;
-       s string;
-       t *Type;
-}
-
-
 export type Expr struct {
        pos, tok int;
        x, y *Expr;  // binary (x, y) and unary (y) expressions
-       ident string;  // identifiers
-       val *Val;  // literals
+       s string;  // identifiers and literals
+       t *Type;  // declarations and composite literals
 }
 
 
@@ -138,28 +116,6 @@ func (x *Expr) len() int {
 }
 
 
-/*
-func (x *Expr) Print() {
-       switch {
-       case x == nil:
-               print("nil");
-       case x.val != nil:
-               print(x.val.s);
-       default:
-               if x.x == nil {
-                       print(Scanner.TokenName(x.tok));
-               } else {
-                       x.x.Print();
-                       print(" ");
-                       print(Scanner.TokenName(x.tok));
-                       print(" ");
-               }
-               x.y.Print();
-       }
-}
-*/
-
-
 export func NewExpr(pos, tok int, x, y *Expr) *Expr {
        e := new(Expr);
        e.pos, e.tok, e.x, e.y = pos, tok, x, y;
@@ -167,16 +123,9 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr {
 }
 
 
-export func NewIdent(pos int, ident string) *Expr {
-       e := new(Expr);
-       e.pos, e.tok, e.ident = pos, Scanner.IDENT, ident;
-       return e;
-}
-
-
-export func NewVal(pos, tok int, val *Val) *Expr {
+export func NewLit(pos, tok int, s string) *Expr {
        e := new(Expr);
-       e.pos, e.tok, e.val = pos, tok, val;
+       e.pos, e.tok, e.s = pos, tok, s;
        return e;
 }
 
@@ -186,9 +135,8 @@ export func NewVal(pos, tok int, val *Val) *Expr {
 
 export type Stat struct {
        pos, tok int;
-       init *Stat;
-       expr *Expr;
-       post *Stat;
+       init, post *Stat;
+       lhs, expr *Expr;
        block *List;
        decl *Decl;
 }
@@ -204,14 +152,6 @@ export func NewStat(pos, tok int) *Stat {
 // ----------------------------------------------------------------------------
 // Declarations
 
-export type VarDeclList struct {
-}
-
-
-func (d *VarDeclList) Print() {
-}
-
-
 export type Decl struct {
        pos, tok int;
        exported bool;
index 4dcacdc16f66c7b6f6f1ad629d2a426d40d77e07..a51683d678b2a36aa69e87837092050fdf1a803f 100644 (file)
@@ -66,7 +66,7 @@ func (P *Parser) Next() {
        P.opt_semi = false;
        if P.verbose {
                P.PrintIndent();
-               print("[", P.pos, "] ", Scanner.TokenName(P.tok), "\n");
+               print("[", P.pos, "] ", Scanner.TokenString(P.tok), "\n");
        }
 }
 
@@ -89,7 +89,7 @@ func (P *Parser) Error(pos int, msg string) {
 
 func (P *Parser) Expect(tok int) {
        if P.tok != tok {
-               P.Error(P.pos, "expected '" + Scanner.TokenName(tok) + "', found '" + Scanner.TokenName(P.tok) + "'");
+               P.Error(P.pos, "expected '" + Scanner.TokenString(tok) + "', found '" + Scanner.TokenString(P.tok) + "'");
        }
        P.Next();  // make progress in any case
 }
@@ -116,10 +116,10 @@ func (P *Parser) ParseIdent() *Node.Expr {
 
        var x *Node.Expr;
        if P.tok == Scanner.IDENT {
-               x = Node.NewIdent(P.pos, P.val);
+               x = Node.NewLit(P.pos, Scanner.IDENT, P.val);
                if P.verbose {
                        P.PrintIndent();
-                       print("Ident = \"", x.val, "\"\n");
+                       print("Ident = \"", x.s, "\"\n");
                }
                P.Next();
        } else {
@@ -238,24 +238,35 @@ func (P *Parser) ParseChannelType() *Node.Type {
 }
 
 
-func (P *Parser) ParseVarDeclList() *Node.VarDeclList {
+func (P *Parser) ParseVarDeclList() {
        P.Trace("VarDeclList");
 
-       list := new(Node.VarDeclList);
-       P.ParseType();
+       list := Node.NewList();
+       list.Add(P.ParseType());
        for P.tok == Scanner.COMMA {
                P.Next();
-               P.ParseType();
+               list.Add(P.ParseType());
        }
-       
+
        typ := P.TryType();
 
-       if typ == nil {
-               // we must have a list of types
+       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++ {
+                       t := list.at(i).(*Node.Type);
+                       if t.tok == Scanner.IDENT && t.expr.tok == Scanner.IDENT {
+                               x := t.expr;
+                       } else {
+                               P.Error(t.pos, "identifier expected");
+                       }
+               }
+       } else {
+               // all list entries are types
+               
        }
        
        P.Ecart();
-       return list;
 }
 
 
@@ -263,10 +274,10 @@ func (P *Parser) ParseParameterList() *Node.List {
        P.Trace("ParameterList");
        
        list := Node.NewList();
-       list.Add(P.ParseVarDeclList());
+       P.ParseVarDeclList();
        for P.tok == Scanner.COMMA {
                P.Next();
-               list.Add(P.ParseVarDeclList());
+               P.ParseVarDeclList();
        }
        
        P.Ecart();
@@ -394,7 +405,7 @@ func (P *Parser) ParseStructType() *Node.Type {
                P.Next();
                t.list = Node.NewList();
                for P.tok == Scanner.IDENT {
-                       t.list.Add(P.ParseVarDeclList());
+                       P.ParseVarDeclList();
                        if P.tok != Scanner.RBRACE {
                                P.Expect(Scanner.SEMICOLON);
                        }
@@ -529,18 +540,13 @@ func (P *Parser) ParseOperand() *Node.Expr {
                P.expr_lev--;
                P.Expect(Scanner.RPAREN);
 
-       case Scanner.INT, Scanner.FLOAT:
-               val := new(Node.Val);
-               val.s = P.val;
-               x = Node.NewVal(P.pos, P.tok, val);
+       case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
+               x = Node.NewLit(P.pos, P.tok, P.val);
                P.Next();
-
-       case Scanner.STRING:
-               val := new(Node.Val);
-               val.s = P.val;
-               x = Node.NewVal(P.pos, Scanner.STRING, val);
-               for P.Next(); P.tok == Scanner.STRING; P.Next() {
-                       val.s += P.val;
+               if x.tok == Scanner.STRING {
+                       for ; P.tok == Scanner.STRING; P.Next() {
+                               x.s += P.val;
+                       }
                }
 
        case Scanner.FUNC:
@@ -744,12 +750,12 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
        P.Trace("SimpleStat");
        
        var s *Node.Stat;
-       list := P.ParseExpressionList();
+       x := P.ParseExpressionList();
        
        switch P.tok {
        case Scanner.COLON:
                // label declaration
-               if list.len() == 1 {
+               if x.len() == 1 {
                } else {
                        P.Error(P.pos, "illegal label declaration");
                }
@@ -763,21 +769,22 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
                Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
                s = Node.NewStat(P.pos, P.tok);
                P.Next();
+               s.lhs = x;
                s.expr = P.ParseExpressionList();
 
        default:
                if P.tok == Scanner.INC || P.tok == Scanner.DEC {
                        s = Node.NewStat(P.pos, P.tok);
-                       if list.len() == 1 {
-                               s.expr = list;
+                       if x.len() == 1 {
+                               s.expr = x;
                        } else {
                                P.Error(P.pos, "more then one operand");
                        }
                        P.Next();
                } else {
                        s = Node.NewStat(P.pos, 0);  // TODO give this a token value
-                       if list.len() == 1 {
-                               s.expr = list;
+                       if x.len() == 1 {
+                               s.expr = x;
                        } else {
                                P.Error(P.pos, "syntax error");
                        }
@@ -830,7 +837,7 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat {
 
 
 func (P *Parser) ParseControlClause(keyword int) *Node.Stat {
-       P.Trace("StatHeader");
+       P.Trace("ControlClause");
        
        s := Node.NewStat(P.pos, keyword);
        P.Expect(keyword);
@@ -872,9 +879,9 @@ func (P *Parser) ParseIfStat() *Node.Stat {
        if P.tok == Scanner.ELSE {
                P.Next();
                if P.tok == Scanner.IF {
-                       P.ParseIfStat();
+                       s.post = P.ParseIfStat();
                } else {
-                       P.ParseStatement();
+                       s.post = P.ParseStatement();
                }
        }
        
@@ -1005,12 +1012,6 @@ func (P *Parser) ParseFallthroughStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseEmptyStat() {
-       P.Trace("EmptyStat");
-       P.Ecart();
-}
-
-
 func (P *Parser) ParseRangeStat() *Node.Stat {
        P.Trace("RangeStat");
        
@@ -1026,6 +1027,12 @@ func (P *Parser) ParseRangeStat() *Node.Stat {
 }
 
 
+func (P *Parser) ParseEmptyStat() {
+       P.Trace("EmptyStat");
+       P.Ecart();
+}
+
+
 func (P *Parser) ParseStatement() *Node.Stat {
        P.Trace("Statement");
        indent := P.indent;
index 1bd44fd168cee7fadff61f784e372daf597238a0..76b9dd9dce4792d326433b4c21fee6e139837a69 100644 (file)
@@ -13,7 +13,6 @@ export type Printer struct {
        indent int;  // indentation level
        semi bool;  // pending ";"
        newl bool;  // pending "\n"
-       prec int;  // operator precedence
 }
 
 
@@ -32,6 +31,11 @@ func (P *Printer) String(s string) {
 }
 
 
+func (P *Printer) Token(tok int) {
+       P.String(Scanner.TokenString(tok));
+}
+
+
 func (P *Printer) NewLine() {  // explicit "\n"
        print("\n");
        P.semi, P.newl = false, true;
@@ -139,106 +143,68 @@ func (P *Printer) Type(t *Node.Type) {
 // ----------------------------------------------------------------------------
 // Expressions
 
-func (P *Printer) Val(tok int, val *Node.Val) {
-       P.String(val.s);  // for now
-}
-
-
-func (P *Printer) Expr(x *Node.Expr) {
+func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
        if x == nil {
                return;  // empty expression list
        }
 
        switch x.tok {
-       case Scanner.IDENT:
-               P.String(x.ident);
-
-       case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
-               P.Val(x.tok, x.val);
-
-       case Scanner.LPAREN:
-               // calls
-               P.Expr(x.x);
-               P.String("(");
-               P.Expr(x.y);
-               P.String(")");
+       case Scanner.IDENT, Scanner.INT, Scanner.STRING, Scanner.FLOAT:
+               P.String(x.s);
+
+       case Scanner.COMMA:
+               P.Expr1(x.x, 0);
+               P.String(", ");
+               P.Expr1(x.y, 0);
+
+       case Scanner.PERIOD:
+               P.Expr1(x.x, 8);
+               P.String(".");
+               P.Expr1(x.y, 8);
                
        case Scanner.LBRACK:
-               P.Expr(x.x);
+               P.Expr1(x.x, 8);
                P.String("[");
-               P.Expr(x.y);
+               P.Expr1(x.y, 0);
                P.String("]");
+
+       case Scanner.LPAREN:
+               P.Expr1(x.x, 8);
+               P.String("(");
+               P.Expr1(x.y, 0);
+               P.String(")");
                
        default:
                if x.x == nil {
                        // unary expression
-                       P.String(Scanner.TokenName(x.tok));
-                       P.Expr(x.y);
+                       P.Token(x.tok);
+                       P.Expr1(x.y, 7);
                } else {
                        // binary expression: print ()'s if necessary
-                       // TODO: pass precedence as parameter instead
-                       outer := P.prec;
-                       P.prec = Scanner.Precedence(x.tok);
-                       if P.prec < outer {
+                       prec := Scanner.Precedence(x.tok);
+                       if prec < prec1 {
                                print("(");
                        }
-                       P.Expr(x.x);
-                       if x.tok != Scanner.PERIOD && x.tok != Scanner.COMMA {
-                               P.String(" ");
-                       }
-                       P.String(Scanner.TokenName(x.tok));
-                       if x.tok != Scanner.PERIOD {
-                               P.String(" ");
-                       }
-                       P.Expr(x.y);
-                       if P.prec < outer {
+                       P.Expr1(x.x, prec);
+                       P.String(" ");
+                       P.Token(x.tok);
+                       P.String(" ");
+                       P.Expr1(x.y, prec);
+                       if prec < prec1 {
                                print(")");
                        }
-                       P.prec = outer; 
                }
        }
 }
 
 
-// ----------------------------------------------------------------------------
-// Statements
-
-/*
-func (P *Printer) DoLabel(x *AST.Label) {
-       P.indent--;
-       P.newl = true;
-       P.Print(x.ident);
-       P.String(":");
-       P.indent++;
-}
-
-
-func (P *Printer) DoExprStat(x *AST.ExprStat) {
-       P.Print(x.expr);
-       P.semi = true;
-}
-
-
-func (P *Printer) DoAssignment(x *AST.Assignment) {
-       P.PrintList(x.lhs);
-       P.String(" " + Scanner.TokenName(x.tok) + " ");
-       P.PrintList(x.rhs);
-       P.semi = true;
+func (P *Printer) Expr(x *Node.Expr) {
+       P.Expr1(x, 0);
 }
 
 
-func (P *Printer) DoIfStat(x *AST.IfStat) {
-       P.String("if");
-       P.PrintControlClause(x.ctrl);
-       P.DoBlock(x.then);
-       if x.has_else {
-               P.newl = false;
-               P.String(" else ");
-               P.Print(x.else_);
-       }
-}
-*/
-
+// ----------------------------------------------------------------------------
+// Statements
 
 func (P *Printer) Stat(s *Node.Stat)
 
@@ -250,9 +216,15 @@ func (P *Printer) StatementList(list *Node.List) {
 }
 
 
-func (P *Printer) Block(list *Node.List) {
+func (P *Printer) Block(list *Node.List, indent bool) {
        P.OpenScope("{");
+       if !indent {
+               P.indent--;
+       }
        P.StatementList(list);
+       if !indent {
+               P.indent++;
+       }
        P.CloseScope("}");
 }
 
@@ -269,7 +241,7 @@ func (P *Printer) ControlClause(s *Node.Stat) {
                P.Expr(s.expr);
                P.semi = false;
        }
-       if s.post != nil {
+       if s.tok == Scanner.FOR && s.post != nil {
                P.semi = true;
                P.String(" ");
                P.Stat(s.post);
@@ -286,6 +258,7 @@ func (P *Printer) Stat(s *Node.Stat) {
                P.String("<nil stat>");
                return;
        }
+
        switch s.tok {
        case 0: // TODO use a real token const
                P.Expr(s.expr);
@@ -298,23 +271,43 @@ func (P *Printer) Stat(s *Node.Stat) {
                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.String(Scanner.TokenName(s.tok));
+               P.Expr(s.lhs);
+               P.String(" ");
+               P.Token(s.tok);
                P.String(" ");
                P.Expr(s.expr);
                P.semi = true;
 
        case Scanner.INC, Scanner.DEC:
                P.Expr(s.expr);
-               P.String(Scanner.TokenName(s.tok));
+               P.Token(s.tok);
                P.semi = true;
 
-       case Scanner.IF, Scanner.FOR, Scanner.SWITCH, Scanner.SELECT:
-               P.String(Scanner.TokenName(s.tok));
+       case Scanner.LBRACE:
+               P.Block(s.block, true);
+
+       case Scanner.IF:
+               P.String("if");
                P.ControlClause(s);
-               P.Block(s.block);
-               
+               P.Block(s.block, true);
+               if s.post != nil {
+                       P.newl = false;
+                       P.String(" else ");
+                       P.Stat(s.post);
+               }
+
+       case Scanner.FOR:
+               P.String("for");
+               P.ControlClause(s);
+               P.Block(s.block, true);
+
+       case Scanner.SWITCH, Scanner.SELECT:
+               P.Token(s.tok);
+               P.ControlClause(s);
+               P.Block(s.block, false);
+
        case Scanner.CASE, Scanner.DEFAULT:
-               P.String(Scanner.TokenName(s.tok));
+               P.Token(s.tok);
                if s.expr != nil {
                        P.String(" ");
                        P.Expr(s.expr);
@@ -323,9 +316,10 @@ func (P *Printer) Stat(s *Node.Stat) {
                P.OpenScope("");
                P.StatementList(s.block);
                P.CloseScope("");
-               
+
        case Scanner.GO, Scanner.RETURN, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
-               P.String("go ");
+               P.Token(s.tok);
+               P.String(" ");
                P.Expr(s.expr);
                P.semi = true;
 
@@ -341,15 +335,6 @@ func (P *Printer) Stat(s *Node.Stat) {
 
 
 /*
-func (P *Printer) DoImportDecl(x *AST.ImportDecl) {
-       if x.ident != nil {
-               P.Print(x.ident);
-               P.String(" ");
-       }
-       P.String(x.file);
-}
-
-
 func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
        P.String("func ");
        if x.typ.recv != nil {
@@ -383,7 +368,7 @@ func (P *Printer) Declaration(d *Node.Decl) {
                if d.exported {
                        P.String("export ");
                }
-               P.String(Scanner.TokenName(d.tok));
+               P.Token(d.tok);
                P.String(" ");
        }
 
@@ -417,10 +402,11 @@ func (P *Printer) Declaration(d *Node.Decl) {
                                panic("must be a func declaration");
                        }
                        P.String(" ");
-                       P.Block(d.list);
+                       P.Block(d.list, true);
                }
        }
 
+       // extra newline at the top level
        if P.level == 0 {
                P.NewLine();
        }
index 56ab9956ad5e53caccbd6e5c598e1976e35d8381..9212927207973cf5bd12ed547c7b229d0ac1d641 100644 (file)
@@ -106,7 +106,7 @@ export const (
 )
 
 
-export func TokenName(tok int) string {
+export func TokenString(tok int) string {
        switch (tok) {
        case ILLEGAL: return "ILLEGAL";
        
@@ -233,7 +233,7 @@ func init() {
        Keywords = new(map [string] int);
        
        for i := KEYWORDS_BEG + 1; i < KEYWORDS_END; i++ {
-         Keywords[TokenName(i)] = i;
+         Keywords[TokenString(i)] = i;
        }
        
        // Provide column information in error messages for gri only...