diff options
author | Adam Scarr <adam@vektah.net> | 2017-08-06 14:31:35 +1000 |
---|---|---|
committer | Adam Scarr <adam@vektah.net> | 2017-08-06 14:31:35 +1000 |
commit | 68cde88125e1f016c5706ca8d0b3db6ba06624a2 (patch) | |
tree | cdd2de679892179f537b22ab05bfe3820dc7b4bf /pointer.go |
Initial commit
Diffstat (limited to 'pointer.go')
-rw-r--r-- | pointer.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/pointer.go b/pointer.go new file mode 100644 index 0000000..92b2bcb --- /dev/null +++ b/pointer.go @@ -0,0 +1,81 @@ +package parsec + +import ( + "strings" + "unicode/utf8" +) + +const ( + EOF rune = -1 +) + +func Input(s string) Pointer { + return Pointer{s, 0} +} + +type Pointer struct { + input string + pos int +} + +func (p Pointer) Advance(i int) Pointer { + return Pointer{p.input, p.pos + i} +} + +func (p Pointer) Get() string { + return p.input[p.pos:] +} + +func (p Pointer) Remaining() int { + remaining := len(p.input) - p.pos + if remaining < 0 { + return 0 + } + return remaining +} + +func (p Pointer) Next() (rune, Pointer) { + if int(p.pos) >= len(p.input) { + return EOF, p + } + r, w := utf8.DecodeRuneInString(p.input[p.pos:]) + return r, p.Advance(w) +} + +func (p Pointer) HasPrefix(s string) bool { + return strings.HasPrefix(p.input[p.pos:], s) +} + +func (p Pointer) Accept(valid string) (string, Pointer) { + c, newP := p.Next() + if strings.ContainsRune(valid, c) { + return string(c), newP + } + return "", p +} + +func (p Pointer) AcceptRun(valid string) (string, Pointer) { + matched := 0 + for p.pos+matched < len(p.input) { + r, w := utf8.DecodeRuneInString(p.input[p.pos+matched:]) + if !strings.ContainsRune(valid, r) { + break + } + matched += w + } + + return p.input[p.pos : p.pos+matched], p.Advance(matched) +} + +func (p Pointer) AcceptUntil(invalid string) (string, Pointer) { + matched := 0 + for p.pos+matched < len(p.input) { + r, w := utf8.DecodeRuneInString(p.input[p.pos+matched:]) + if strings.ContainsRune(invalid, r) { + break + } + matched += w + } + + return p.input[p.pos : p.pos+matched], p.Advance(matched) +} |