From a09b7fdd6c94dbf9a4f52140ce8043ad521a2cfb Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 16 Oct 2008 10:16:59 -0700 Subject: [PATCH] snapshot: - fallthrough stat, label decls - improved printing layout R=r OCL=17283 CL=17283 --- usr/gri/pretty/parser.go | 35 +++++++++---------- usr/gri/pretty/printer.go | 73 +++++++++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go index a4b4d56854..f195a8e73d 100644 --- a/usr/gri/pretty/parser.go +++ b/usr/gri/pretty/parser.go @@ -786,6 +786,8 @@ func (P *Parser) ParseSimpleStat() *Node.Stat { case Scanner.COLON: // label declaration if x.len() == 1 { + s = Node.NewStat(P.pos, Scanner.COLON); + s.expr = x; } else { P.Error(P.pos, "illegal label declaration"); } @@ -810,7 +812,7 @@ func (P *Parser) ParseSimpleStat() *Node.Stat { } else { P.Error(P.pos, "more then one operand"); } - P.Next(); + P.Next(); // consume "++" or "--" } else { s = Node.NewStat(P.pos, 0); // TODO give this a token value if x.len() == 1 { @@ -857,7 +859,7 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat { s := Node.NewStat(P.pos, tok); P.Expect(tok); - if P.tok == Scanner.IDENT { + if tok != Scanner.FALLTHROUGH && P.tok == Scanner.IDENT { s.expr = P.ParseIdent(); } @@ -911,7 +913,16 @@ func (P *Parser) ParseIfStat() *Node.Stat { if P.tok == Scanner.IF { s.post = P.ParseIfStat(); } else { - s.post = P.ParseStatement(); + // For 6g compliance - should really be P.ParseBlock() + t := P.ParseStatement(); + if t.tok != Scanner.LBRACE { + // wrap in a block if we don't have one + t1 := Node.NewStat(P.pos, Scanner.LBRACE); + t1.block = Node.NewList(); + t1.block.Add(t); + t = t1; + } + s.post = t; } } @@ -1031,17 +1042,6 @@ func (P *Parser) ParseSelectStat() *Node.Stat { } -func (P *Parser) ParseFallthroughStat() *Node.Stat { - P.Trace("FallthroughStat"); - - s := Node.NewStat(P.pos, Scanner.FALLTHROUGH); - P.Expect(Scanner.FALLTHROUGH); - - P.Ecart(); - return s; -} - - func (P *Parser) ParseRangeStat() *Node.Stat { P.Trace("RangeStat"); @@ -1073,7 +1073,8 @@ func (P *Parser) ParseStatement() *Node.Stat { s = Node.NewStat(P.pos, P.tok); s.decl = P.ParseDeclaration(); case Scanner.FUNC: - // for now we do not allow local function declarations + // for now we do not allow local function declarations, + // instead we assume this starts a function literal fallthrough; case // only the tokens that are legal top-level expression starts @@ -1085,7 +1086,7 @@ func (P *Parser) ParseStatement() *Node.Stat { s = P.ParseGoStat(); case Scanner.RETURN: s = P.ParseReturnStat(); - case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO: + case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH: s = P.ParseControlFlowStat(P.tok); case Scanner.LBRACE: s = Node.NewStat(P.pos, Scanner.LBRACE); @@ -1100,8 +1101,6 @@ func (P *Parser) ParseStatement() *Node.Stat { s = P.ParseRangeStat(); case Scanner.SELECT: s = P.ParseSelectStat(); - case Scanner.FALLTHROUGH: - s = P.ParseFallthroughStat(); default: P.ParseEmptyStat(); // for complete tracing output only } diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go index 2b5e70da17..2156ae7e7d 100644 --- a/usr/gri/pretty/printer.go +++ b/usr/gri/pretty/printer.go @@ -12,7 +12,7 @@ export type Printer struct { level int; // true scope level indent int; // indentation level semi bool; // pending ";" - newl bool; // pending "\n" + newl int; // pending "\n"'s } @@ -20,14 +20,19 @@ func (P *Printer) String(pos int, s string) { if P.semi && P.level > 0 { // no semicolons at level 0 print(";"); } - if P.newl { - print("\n"); + + if P.newl > 0 { + for i := P.newl; i > 0; i-- { + print("\n"); + } for i := P.indent; i > 0; i-- { print("\t"); } } + print(s); - P.newl, P.semi = false, false; + + P.semi, P.newl = false, 0; } @@ -41,18 +46,12 @@ func (P *Printer) Token(pos int, tok int) { } -func (P *Printer) NewLine() { // explicit "\n" - print("\n"); - P.semi, P.newl = false, true; -} - - func (P *Printer) OpenScope(paren string) { - P.semi, P.newl = false, false; + P.semi, P.newl = false, 0; P.String(0, paren); P.level++; P.indent++; - P.newl = true; + P.newl = 1; } @@ -61,7 +60,7 @@ func (P *Printer) CloseScope(paren string) { P.semi = false; P.String(0, paren); P.level--; - P.semi, P.newl = false, true; + P.semi, P.newl = false, 1; } @@ -95,7 +94,7 @@ func (P *Printer) Fields(list *Node.List) { if i > 0 { if prev == Scanner.TYPE { P.String(0, ";"); - P.newl = true; + P.newl = 1; } else if prev == x.tok { P.String(0, ", "); } else { @@ -105,7 +104,7 @@ func (P *Printer) Fields(list *Node.List) { P.Expr(x); prev = x.tok; } - P.newl = true; + P.newl = 1; } @@ -261,7 +260,7 @@ func (P *Printer) Stat(s *Node.Stat) func (P *Printer) StatementList(list *Node.List) { for i, n := 0, list.len(); i < n; i++ { P.Stat(list.at(i).(*Node.Stat)); - P.newl = true; + P.newl = 1; } } @@ -310,16 +309,27 @@ func (P *Printer) Stat(s *Node.Stat) { switch s.tok { case 0: // TODO use a real token const + // expression statement P.Expr(s.expr); P.semi = true; + case Scanner.COLON: + // label declaration + P.indent--; + P.Expr(s.expr); + P.Token(s.pos, s.tok); + P.indent++; + P.semi = false; + case Scanner.CONST, Scanner.TYPE, Scanner.VAR: + // declaration P.Declaration(s.decl, false); case Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN, Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN, Scanner.REM_ASSIGN, Scanner.AND_ASSIGN, Scanner.OR_ASSIGN, Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN: + // assignment P.Expr(s.lhs); P.Blank(); P.Token(s.pos, s.tok); @@ -333,6 +343,7 @@ func (P *Printer) Stat(s *Node.Stat) { P.semi = true; case Scanner.LBRACE: + // block P.Block(s.block, true); case Scanner.IF: @@ -340,7 +351,7 @@ func (P *Printer) Stat(s *Node.Stat) { P.ControlClause(s); P.Block(s.block, true); if s.post != nil { - P.newl = false; + P.newl = 0; P.String(0, " else "); P.Stat(s.post); } @@ -366,10 +377,12 @@ func (P *Printer) Stat(s *Node.Stat) { P.StatementList(s.block); P.CloseScope(""); - case Scanner.GO, Scanner.RETURN, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO: + case Scanner.GO, Scanner.RETURN, Scanner.FALLTHROUGH, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO: P.Token(s.pos, s.tok); - P.Blank(); - P.Expr(s.expr); + if s.expr != nil { + P.Blank(); + P.Expr(s.expr); + } P.semi = true; default: @@ -430,16 +443,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { P.OpenScope("("); for i := 0; i < d.list.len(); i++ { P.Declaration(d.list.at(i).(*Node.Decl), true); - P.newl, P.semi = true, true; + P.semi, P.newl = true, 1; } P.CloseScope(")"); } else { P.Expr(d.ident); + if d.typ != nil { P.Blank(); P.Type(d.typ); } + if d.val != nil { if d.tok == Scanner.IMPORT { P.Blank(); @@ -448,6 +463,7 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { } P.Expr(d.val); } + if d.list != nil { if d.tok != Scanner.FUNC { panic("must be a func declaration"); @@ -456,13 +472,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { P.Block(d.list, true); } } + + P.newl = 1; + // extra newline after a function declaration + if d.tok == Scanner.FUNC { + P.newl++; + } + // extra newline at the top level if P.level == 0 { - P.NewLine(); + P.newl++; } - - P.newl = true; } @@ -472,10 +493,10 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { func (P *Printer) Program(p *Node.Program) { P.String(p.pos, "package "); P.Expr(p.ident); - P.NewLine(); + P.newl = 2; for i := 0; i < p.decls.len(); i++ { P.Declaration(p.decls.at(i), false); } - P.newl = true; + P.newl = 1; P.String(0, ""); // flush } -- 2.50.0