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();
}
-func (P *Parser) ParseCompositeList() *AST.Expr {
+func (P *Parser) ParseCompositeElements() *AST.Expr {
x := P.ParseExpression(0);
if P.tok == Scanner.COMMA {
pos := P.pos;
x.t = t;
P.Expect(Scanner.LBRACE);
if P.tok != Scanner.RBRACE {
- x.y = P.ParseCompositeList();
+ x.y = P.ParseCompositeElements();
}
P.Expect(Scanner.RBRACE);
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
}
+// 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
}
}
*/
-
+
if P.newl > 0 {
for i := P.newl; i > 0; i-- {
print("\n");
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
// 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, ")");
}
}
}