- 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");
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);

View 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, ")");
}
}
}

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