]> Cypherpunks repositories - gostls13.git/commitdiff
go/ast, parser: condition in if statement is mandatory
authorRobert Griesemer <gri@golang.org>
Wed, 23 Feb 2011 01:25:10 +0000 (17:25 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 23 Feb 2011 01:25:10 +0000 (17:25 -0800)
As a result, parsing a "control clause" is now sufficiently
different for if, switch, and for statements that the code
is not factored out anymore. The code is a bit longer but
clearer in each individual case.

Reflect the changes in AST.

R=r, r2
CC=golang-dev
https://golang.org/cl/4173075

src/pkg/go/ast/ast.go
src/pkg/go/ast/walk.go
src/pkg/go/parser/parser.go
src/pkg/go/parser/parser_test.go

index 2e8f0973fa2602a4aabc179fec40f2d268989c18..abafb5663b3baf0ef0dcfdebfc9d303be68a6ae1 100644 (file)
@@ -597,7 +597,7 @@ type (
        IfStmt struct {
                If   token.Pos // position of "if" keyword
                Init Stmt      // initalization statement; or nil
-               Cond Expr      // condition; or nil
+               Cond Expr      // condition
                Body *BlockStmt
                Else Stmt // else branch; or nil
        }
index a77f8ee5e07e382e1ffa583bc3b4213cb719f4bf..20c337c3be98b8f469da3f9d42f29979f03a78a7 100644 (file)
@@ -227,9 +227,7 @@ func Walk(v Visitor, node Node) {
                if n.Init != nil {
                        Walk(v, n.Init)
                }
-               if n.Cond != nil {
-                       Walk(v, n.Cond)
-               }
+               Walk(v, n.Cond)
                Walk(v, n.Body)
                if n.Else != nil {
                        Walk(v, n.Else)
index 2395b815878db942824e12cf0377db3c021f869d..77bcc448273704ede7047ec1478c97c8f6469ff5 100644 (file)
@@ -1327,44 +1327,29 @@ func (p *parser) makeExpr(s ast.Stmt) ast.Expr {
 }
 
 
-func (p *parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) {
-       if p.tok != token.LBRACE {
+func (p *parser) parseIfStmt() *ast.IfStmt {
+       if p.trace {
+               defer un(trace(p, "IfStmt"))
+       }
+
+       pos := p.expect(token.IF)
+
+       var s ast.Stmt
+       var x ast.Expr
+       {
                prevLev := p.exprLev
                p.exprLev = -1
-
-               if p.tok != token.SEMICOLON {
-                       s1 = p.parseSimpleStmt(false)
-               }
+               s = p.parseSimpleStmt(false)
                if p.tok == token.SEMICOLON {
                        p.next()
-                       if p.tok != token.LBRACE && p.tok != token.SEMICOLON {
-                               s2 = p.parseSimpleStmt(false)
-                       }
-                       if isForStmt {
-                               // for statements have a 3rd section
-                               p.expectSemi()
-                               if p.tok != token.LBRACE {
-                                       s3 = p.parseSimpleStmt(false)
-                               }
-                       }
+                       x = p.parseExpr()
                } else {
-                       s1, s2 = nil, s1
+                       x = p.makeExpr(s)
+                       s = nil
                }
-
                p.exprLev = prevLev
        }
 
-       return s1, s2, s3
-}
-
-
-func (p *parser) parseIfStmt() *ast.IfStmt {
-       if p.trace {
-               defer un(trace(p, "IfStmt"))
-       }
-
-       pos := p.expect(token.IF)
-       s1, s2, _ := p.parseControlClause(false)
        body := p.parseBlockStmt()
        var else_ ast.Stmt
        if p.tok == token.ELSE {
@@ -1374,7 +1359,7 @@ func (p *parser) parseIfStmt() *ast.IfStmt {
                p.expectSemi()
        }
 
-       return &ast.IfStmt{pos, s1, p.makeExpr(s2), body, else_}
+       return &ast.IfStmt{pos, s, x, body, else_}
 }
 
 
@@ -1457,7 +1442,22 @@ func (p *parser) parseSwitchStmt() ast.Stmt {
        }
 
        pos := p.expect(token.SWITCH)
-       s1, s2, _ := p.parseControlClause(false)
+
+       var s1, s2 ast.Stmt
+       if p.tok != token.LBRACE {
+               prevLev := p.exprLev
+               p.exprLev = -1
+               s2 = p.parseSimpleStmt(false)
+               if p.tok == token.SEMICOLON {
+                       p.next()
+                       s1 = s2
+                       s2 = nil
+                       if p.tok != token.LBRACE {
+                               s2 = p.parseSimpleStmt(false)
+                       }
+               }
+               p.exprLev = prevLev
+       }
 
        if isExprSwitch(s2) {
                lbrace := p.expect(token.LBRACE)
@@ -1575,7 +1575,31 @@ func (p *parser) parseForStmt() ast.Stmt {
        }
 
        pos := p.expect(token.FOR)
-       s1, s2, s3 := p.parseControlClause(true)
+
+       var s1, s2, s3 ast.Stmt
+       if p.tok != token.LBRACE {
+               prevLev := p.exprLev
+               p.exprLev = -1
+
+               if p.tok != token.SEMICOLON {
+                       s2 = p.parseSimpleStmt(false)
+               }
+               if p.tok == token.SEMICOLON {
+                       p.next()
+                       s1 = s2
+                       s2 = nil
+                       if p.tok != token.SEMICOLON {
+                               s2 = p.parseSimpleStmt(false)
+                       }
+                       p.expectSemi()
+                       if p.tok != token.LBRACE {
+                               s3 = p.parseSimpleStmt(false)
+                       }
+               }
+
+               p.exprLev = prevLev
+       }
+
        body := p.parseBlockStmt()
        p.expectSemi()
 
index 5a7f05ca835b742106b85b5dd30c4cdb18984ae6..71238702038ebe77fcc83fd7566a4ce8a8f2a2d4 100644 (file)
@@ -18,6 +18,7 @@ var illegalInputs = []interface{}{
        3.14,
        []byte(nil),
        "foo!",
+       `package p; func f() { if /* should have condition */ {} };`,
 }