aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2011-07-06 11:02:53 +1000
committerRob Pike <r@golang.org>2011-07-06 11:02:53 +1000
commit329990d52509cd454022e0b6bbcd06e5b7092dc6 (patch)
tree01303f56df8cd331d0f821efc4b43cf773a3314d
parent4657d7d7db3b28206c7fc98907f998140843ed88 (diff)
downloadgo-329990d52509cd454022e0b6bbcd06e5b7092dc6.tar.gz
go-329990d52509cd454022e0b6bbcd06e5b7092dc6.zip
exp/template: remove the need for a goroutine.
R=golang-dev, adg CC=golang-dev https://golang.org/cl/4626095
-rw-r--r--src/pkg/exp/template/lex.go25
-rw-r--r--src/pkg/exp/template/lex_test.go9
2 files changed, 20 insertions, 14 deletions
diff --git a/src/pkg/exp/template/lex.go b/src/pkg/exp/template/lex.go
index 52d0617058..435762c03e 100644
--- a/src/pkg/exp/template/lex.go
+++ b/src/pkg/exp/template/lex.go
@@ -113,6 +113,7 @@ type stateFn func(*lexer) stateFn
type lexer struct {
name string // the name of the input; used only for error reports.
input string // the string being scanned.
+ state stateFn // the next lexing function to enter
pos int // current position in the input.
start int // start position of this item.
width int // width of last rune read from input.
@@ -182,27 +183,27 @@ func (l *lexer) errorf(format string, args ...interface{}) stateFn {
return nil
}
-// run lexes the input by executing state functions until nil.
-func (l *lexer) run() {
- for state := lexText; state != nil; {
- state = state(l)
- }
- close(l.items)
-}
-
// nextItem returns the next item from the input.
func (l *lexer) nextItem() item {
- return <-l.items
+ for {
+ select {
+ case item := <-l.items:
+ return item
+ default:
+ l.state = l.state(l)
+ }
+ }
+ panic("not reached")
}
-// lex launches a new scanner and returns the channel of items.
+// lex creates a new scanner for the input string.
func lex(name, input string) *lexer {
l := &lexer{
name: name,
input: input,
- items: make(chan item),
+ state: lexText,
+ items: make(chan item, 2), // Two items of buffering is sufficient for all state functions
}
- go l.run()
return l
}
diff --git a/src/pkg/exp/template/lex_test.go b/src/pkg/exp/template/lex_test.go
index 4b4d619bf0..4246b400dd 100644
--- a/src/pkg/exp/template/lex_test.go
+++ b/src/pkg/exp/template/lex_test.go
@@ -128,14 +128,19 @@ var lexTests = []lexTest{
// collect gathers the emitted items into a slice.
func collect(t *lexTest) (items []item) {
l := lex(t.name, t.input)
- for i := range l.items {
- items = append(items, i)
+ for {
+ item := l.nextItem()
+ items = append(items, item)
+ if item.typ == itemEOF || item.typ == itemError {
+ break
+ }
}
return
}
func TestLex(t *testing.T) {
for _, test := range lexTests {
+ println(test.name)
items := collect(&test)
if !reflect.DeepEqual(items, test.items) {
t.Errorf("%s: got\n\t%v\nexpected\n\t%v", test.name, items, test.items)