diff options
Diffstat (limited to 'walk/walk.go')
-rw-r--r-- | walk/walk.go | 186 |
1 files changed, 12 insertions, 174 deletions
diff --git a/walk/walk.go b/walk/walk.go index 493bc46..20eac38 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -15,8 +15,8 @@ func stringPathSegment(segment PathSegment) string { return fmt.Sprintf("%v", segment) } type Path []PathSegment -func (path Path) ToWalkValues() []WalkValue { - var values []WalkValue +func (path Path) ToWalkValues() []Value { + var values []Value for _, segment := range path { switch s := segment.(type) { case int: @@ -30,7 +30,7 @@ func (path Path) ToWalkValues() []WalkValue { return values } -func PathFromWalkValues(values []WalkValue) Path { +func PathFromWalkValues(values []Value) Path { var segments []PathSegment for _, value := range values { switch v := value.(type) { @@ -45,168 +45,6 @@ func PathFromWalkValues(values []WalkValue) Path { return segments } -type TerminalValue int -const ( - ArrayBegin TerminalValue = iota - ArrayEnd - MapBegin - MapEnd -) -func (value TerminalValue) Atomise(in []Atom) []Atom { - return append(in, NewAtomTerminal(value)) -} -func (value TerminalValue) String() string { - switch value { - case ArrayBegin: - return "[" - case ArrayEnd: - return "]" - case MapBegin: - return "{" - case MapEnd: - return "}" - default: - panic("Unknown TerminalValue") - } -} - -type ValueNull struct {} -func (value ValueNull) Atomise(in []Atom) []Atom { - return append(in, NewAtomNull()) -} -func (value ValueNull) String() string { - return "null" -} - -type ValueBool bool -func (value ValueBool) Atomise(in []Atom) []Atom { - return append(in, NewAtomBool(bool(value))) -} -func (value ValueBool) String() string { - if value { - return "true" - } else { - return "false" - } -} - -type ValueNumber float64 -func (value ValueNumber) Atomise(in []Atom) []Atom { - return append(in, NewAtomNumber(float64(value))) -} -func (value ValueNumber) String() string { - v := float64(value) - return fmt.Sprintf("%f", v) -} - -type ValueString string -func (value ValueString) Atomise(in []Atom) []Atom { - in = append(in, NewAtomStringTerminal()) - for _, char := range value { - in = append(in, NewAtomStringRune(char)) - } - in = append(in, NewAtomStringTerminal()) - return in -} -func (value ValueString) String() string { - return fmt.Sprintf("\"%s\"", string(value)) -} - -type AtomType int64 -const ( - AtomNull AtomType = iota - AtomBool - AtomNumber - AtomTerminal - AtomStringTerminal - AtomStringRune -) -type Atom struct { - Typ AtomType - data uint64 -} -func NewAtomNull() Atom { - return Atom { - Typ: AtomNull, - data: 0, - } -} -func NewAtomBool(v bool) Atom { - if v { - return Atom { - Typ: AtomBool, - data: 1, - } - } else { - return Atom { - Typ: AtomBool, - data: 0, - } - } -} -func NewAtomNumber(v float64) Atom { - return Atom { - Typ: AtomNumber, - data: math.Float64bits(v), - } -} -func NewAtomTerminal(v TerminalValue) Atom { - return Atom { - Typ: AtomTerminal, - data: uint64(v), - } -} -func NewAtomStringTerminal() Atom { - return Atom { - Typ: AtomStringTerminal, - data: 0, - } -} -func NewAtomStringRune(v rune) Atom { - return Atom { - Typ: AtomStringRune, - data: uint64(v), - } -} -func (v Atom) String() string { - switch v.Typ { - case AtomNull: - return "null" - case AtomBool: - if v.data == 0 { - return "false" - } - return "true" - case AtomNumber: - return fmt.Sprintf("%v", math.Float64frombits(v.data)) - case AtomTerminal: - switch TerminalValue(v.data) { - case MapBegin: - return "{" - case MapEnd: - return "}" - case ArrayBegin: - return "[" - case ArrayEnd: - return "]" - default: - panic("Invalid terminal atom") - } - case AtomStringTerminal: - return "\"" - case AtomStringRune: - return string(rune(v.data)) - default: - panic("Invalid atom type") - } -} - -type WalkValue interface { - // Append this values atoms to the input - Atomise(in []Atom) []Atom - String() string -} - type WalkItem struct { Value []Atom Path []Atom @@ -527,7 +365,7 @@ func (out *JSONOut) atomOut(key string, atom Atom) { fmt.Fprint(out.writer, "\"") out.structure = append(out.structure, JSONOutString) case AtomTerminal: - switch TerminalValue(atom.data) { + switch ValueTerminal(atom.data) { case MapBegin: out.indent(0) if state == JSONOutMap { @@ -565,12 +403,12 @@ func (out *JSONOut) atomOut(key string, atom Atom) { case JSONOutValueEnd: out.structure = out.structure[:len(out.structure) - 1] underState := out.structure[len(out.structure) - 1] - if underState == JSONOutMap && atom.Typ == AtomTerminal && TerminalValue(atom.data) == MapEnd { + if underState == JSONOutMap && atom.Typ == AtomTerminal && ValueTerminal(atom.data) == MapEnd { fmt.Fprint(out.writer, "\n") out.indent(-1) fmt.Fprint(out.writer, "}") out.structure[len(out.structure) - 1] = JSONOutValueEnd - } else if underState == JSONOutArray && atom.Typ == AtomTerminal && TerminalValue(atom.data) == ArrayEnd { + } else if underState == JSONOutArray && atom.Typ == AtomTerminal && ValueTerminal(atom.data) == ArrayEnd { fmt.Fprint(out.writer, "\n") out.indent(-1) fmt.Fprint(out.writer, "]") @@ -625,11 +463,11 @@ func ConcatData(first []Atom, second []Atom) []Atom { return res } -func Atomise(in []WalkValue) (out []Atom) { +func Atomise(in []Value) (out []Atom) { numAtoms := 0 for _, value := range in { switch v := value.(type) { - case TerminalValue, ValueNull, ValueBool, ValueNumber: + case ValueTerminal, ValueNull, ValueBool, ValueNumber: numAtoms++ case ValueString: numAtoms += utf8.RuneCountInString(string(v)) + 2 @@ -669,11 +507,11 @@ func (err CompoundError) Error() string { } type CompoundResult struct { - value WalkValue + value Value error error } -func Compound(in []Atom) (out []WalkValue, error error) { +func Compound(in []Atom) (out []Value, error error) { numValues := 0 i := 0 inString := false @@ -691,7 +529,7 @@ func Compound(in []Atom) (out []WalkValue, error error) { } } i = 0 - out = make([]WalkValue, 0, numValues) + out = make([]Value, 0, numValues) for { if i >= len(in) { break @@ -709,7 +547,7 @@ func Compound(in []Atom) (out []WalkValue, error error) { out = append(out, ValueNumber(math.Float64frombits(atom.data))) continue case AtomTerminal: - out = append(out, TerminalValue(atom.data)) + out = append(out, ValueTerminal(atom.data)) continue case AtomStringRune: return nil, CompoundRuneOutsideString |