Skip to content

Commit

Permalink
rename unrollLoops to UnrollPointers and move it
Browse files Browse the repository at this point in the history
  • Loading branch information
zimmski committed Jun 26, 2014
1 parent f7bb913 commit e0c51c3
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 148 deletions.
145 changes: 4 additions & 141 deletions parser/tavor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ import (

const zeroRune = 0

const (
MaxRepeat = 2
)

type tokenUse struct {
token token.Token
position scanner.Position
Expand Down Expand Up @@ -328,7 +324,7 @@ OUT:
var from, to int

if sym == '*' {
from, to = 0, MaxRepeat
from, to = 0, tavor.MaxRepeat
} else {
if c == scanner.Int {
from, _ = strconv.Atoi(p.scan.TokenText())
Expand All @@ -341,7 +337,7 @@ OUT:
// until there is an explicit "to" we can assume to==from
to = from
} else {
from, to = 1, MaxRepeat
from, to = 1, tavor.MaxRepeat
}

if c == ',' {
Expand All @@ -358,7 +354,7 @@ OUT:
fmt.Printf("parseTerm repeat after to ( %d:%v -> %v\n", p.scan.Line, scanner.TokenString(c), p.scan.TokenText())
}
} else {
to = MaxRepeat
to = tavor.MaxRepeat
}
}
}
Expand Down Expand Up @@ -1109,139 +1105,6 @@ func (p *tavorParser) parseSpecialTokenDefinition() (rune, error) {
return c, nil
}

func (p *tavorParser) unrollLoops(root token.Token) token.Token {
type unrollToken struct {
tok token.Token
parent *unrollToken
}

if tavor.DEBUG {
fmt.Println("Unroll loops by cloning pointers")
}

checked := make(map[token.Token]token.Token)
counters := make(map[token.Token]int)

queue := linkedlist.New()

queue.Push(&unrollToken{
tok: root,
parent: nil,
})

for !queue.Empty() {
v, _ := queue.Shift()
iTok, _ := v.(*unrollToken)

switch t := iTok.tok.(type) {
case *primitives.Pointer:
o := t.InternalGet()

parent, ok := checked[o]
times := 0

if ok {
times = counters[parent]
} else {
parent = o.Clone()
checked[o] = parent
}

if times != MaxRepeat {
if tavor.DEBUG {
fmt.Printf("Clone (%p)%#v with parent (%p)%#v\n", t, t, parent, parent)
}

c := parent.Clone()

t.Set(c)

counters[parent] = times + 1
checked[c] = parent

if iTok.parent != nil {
switch tt := iTok.parent.tok.(type) {
case token.ForwardToken:
tt.InternalReplace(t, c)
case lists.List:
tt.InternalReplace(t, c)
}
} else {
root = c
}

queue.Unshift(&unrollToken{
tok: c,
parent: iTok.parent,
})
} else {
if tavor.DEBUG {
fmt.Printf("Reached max repeat of %d for (%p)%#v with parent (%p)%#v\n", MaxRepeat, t, t, parent, parent)
}

t.Set(nil)

ta := iTok.tok
tt := iTok.parent

REMOVE:
for tt != nil {
switch l := tt.tok.(type) {
case token.ForwardToken:
if tavor.DEBUG {
fmt.Printf("Remove (%p)%#v from (%p)%#v\n", ta, ta, l, l)
}

c := l.InternalLogicalRemove(ta)

if c != nil {
break REMOVE
}

ta = l
tt = tt.parent
case lists.List:
if tavor.DEBUG {
fmt.Printf("Remove (%p)%#v from (%p)%#v\n", ta, ta, l, l)
}

c := l.InternalLogicalRemove(ta)

if c != nil {
break REMOVE
}

ta = l
tt = tt.parent
}
}
}
case token.ForwardToken:
if v := t.InternalGet(); v != nil {
queue.Push(&unrollToken{
tok: v,
parent: iTok,
})
}
case lists.List:
for i := 0; i < t.InternalLen(); i++ {
c, _ := t.InternalGet(i)

queue.Push(&unrollToken{
tok: c,
parent: iTok,
})
}
}
}

if tavor.DEBUG {
fmt.Println("Done unrolling")
}

return root
}

func ParseTavor(src io.Reader) (token.Token, error) {
p := &tavorParser{
earlyUse: make(map[string][]tokenUse),
Expand Down Expand Up @@ -1300,7 +1163,7 @@ func ParseTavor(src io.Reader) (token.Token, error) {

start := p.lookup["START"].token

start = p.unrollLoops(start)
start = tavor.UnrollPointers(start)

return start, nil
}
15 changes: 8 additions & 7 deletions parser/tavor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

. "github.com/stretchr/testify/assert"

"github.com/zimmski/tavor"
"github.com/zimmski/tavor/test"
"github.com/zimmski/tavor/token"
"github.com/zimmski/tavor/token/aggregates"
Expand Down Expand Up @@ -403,7 +404,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
Nil(t, err)
Equal(t, tok, lists.NewAll(
primitives.NewConstantInt(1),
lists.NewRepeat(primitives.NewConstantInt(2), 1, MaxRepeat),
lists.NewRepeat(primitives.NewConstantInt(2), 1, tavor.MaxRepeat),
))

// or repeat
Expand All @@ -414,7 +415,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
lists.NewRepeat(lists.NewOne(
primitives.NewConstantInt(2),
primitives.NewConstantInt(3),
), 1, MaxRepeat),
), 1, tavor.MaxRepeat),
primitives.NewConstantInt(4),
))

Expand All @@ -423,7 +424,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
Nil(t, err)
Equal(t, tok, lists.NewAll(
primitives.NewConstantInt(1),
lists.NewRepeat(primitives.NewConstantInt(2), 0, MaxRepeat),
lists.NewRepeat(primitives.NewConstantInt(2), 0, tavor.MaxRepeat),
))

// or optional repeat
Expand All @@ -434,7 +435,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
lists.NewRepeat(lists.NewOne(
primitives.NewConstantInt(2),
primitives.NewConstantInt(3),
), 0, MaxRepeat),
), 0, tavor.MaxRepeat),
primitives.NewConstantInt(4),
))

Expand All @@ -443,7 +444,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
Nil(t, err)
Equal(t, tok, lists.NewAll(
primitives.NewConstantInt(1),
lists.NewRepeat(primitives.NewConstantInt(2), 0, MaxRepeat),
lists.NewRepeat(primitives.NewConstantInt(2), 0, tavor.MaxRepeat),
))

// exact repeat
Expand All @@ -459,7 +460,7 @@ func TestTavorParserAlternationsAndGroupings(t *testing.T) {
Nil(t, err)
Equal(t, tok, lists.NewAll(
primitives.NewConstantInt(1),
lists.NewRepeat(primitives.NewConstantInt(2), 3, MaxRepeat),
lists.NewRepeat(primitives.NewConstantInt(2), 3, tavor.MaxRepeat),
))

// at most repeat
Expand Down Expand Up @@ -499,7 +500,7 @@ func TestTavorParserTokenAttributes(t *testing.T) {
primitives.NewConstantInt(1),
primitives.NewConstantInt(2),
primitives.NewConstantInt(3),
), 0, MaxRepeat),
), 0, tavor.MaxRepeat),
primitives.NewConstantString("->"),
aggregates.NewLen(list),
))
Expand Down
Loading

0 comments on commit e0c51c3

Please sign in to comment.