Commit a09b7fdd authored by Robert Griesemer's avatar Robert Griesemer

snapshot:

- fallthrough stat, label decls
- improved printing layout

R=r
OCL=17283
CL=17283
parent 59167e5b
...@@ -786,6 +786,8 @@ func (P *Parser) ParseSimpleStat() *Node.Stat { ...@@ -786,6 +786,8 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
case Scanner.COLON: case Scanner.COLON:
// label declaration // label declaration
if x.len() == 1 { if x.len() == 1 {
s = Node.NewStat(P.pos, Scanner.COLON);
s.expr = x;
} else { } else {
P.Error(P.pos, "illegal label declaration"); P.Error(P.pos, "illegal label declaration");
} }
...@@ -810,7 +812,7 @@ func (P *Parser) ParseSimpleStat() *Node.Stat { ...@@ -810,7 +812,7 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
} else { } else {
P.Error(P.pos, "more then one operand"); P.Error(P.pos, "more then one operand");
} }
P.Next(); P.Next(); // consume "++" or "--"
} else { } else {
s = Node.NewStat(P.pos, 0); // TODO give this a token value s = Node.NewStat(P.pos, 0); // TODO give this a token value
if x.len() == 1 { if x.len() == 1 {
...@@ -857,7 +859,7 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat { ...@@ -857,7 +859,7 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat {
s := Node.NewStat(P.pos, tok); s := Node.NewStat(P.pos, tok);
P.Expect(tok); P.Expect(tok);
if P.tok == Scanner.IDENT { if tok != Scanner.FALLTHROUGH && P.tok == Scanner.IDENT {
s.expr = P.ParseIdent(); s.expr = P.ParseIdent();
} }
...@@ -911,7 +913,16 @@ func (P *Parser) ParseIfStat() *Node.Stat { ...@@ -911,7 +913,16 @@ func (P *Parser) ParseIfStat() *Node.Stat {
if P.tok == Scanner.IF { if P.tok == Scanner.IF {
s.post = P.ParseIfStat(); s.post = P.ParseIfStat();
} else { } 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 { ...@@ -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 { func (P *Parser) ParseRangeStat() *Node.Stat {
P.Trace("RangeStat"); P.Trace("RangeStat");
...@@ -1073,7 +1073,8 @@ func (P *Parser) ParseStatement() *Node.Stat { ...@@ -1073,7 +1073,8 @@ func (P *Parser) ParseStatement() *Node.Stat {
s = Node.NewStat(P.pos, P.tok); s = Node.NewStat(P.pos, P.tok);
s.decl = P.ParseDeclaration(); s.decl = P.ParseDeclaration();
case Scanner.FUNC: 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; fallthrough;
case case
// only the tokens that are legal top-level expression starts // only the tokens that are legal top-level expression starts
...@@ -1085,7 +1086,7 @@ func (P *Parser) ParseStatement() *Node.Stat { ...@@ -1085,7 +1086,7 @@ func (P *Parser) ParseStatement() *Node.Stat {
s = P.ParseGoStat(); s = P.ParseGoStat();
case Scanner.RETURN: case Scanner.RETURN:
s = P.ParseReturnStat(); s = P.ParseReturnStat();
case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO: case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH:
s = P.ParseControlFlowStat(P.tok); s = P.ParseControlFlowStat(P.tok);
case Scanner.LBRACE: case Scanner.LBRACE:
s = Node.NewStat(P.pos, Scanner.LBRACE); s = Node.NewStat(P.pos, Scanner.LBRACE);
...@@ -1100,8 +1101,6 @@ func (P *Parser) ParseStatement() *Node.Stat { ...@@ -1100,8 +1101,6 @@ func (P *Parser) ParseStatement() *Node.Stat {
s = P.ParseRangeStat(); s = P.ParseRangeStat();
case Scanner.SELECT: case Scanner.SELECT:
s = P.ParseSelectStat(); s = P.ParseSelectStat();
case Scanner.FALLTHROUGH:
s = P.ParseFallthroughStat();
default: default:
P.ParseEmptyStat(); // for complete tracing output only P.ParseEmptyStat(); // for complete tracing output only
} }
......
...@@ -12,7 +12,7 @@ export type Printer struct { ...@@ -12,7 +12,7 @@ export type Printer struct {
level int; // true scope level level int; // true scope level
indent int; // indentation level indent int; // indentation level
semi bool; // pending ";" semi bool; // pending ";"
newl bool; // pending "\n" newl int; // pending "\n"'s
} }
...@@ -20,14 +20,19 @@ func (P *Printer) String(pos int, s string) { ...@@ -20,14 +20,19 @@ 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(";");
} }
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-- { for i := P.indent; i > 0; i-- {
print("\t"); print("\t");
} }
} }
print(s); 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) { ...@@ -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) { func (P *Printer) OpenScope(paren string) {
P.semi, P.newl = false, false; P.semi, P.newl = false, 0;
P.String(0, paren); P.String(0, paren);
P.level++; P.level++;
P.indent++; P.indent++;
P.newl = true; P.newl = 1;
} }
...@@ -61,7 +60,7 @@ func (P *Printer) CloseScope(paren string) { ...@@ -61,7 +60,7 @@ func (P *Printer) CloseScope(paren string) {
P.semi = false; P.semi = false;
P.String(0, paren); P.String(0, paren);
P.level--; 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) { ...@@ -95,7 +94,7 @@ func (P *Printer) Fields(list *Node.List) {
if i > 0 { if i > 0 {
if prev == Scanner.TYPE { if prev == Scanner.TYPE {
P.String(0, ";"); P.String(0, ";");
P.newl = true; P.newl = 1;
} else if prev == x.tok { } else if prev == x.tok {
P.String(0, ", "); P.String(0, ", ");
} else { } else {
...@@ -105,7 +104,7 @@ func (P *Printer) Fields(list *Node.List) { ...@@ -105,7 +104,7 @@ func (P *Printer) Fields(list *Node.List) {
P.Expr(x); P.Expr(x);
prev = x.tok; prev = x.tok;
} }
P.newl = true; P.newl = 1;
} }
...@@ -261,7 +260,7 @@ func (P *Printer) Stat(s *Node.Stat) ...@@ -261,7 +260,7 @@ func (P *Printer) Stat(s *Node.Stat)
func (P *Printer) StatementList(list *Node.List) { func (P *Printer) StatementList(list *Node.List) {
for i, n := 0, list.len(); i < n; i++ { for i, n := 0, list.len(); i < n; i++ {
P.Stat(list.at(i).(*Node.Stat)); P.Stat(list.at(i).(*Node.Stat));
P.newl = true; P.newl = 1;
} }
} }
...@@ -310,16 +309,27 @@ func (P *Printer) Stat(s *Node.Stat) { ...@@ -310,16 +309,27 @@ func (P *Printer) Stat(s *Node.Stat) {
switch s.tok { switch s.tok {
case 0: // TODO use a real token const case 0: // TODO use a real token const
// expression statement
P.Expr(s.expr); P.Expr(s.expr);
P.semi = true; 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: case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
// declaration
P.Declaration(s.decl, false); P.Declaration(s.decl, false);
case Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN, case Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN,
Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN, Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN,
Scanner.REM_ASSIGN, Scanner.AND_ASSIGN, Scanner.OR_ASSIGN, Scanner.REM_ASSIGN, Scanner.AND_ASSIGN, Scanner.OR_ASSIGN,
Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN: Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
// assignment
P.Expr(s.lhs); P.Expr(s.lhs);
P.Blank(); P.Blank();
P.Token(s.pos, s.tok); P.Token(s.pos, s.tok);
...@@ -333,6 +343,7 @@ func (P *Printer) Stat(s *Node.Stat) { ...@@ -333,6 +343,7 @@ func (P *Printer) Stat(s *Node.Stat) {
P.semi = true; P.semi = true;
case Scanner.LBRACE: case Scanner.LBRACE:
// block
P.Block(s.block, true); P.Block(s.block, true);
case Scanner.IF: case Scanner.IF:
...@@ -340,7 +351,7 @@ func (P *Printer) Stat(s *Node.Stat) { ...@@ -340,7 +351,7 @@ func (P *Printer) Stat(s *Node.Stat) {
P.ControlClause(s); P.ControlClause(s);
P.Block(s.block, true); P.Block(s.block, true);
if s.post != nil { if s.post != nil {
P.newl = false; P.newl = 0;
P.String(0, " else "); P.String(0, " else ");
P.Stat(s.post); P.Stat(s.post);
} }
...@@ -366,10 +377,12 @@ func (P *Printer) Stat(s *Node.Stat) { ...@@ -366,10 +377,12 @@ func (P *Printer) Stat(s *Node.Stat) {
P.StatementList(s.block); P.StatementList(s.block);
P.CloseScope(""); 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.Token(s.pos, s.tok);
P.Blank(); if s.expr != nil {
P.Expr(s.expr); P.Blank();
P.Expr(s.expr);
}
P.semi = true; P.semi = true;
default: default:
...@@ -430,16 +443,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { ...@@ -430,16 +443,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
P.OpenScope("("); P.OpenScope("(");
for i := 0; i < d.list.len(); i++ { for i := 0; i < d.list.len(); i++ {
P.Declaration(d.list.at(i).(*Node.Decl), true); P.Declaration(d.list.at(i).(*Node.Decl), true);
P.newl, P.semi = true, true; P.semi, P.newl = true, 1;
} }
P.CloseScope(")"); P.CloseScope(")");
} else { } else {
P.Expr(d.ident); P.Expr(d.ident);
if d.typ != nil { if d.typ != nil {
P.Blank(); P.Blank();
P.Type(d.typ); P.Type(d.typ);
} }
if d.val != nil { if d.val != nil {
if d.tok == Scanner.IMPORT { if d.tok == Scanner.IMPORT {
P.Blank(); P.Blank();
...@@ -448,6 +463,7 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { ...@@ -448,6 +463,7 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
} }
P.Expr(d.val); P.Expr(d.val);
} }
if d.list != nil { if d.list != nil {
if d.tok != Scanner.FUNC { if d.tok != Scanner.FUNC {
panic("must be a func declaration"); panic("must be a func declaration");
...@@ -456,13 +472,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { ...@@ -456,13 +472,18 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
P.Block(d.list, true); 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 // extra newline at the top level
if P.level == 0 { if P.level == 0 {
P.NewLine(); P.newl++;
} }
P.newl = true;
} }
...@@ -472,10 +493,10 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) { ...@@ -472,10 +493,10 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
func (P *Printer) Program(p *Node.Program) { func (P *Printer) Program(p *Node.Program) {
P.String(p.pos, "package "); P.String(p.pos, "package ");
P.Expr(p.ident); P.Expr(p.ident);
P.NewLine(); P.newl = 2;
for i := 0; i < p.decls.len(); i++ { for i := 0; i < p.decls.len(); i++ {
P.Declaration(p.decls.at(i), false); P.Declaration(p.decls.at(i), false);
} }
P.newl = true; P.newl = 1;
P.String(0, ""); // flush P.String(0, ""); // flush
} }
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