1
0
mirror of https://github.com/golang/go synced 2024-11-26 14:26:51 -07:00

- fixed missing parens in some cases of unary expressions

- 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
This commit is contained in:
Robert Griesemer 2008-10-20 16:44:03 -07:00
parent 28912ce03f
commit 9d20c85ae9
3 changed files with 56 additions and 22 deletions

View File

@ -190,11 +190,16 @@ func (P *Parser) ParseIdentList() *AST.Expr {
P.Trace("IdentList"); P.Trace("IdentList");
x := P.ParseIdent(); x := P.ParseIdent();
if P.tok == Scanner.COMMA { for first := true; P.tok == Scanner.COMMA; {
pos := P.pos; pos := P.pos;
P.Next(); P.Next();
y := P.ParseIdentList(); y := P.ParseIdent();
if first {
x = P.NewExpr(pos, Scanner.COMMA, x, y); x = P.NewExpr(pos, Scanner.COMMA, x, y);
first = false;
} else {
x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
}
} }
P.Ecart(); 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); x := P.ParseExpression(0);
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
pos := P.pos; pos := P.pos;
@ -792,7 +797,7 @@ func (P *Parser) ParseCompositeLit(t *AST.Type) *AST.Expr {
x.t = t; x.t = t;
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
x.y = P.ParseCompositeList(); x.y = P.ParseCompositeElements();
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);

View File

@ -4,11 +4,14 @@
package Printer package Printer
import Strings "strings"
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
export type Printer struct { export type Printer struct {
pos int; // actual output position
// formatting control // formatting control
level int; // true scope level level int; // true scope level
indent int; // indentation level indent int; // indentation level
@ -22,6 +25,14 @@ 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) { func (P *Printer) String(pos int, s string) {
if P.semi && P.level > 0 { // no semicolons at level 0 if P.semi && P.level > 0 { // no semicolons at level 0
print(";"); print(";");
@ -226,9 +237,10 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
case Scanner.COMMA: case Scanner.COMMA:
// list // 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.String(x.pos, ", ");
P.Expr1(x.y, 0); P.Expr1(x.y, Scanner.LowestPrec);
case Scanner.PERIOD: case Scanner.PERIOD:
// selector or type guard // selector or type guard
@ -253,39 +265,41 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
// call // call
P.Expr1(x.x, Scanner.HighestPrec); P.Expr1(x.x, Scanner.HighestPrec);
P.String(x.pos, "("); P.String(x.pos, "(");
P.Expr1(x.y, 0); P.Expr1(x.y, Scanner.LowestPrec);
P.String(0, ")"); P.String(0, ")");
case Scanner.LBRACE: case Scanner.LBRACE:
// composite // composite
P.Type(x.t); P.Type(x.t);
P.String(x.pos, "{"); P.String(x.pos, "{");
P.Expr1(x.y, 0); P.Expr1(x.y, Scanner.LowestPrec);
P.String(0, "}"); P.String(0, "}");
default: default:
// unary and binary expressions // unary and binary expressions including ":" for pairs
if x.x == nil { prec := Scanner.UnaryPrec;
// unary expression if x.x != nil {
P.Token(x.pos, x.tok); prec = Scanner.Precedence(x.tok);
P.Expr1(x.y, Scanner.UnaryPrec); }
} else {
// binary expression: print ()'s if necessary
prec := Scanner.Precedence(x.tok);
if prec < prec1 { if prec < prec1 {
P.String(0, "("); P.String(0, "(");
} }
if x.x == nil {
// unary expression
P.Token(x.pos, x.tok);
} else {
// binary expression
P.Expr1(x.x, prec); P.Expr1(x.x, prec);
P.Blank(); P.Blank();
P.Token(x.pos, x.tok); P.Token(x.pos, x.tok);
P.Blank(); P.Blank();
}
P.Expr1(x.y, prec); P.Expr1(x.y, prec);
if prec < prec1 { if prec < prec1 {
P.String(0, ")"); P.String(0, ")");
} }
} }
} }
}
func (P *Printer) Expr(x *AST.Expr) { func (P *Printer) Expr(x *AST.Expr) {

View File

@ -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() { runtest() {
#echo "Testing silent mode" #echo "Testing silent mode"
cleanup cleanup
@ -79,6 +90,10 @@ runtest() {
#echo "Testing idempotency" #echo "Testing idempotency"
cleanup cleanup
$1 idempotent $2 $1 idempotent $2
#echo "Testing validity"
#cleanup
#$1 valid $2
} }