]> Cypherpunks repositories - gostls13.git/commitdiff
- fixed missing parens in some cases of unary expressions
authorRobert Griesemer <gri@golang.org>
Mon, 20 Oct 2008 23:44:03 +0000 (16:44 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 20 Oct 2008 23:44:03 +0000 (16:44 -0700)
- added validation test verifying that pretty output compiles with 6g again (disabled at the moment)
- replaced another recursive function with an interative solution

R=r
OCL=17505
CL=17505

usr/gri/pretty/parser.go
usr/gri/pretty/printer.go
usr/gri/pretty/test.sh

index 81e8af8f7f80bdf37cef9185f22d4f5d297fca81..e74416663aeef1d504f317ce10f4282b46146b77 100644 (file)
@@ -190,11 +190,16 @@ func (P *Parser) ParseIdentList() *AST.Expr {
        P.Trace("IdentList");
 
        x := P.ParseIdent();
-       if P.tok == Scanner.COMMA {
+       for first := true; P.tok == Scanner.COMMA; {
                pos := P.pos;
                P.Next();
-               y := P.ParseIdentList();
-               x = P.NewExpr(pos, Scanner.COMMA, x, y);
+               y := P.ParseIdent();
+               if first {
+                       x = P.NewExpr(pos, Scanner.COMMA, x, y);
+                       first = false;
+               } else {
+                       x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
+               }
        }
 
        P.Ecart();
@@ -741,7 +746,7 @@ func (P *Parser) ParseCall(x *AST.Expr) *AST.Expr {
 }
 
 
-func (P *Parser) ParseCompositeList() *AST.Expr {
+func (P *Parser) ParseCompositeElements() *AST.Expr {
        x := P.ParseExpression(0);
        if P.tok == Scanner.COMMA {
                pos := P.pos;
@@ -792,7 +797,7 @@ func (P *Parser) ParseCompositeLit(t *AST.Type) *AST.Expr {
        x.t = t;
        P.Expect(Scanner.LBRACE);
        if P.tok != Scanner.RBRACE {
-               x.y = P.ParseCompositeList();
+               x.y = P.ParseCompositeElements();
        }
        P.Expect(Scanner.RBRACE);
        
index 3072b6a46e971b2afc2aa9d6a78f022493b17899..60f1c63bbcf624025da85a4b381fb2d36189e8d2 100644 (file)
@@ -4,11 +4,14 @@
 
 package Printer
 
+import Strings "strings"
 import Scanner "scanner"
 import AST "ast"
 
 
 export type Printer struct {
+       pos int;  // actual output position
+
        // formatting control
        level int;  // true scope level
        indent int;  // indentation level
@@ -22,11 +25,19 @@ export type Printer struct {
 }
 
 
+// Bottleneck interface - all output goes through here.
+func (P *Printer) print(s string) {
+       print(s);
+       // TODO do we need the code below?
+       // P.pos += Strings.utflen(s);
+}
+
+
 func (P *Printer) String(pos int, s string) {
        if P.semi && P.level > 0 {  // no semicolons at level 0
                print(";");
        }
-       
+
        /*
        for pos > P.cpos {
                // we have a comment
@@ -47,7 +58,7 @@ func (P *Printer) String(pos int, s string) {
                }
        }
        */
-       
+
        if P.newl > 0 {
                for i := P.newl; i > 0; i-- {
                        print("\n");
@@ -226,9 +237,10 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
 
        case Scanner.COMMA:
                // list
-               P.Expr1(x.x, 0);
+               // (don't use binary expression printing because of different spacing)
+               P.Expr1(x.x, Scanner.LowestPrec);
                P.String(x.pos, ", ");
-               P.Expr1(x.y, 0);
+               P.Expr1(x.y, Scanner.LowestPrec);
 
        case Scanner.PERIOD:
                // selector or type guard
@@ -253,36 +265,38 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
                // call
                P.Expr1(x.x, Scanner.HighestPrec);
                P.String(x.pos, "(");
-               P.Expr1(x.y, 0);
+               P.Expr1(x.y, Scanner.LowestPrec);
                P.String(0, ")");
 
        case Scanner.LBRACE:
                // composite
                P.Type(x.t);
                P.String(x.pos, "{");
-               P.Expr1(x.y, 0);
+               P.Expr1(x.y, Scanner.LowestPrec);
                P.String(0, "}");
                
        default:
-               // unary and binary expressions
+               // unary and binary expressions including ":" for pairs
+               prec := Scanner.UnaryPrec;
+               if x.x != nil {
+                       prec = Scanner.Precedence(x.tok);
+               }
+               if prec < prec1 {
+                       P.String(0, "(");
+               }
                if x.x == nil {
                        // unary expression
                        P.Token(x.pos, x.tok);
-                       P.Expr1(x.y, Scanner.UnaryPrec);
                } else {
-                       // binary expression: print ()'s if necessary
-                       prec := Scanner.Precedence(x.tok);
-                       if prec < prec1 {
-                               P.String(0, "(");
-                       }
+                       // binary expression
                        P.Expr1(x.x, prec);
                        P.Blank();
                        P.Token(x.pos, x.tok);
                        P.Blank();
-                       P.Expr1(x.y, prec);
-                       if prec < prec1 {
-                               P.String(0, ")");
-                       }
+               }
+               P.Expr1(x.y, prec);
+               if prec < prec1 {
+                       P.String(0, ")");
                }
        }
 }
index de0003d862d43341d60e726febb32f7b1d54a5b6..2af377038560264533d348c4baf22078f2dd0d69 100755 (executable)
@@ -71,6 +71,17 @@ idempotent() {
 }
 
 
+valid() {
+       cleanup
+       pretty $1 > $TMP1
+       6g -o /dev/null $TMP1
+       if [ $? != 0 ]; then
+               echo "Error (validity test): test.sh $1"
+               exit 1
+       fi
+}
+
+
 runtest() {
        #echo "Testing silent mode"
        cleanup
@@ -79,6 +90,10 @@ runtest() {
        #echo "Testing idempotency"
        cleanup
        $1 idempotent $2
+
+       #echo "Testing validity"
+       #cleanup
+       #$1 valid $2
 }