]> Cypherpunks repositories - gostls13.git/commitdiff
exp/template: remove the need for a goroutine.
authorRob Pike <r@golang.org>
Wed, 6 Jul 2011 01:02:53 +0000 (11:02 +1000)
committerRob Pike <r@golang.org>
Wed, 6 Jul 2011 01:02:53 +0000 (11:02 +1000)
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/4626095

src/pkg/exp/template/lex.go
src/pkg/exp/template/lex_test.go

index 52d0617058c3ed0e2e46142816ba4d0c4c60af20..435762c03e4e871472fb341306b7d8514e5abbe4 100644 (file)
@@ -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
 }
 
index 4b4d619bf02403567e9fe2b257122e9a25f88c00..4246b400dde06314b47afc5d5b5fbb407c8ea653 100644 (file)
@@ -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)