summaryrefslogtreecommitdiff
path: root/src/pkg/go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-04-20 15:44:41 +0200
committerOndřej Surý <ondrej@sury.org>2011-04-20 15:44:41 +0200
commit50104cc32a498f7517a51c8dc93106c51c7a54b4 (patch)
tree47af80be259cc7c45d0eaec7d42e61fa38c8e4fb /src/pkg/go
parentc072558b90f1bbedc2022b0f30c8b1ac4712538e (diff)
downloadgolang-50104cc32a498f7517a51c8dc93106c51c7a54b4.tar.gz
Imported Upstream version 2011.03.07.1upstream/2011.03.07.1
Diffstat (limited to 'src/pkg/go')
-rw-r--r--src/pkg/go/ast/ast.go2
-rw-r--r--src/pkg/go/ast/walk.go4
-rw-r--r--src/pkg/go/parser/interface.go4
-rw-r--r--src/pkg/go/parser/parser.go93
-rw-r--r--src/pkg/go/parser/parser_test.go35
-rw-r--r--src/pkg/go/printer/printer.go4
-rw-r--r--src/pkg/go/printer/printer_test.go6
-rw-r--r--src/pkg/go/printer/testdata/statements.golden10
-rw-r--r--src/pkg/go/printer/testdata/statements.input10
-rw-r--r--src/pkg/go/scanner/scanner.go11
10 files changed, 106 insertions, 73 deletions
diff --git a/src/pkg/go/ast/ast.go b/src/pkg/go/ast/ast.go
index 2e8f0973f..abafb5663 100644
--- a/src/pkg/go/ast/ast.go
+++ b/src/pkg/go/ast/ast.go
@@ -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
}
diff --git a/src/pkg/go/ast/walk.go b/src/pkg/go/ast/walk.go
index a77f8ee5e..20c337c3b 100644
--- a/src/pkg/go/ast/walk.go
+++ b/src/pkg/go/ast/walk.go
@@ -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)
diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go
index 84d699a67..6f35b495e 100644
--- a/src/pkg/go/parser/interface.go
+++ b/src/pkg/go/parser/interface.go
@@ -14,7 +14,7 @@ import (
"io"
"io/ioutil"
"os"
- pathutil "path"
+ "path/filepath"
)
@@ -198,7 +198,7 @@ func ParseDir(fset *token.FileSet, path string, filter func(*os.FileInfo) bool,
for i := 0; i < len(list); i++ {
d := &list[i]
if filter == nil || filter(d) {
- filenames[n] = pathutil.Join(path, d.Name)
+ filenames[n] = filepath.Join(path, d.Name)
n++
}
}
diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go
index 2395b8158..7c5843f36 100644
--- a/src/pkg/go/parser/parser.go
+++ b/src/pkg/go/parser/parser.go
@@ -1327,44 +1327,34 @@ 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)
- }
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
+ s = p.parseSimpleStmt(false)
+ if p.tok == token.SEMICOLON {
+ p.next()
+ x = p.parseExpr()
+ } else {
+ 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 +1364,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 +1447,24 @@ 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
+ if p.tok != token.SEMICOLON {
+ 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 +1582,29 @@ 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()
diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go
index 5a7f05ca8..38535627a 100644
--- a/src/pkg/go/parser/parser_test.go
+++ b/src/pkg/go/parser/parser_test.go
@@ -18,6 +18,9 @@ var illegalInputs = []interface{}{
3.14,
[]byte(nil),
"foo!",
+ `package p; func f() { if /* should have condition */ {} };`,
+ `package p; func f() { if ; /* should have condition */ {} };`,
+ `package p; func f() { if f(); /* should have condition */ {} };`,
}
@@ -32,21 +35,23 @@ func TestParseIllegalInputs(t *testing.T) {
var validPrograms = []interface{}{
- "package main\n",
- `package main;`,
- `package main; import "fmt"; func main() { fmt.Println("Hello, World!") };`,
- `package main; func main() { if f(T{}) {} };`,
- `package main; func main() { _ = (<-chan int)(x) };`,
- `package main; func main() { _ = (<-chan <-chan int)(x) };`,
- `package main; func f(func() func() func());`,
- `package main; func f(...T);`,
- `package main; func f(float, ...int);`,
- `package main; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
- `package main; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
- `package main; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
- `package main; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
- `package main; var a = T{{1, 2}, {3, 4}}`,
- `package main; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
+ "package p\n",
+ `package p;`,
+ `package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
+ `package p; func f() { if f(T{}) {} };`,
+ `package p; func f() { _ = (<-chan int)(x) };`,
+ `package p; func f() { _ = (<-chan <-chan int)(x) };`,
+ `package p; func f(func() func() func());`,
+ `package p; func f(...T);`,
+ `package p; func f(float, ...int);`,
+ `package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
+ `package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
+ `package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
+ `package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
+ `package p; var a = T{{1, 2}, {3, 4}}`,
+ `package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
+ `package p; func f() { if ; true {} };`,
+ `package p; func f() { switch ; {} };`,
}
diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go
index 48e2af1b7..90d9784ac 100644
--- a/src/pkg/go/printer/printer.go
+++ b/src/pkg/go/printer/printer.go
@@ -12,7 +12,7 @@ import (
"go/token"
"io"
"os"
- "path"
+ "path/filepath"
"runtime"
"tabwriter"
)
@@ -244,7 +244,7 @@ func (p *printer) writeItem(pos token.Position, data []byte) {
}
if debug {
// do not update p.pos - use write0
- _, filename := path.Split(pos.Filename)
+ _, filename := filepath.Split(pos.Filename)
p.write0([]byte(fmt.Sprintf("[%s:%d:%d]", filename, pos.Line, pos.Column)))
}
p.write(data)
diff --git a/src/pkg/go/printer/printer_test.go b/src/pkg/go/printer/printer_test.go
index 565075aa2..62b726913 100644
--- a/src/pkg/go/printer/printer_test.go
+++ b/src/pkg/go/printer/printer_test.go
@@ -11,7 +11,7 @@ import (
"go/ast"
"go/parser"
"go/token"
- "path"
+ "path/filepath"
"testing"
)
@@ -129,8 +129,8 @@ var data = []entry{
func TestFiles(t *testing.T) {
for _, e := range data {
- source := path.Join(dataDir, e.source)
- golden := path.Join(dataDir, e.golden)
+ source := filepath.Join(dataDir, e.source)
+ golden := filepath.Join(dataDir, e.golden)
check(t, source, golden, e.mode)
// TODO(gri) check that golden is idempotent
//check(t, golden, golden, e.mode);
diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden
index 5eceb7dd5..290060269 100644
--- a/src/pkg/go/printer/testdata/statements.golden
+++ b/src/pkg/go/printer/testdata/statements.golden
@@ -10,9 +10,9 @@ func use(x interface{}) {}
// Formatting of if-statement headers.
func _() {
- if {
+ if true {
}
- if {
+ if true {
} // no semicolon printed
if expr {
}
@@ -22,7 +22,7 @@ func _() {
} // no parens printed
if expr {
} // no semicolon and parens printed
- if x := expr; {
+ if x := expr; true {
use(x)
}
if x := expr; expr {
@@ -354,14 +354,14 @@ func _() {
func _() {
- if {
+ if true {
_ = 0
}
_ = 0 // the indentation here should not be affected by the long label name
AnOverlongLabel:
_ = 0
- if {
+ if true {
_ = 0
}
_ = 0
diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input
index 7819820ed..21e61efc4 100644
--- a/src/pkg/go/printer/testdata/statements.input
+++ b/src/pkg/go/printer/testdata/statements.input
@@ -10,13 +10,13 @@ func use(x interface{}) {}
// Formatting of if-statement headers.
func _() {
- if {}
- if;{} // no semicolon printed
+ if true {}
+ if; true {} // no semicolon printed
if expr{}
if;expr{} // no semicolon printed
if (expr){} // no parens printed
if;((expr)){} // no semicolon and parens printed
- if x:=expr;{
+ if x:=expr;true{
use(x)}
if x:=expr; expr {use(x)}
}
@@ -271,14 +271,14 @@ func _() {
func _() {
- if {
+ if true {
_ = 0
}
_ = 0 // the indentation here should not be affected by the long label name
AnOverlongLabel:
_ = 0
- if {
+ if true {
_ = 0
}
_ = 0
diff --git a/src/pkg/go/scanner/scanner.go b/src/pkg/go/scanner/scanner.go
index 8c3205230..153707f59 100644
--- a/src/pkg/go/scanner/scanner.go
+++ b/src/pkg/go/scanner/scanner.go
@@ -8,7 +8,8 @@
//
// var s Scanner
// fset := token.NewFileSet() // position information is relative to fset
-// s.Init(fset, filename, src, nil /* no error handler */, 0)
+// file := fset.AddFile(filename, fset.Base(), len(src)) // register file
+// s.Init(file, src, nil /* no error handler */, 0)
// for {
// pos, tok, lit := s.Scan()
// if tok == token.EOF {
@@ -22,7 +23,7 @@ package scanner
import (
"bytes"
"go/token"
- "path"
+ "path/filepath"
"strconv"
"unicode"
"utf8"
@@ -117,7 +118,7 @@ func (S *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode uint
panic("file size does not match src len")
}
S.file = file
- S.dir, _ = path.Split(file.Name())
+ S.dir, _ = filepath.Split(file.Name())
S.src = src
S.err = err
S.mode = mode
@@ -179,10 +180,10 @@ func (S *Scanner) interpretLineComment(text []byte) {
if i := bytes.Index(text, []byte{':'}); i > 0 {
if line, err := strconv.Atoi(string(text[i+1:])); err == nil && line > 0 {
// valid //line filename:line comment;
- filename := path.Clean(string(text[len(prefix):i]))
+ filename := filepath.Clean(string(text[len(prefix):i]))
if filename[0] != '/' {
// make filename relative to current directory
- filename = path.Join(S.dir, filename)
+ filename = filepath.Join(S.dir, filename)
}
// update scanner position
S.file.AddLineInfo(S.lineOffset, filename, line-1) // -1 since comment applies to next line