<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--walk/walk.go45
1 files changed, 29 insertions, 16 deletions
diff --git a/walk/walk.go b/walk/walk.go
index 6d00ef2..490a6f2 100644
--- a/walk/walk.go
+++ b/walk/walk.go
@@ -6,6 +6,7 @@ import (
"fmt"
"strings"
"math"
+ "unicode/utf8"
)
// int or string
@@ -48,8 +49,8 @@ const (
MapBegin
MapEnd
)
-func (value TerminalValue) Atomise() []Atom {
- return []Atom{value}
+func (value TerminalValue) Atomise(in []Atom) []Atom {
+ return append(in, value)
}
func (value TerminalValue) String() string {
switch value {
@@ -67,16 +68,16 @@ func (value TerminalValue) String() string {
}
type ValueNull struct {}
-func (value ValueNull) Atomise() []Atom {
- return []Atom{ValueNull{}}
+func (value ValueNull) Atomise(in []Atom) []Atom {
+ return append(in, value)
}
func (value ValueNull) String() string {
return "null"
}
type ValueBool bool
-func (value ValueBool) Atomise() []Atom {
- return []Atom{value}
+func (value ValueBool) Atomise(in []Atom) []Atom {
+ return append(in, value)
}
func (value ValueBool) String() string {
if value {
@@ -87,8 +88,8 @@ func (value ValueBool) String() string {
}
type ValueNumber float64
-func (value ValueNumber) Atomise() []Atom {
- return []Atom{value}
+func (value ValueNumber) Atomise(in []Atom) []Atom {
+ return append(in, value)
}
func (value ValueNumber) String() string {
v := float64(value)
@@ -106,13 +107,13 @@ func (value StringAtom) String() string {
}
type ValueString string
-func (value ValueString) Atomise() (out []Atom) {
- out = append(out, StringTerminal{})
+func (value ValueString) Atomise(in []Atom) []Atom {
+ in = append(in, StringTerminal{})
for _, char := range value {
- out = append(out, StringAtom(char))
+ in = append(in, StringAtom(char))
}
- out = append(out, StringTerminal{})
- return out
+ in = append(in, StringTerminal{})
+ return in
}
func (value ValueString) String() string {
return fmt.Sprintf("\"%s\"", string(value))
@@ -123,7 +124,8 @@ type Atom interface {
}
type WalkValue interface {
- Atomise() []Atom
+ // Append this values atoms to the input
+ Atomise(in []Atom) []Atom
String() string
}
@@ -427,9 +429,20 @@ func ConcatData(first []Atom, second []Atom) []Atom {
}
func Atomise(in []WalkValue) (out []Atom) {
- out = make([]Atom, 0, len(in) * 2)
+ numAtoms := 0
+ for _, value := range in {
+ switch v := value.(type) {
+ case TerminalValue, ValueNull, ValueBool, ValueNumber:
+ numAtoms++
+ case ValueString:
+ numAtoms += utf8.RuneCountInString(string(v)) + 2
+ default:
+ panic("Invalid WalkValue")
+ }
+ }
+ out = make([]Atom, 0, numAtoms)
for _, value := range in {
- out = append(out, value.Atomise()...)
+ out = value.Atomise(out)
}
return out
}