Commit 8e787367 authored by Robert Griesemer's avatar Robert Griesemer

- fixed bugs related to the empty statement

  (now in sync with the spec and with 6g)
- fixed incorrect logging statement in gds

R=r
OCL=24970
CL=24970
parent 6f8df7aa
...@@ -390,6 +390,10 @@ type ( ...@@ -390,6 +390,10 @@ type (
Tok int; // BREAK, CONTINUE, GOTO, FALLTHROUGH Tok int; // BREAK, CONTINUE, GOTO, FALLTHROUGH
Label *Ident; // if any, or nil Label *Ident; // if any, or nil
}; };
EmptyStat struct {
Pos int; // position of ";"
};
) )
...@@ -405,6 +409,7 @@ type StatVisitor interface { ...@@ -405,6 +409,7 @@ type StatVisitor interface {
DoSwitchStat(s *SwitchStat); DoSwitchStat(s *SwitchStat);
DoSelectStat(s *SelectStat); DoSelectStat(s *SelectStat);
DoControlFlowStat(s *ControlFlowStat); DoControlFlowStat(s *ControlFlowStat);
DoEmptyStat(s *EmptyStat);
} }
...@@ -419,6 +424,7 @@ func (s *CaseClause) Visit(v StatVisitor) { v.DoCaseClause(s); } ...@@ -419,6 +424,7 @@ func (s *CaseClause) Visit(v StatVisitor) { v.DoCaseClause(s); }
func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); } func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); }
func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); } func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); }
func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); } func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); }
func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
......
...@@ -155,7 +155,7 @@ func main() { ...@@ -155,7 +155,7 @@ func main() {
http.Handle("/", http.HandlerFunc(serve)); http.Handle("/", http.HandlerFunc(serve));
err2 := http.ListenAndServe(":" + *port, nil); err2 := http.ListenAndServe(":" + *port, nil);
if err2 != nil { if err2 != nil {
log.Exitf("ListenAndServe: ", err2.String()) log.Exitf("ListenAndServe: %s", err2.String())
} }
} }
...@@ -733,25 +733,21 @@ func (P *Parser) parseStatementList(list *array.Array) { ...@@ -733,25 +733,21 @@ func (P *Parser) parseStatementList(list *array.Array) {
defer un(trace(P, "StatementList")); defer un(trace(P, "StatementList"));
} }
expect_semi := false;
for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s := P.parseStatement(); if expect_semi {
if s != nil { P.expect(Scanner.SEMICOLON);
// not the empty statement expect_semi = false;
list.Push(s);
} }
list.Push(P.parseStatement());
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.next(); P.next();
} else if P.opt_semi { } else if P.opt_semi {
P.opt_semi = false; // "consume" optional semicolon P.opt_semi = false; // "consume" optional semicolon
} else { } else {
break; expect_semi = true;
} }
} }
// Try to provide a good error message
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.error(P.pos, "expected end of statement list (semicolon missing?)");
}
} }
...@@ -1273,12 +1269,9 @@ func (P *Parser) parseIfStat() *AST.IfStat { ...@@ -1273,12 +1269,9 @@ func (P *Parser) parseIfStat() *AST.IfStat {
var else_ AST.Stat; var else_ AST.Stat;
if P.tok == Scanner.ELSE { if P.tok == Scanner.ELSE {
P.next(); P.next();
if P.tok == Scanner.IF || P.tok == Scanner.LBRACE { if ok := P.tok == Scanner.IF || P.tok == Scanner.LBRACE; ok || P.sixg {
else_ = P.parseStatement(); else_ = P.parseStatement();
} else if P.sixg { if !ok {
else_ = P.parseStatement();
if else_ != nil {
// not the empty statement
// wrap in a block since we don't have one // wrap in a block since we don't have one
body := AST.NewBlock(0, Scanner.LBRACE); body := AST.NewBlock(0, Scanner.LBRACE);
body.List.Push(else_); body.List.Push(else_);
...@@ -1290,7 +1283,7 @@ func (P *Parser) parseIfStat() *AST.IfStat { ...@@ -1290,7 +1283,7 @@ func (P *Parser) parseIfStat() *AST.IfStat {
} }
P.closeScope(); P.closeScope();
return &AST.IfStat{pos, init, cond, body, else_ }; return &AST.IfStat{pos, init, cond, body, else_};
} }
...@@ -1438,10 +1431,14 @@ func (P *Parser) parseStatement() AST.Stat { ...@@ -1438,10 +1431,14 @@ func (P *Parser) parseStatement() AST.Stat {
return P.parseSwitchStat(); return P.parseSwitchStat();
case Scanner.SELECT: case Scanner.SELECT:
return P.parseSelectStat(); return P.parseSelectStat();
case Scanner.SEMICOLON:
// don't consume the ";", it is the separator following the empty statement
return &AST.EmptyStat{P.pos};
} }
// empty statement // no statement found
return nil; P.error(P.pos, "statement expected");
return &AST.BadStat{P.pos};
} }
......
...@@ -919,6 +919,12 @@ func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) { ...@@ -919,6 +919,12 @@ func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) {
} }
func (P *Printer) DoEmptyStat(s *AST.EmptyStat) {
P.String(s.Pos, "");
P.separator = semicolon;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
......
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