Commit 9d20c85a authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent 28912ce0
...@@ -190,11 +190,16 @@ func (P *Parser) ParseIdentList() *AST.Expr { ...@@ -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();
x = P.NewExpr(pos, Scanner.COMMA, x, y); 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(); P.Ecart();
...@@ -741,7 +746,7 @@ func (P *Parser) ParseCall(x *AST.Expr) *AST.Expr { ...@@ -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 { ...@@ -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);
......
...@@ -4,11 +4,14 @@ ...@@ -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,11 +25,19 @@ export type Printer struct { ...@@ -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) { 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(";");
} }
/* /*
for pos > P.cpos { for pos > P.cpos {
// we have a comment // we have a comment
...@@ -47,7 +58,7 @@ func (P *Printer) String(pos int, s string) { ...@@ -47,7 +58,7 @@ func (P *Printer) String(pos int, s string) {
} }
} }
*/ */
if P.newl > 0 { if P.newl > 0 {
for i := P.newl; i > 0; i-- { for i := P.newl; i > 0; i-- {
print("\n"); print("\n");
...@@ -226,9 +237,10 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) { ...@@ -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,36 +265,38 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) { ...@@ -253,36 +265,38 @@ 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
prec := Scanner.UnaryPrec;
if x.x != nil {
prec = Scanner.Precedence(x.tok);
}
if prec < prec1 {
P.String(0, "(");
}
if x.x == nil { if x.x == nil {
// unary expression // unary expression
P.Token(x.pos, x.tok); P.Token(x.pos, x.tok);
P.Expr1(x.y, Scanner.UnaryPrec);
} else { } else {
// binary expression: print ()'s if necessary // binary expression
prec := Scanner.Precedence(x.tok);
if prec < prec1 {
P.String(0, "(");
}
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); }
if prec < prec1 { P.Expr1(x.y, prec);
P.String(0, ")"); if prec < prec1 {
} P.String(0, ")");
} }
} }
} }
......
...@@ -71,6 +71,17 @@ idempotent() { ...@@ -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() { ...@@ -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
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment