<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-25 13:55:26 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-25 13:55:26 +0100
commit6a4e25b1c691846185e9dd698c1558981089738c (patch)
tree7a5031ae4a8d21b48836f98f7fe7629d276df0ac
parenta28312895aecd8643c1705c0a316d1b99107dc0d (diff)
downloadstred-go-6a4e25b1c691846185e9dd698c1558981089738c.tar
Refactor Atom and Value code out of walk.go and into separate files
-rw-r--r--walk/atom.go95
-rw-r--r--walk/value.go78
-rw-r--r--walk/walk.go186
3 files changed, 185 insertions, 174 deletions
diff --git a/walk/atom.go b/walk/atom.go
new file mode 100644
index 0000000..13ad2ff
--- /dev/null
+++ b/walk/atom.go
@@ -0,0 +1,95 @@
+package walk
+
+import (
+ "math"
+ "fmt"
+)
+
+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 ValueTerminal) 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 ValueTerminal(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")
+ }
+}
diff --git a/walk/value.go b/walk/value.go
new file mode 100644
index 0000000..2e2c3c9
--- /dev/null
+++ b/walk/value.go
@@ -0,0 +1,78 @@
+package walk
+
+import (
+ "fmt"
+)
+
+type ValueTerminal int
+const (
+ ArrayBegin ValueTerminal = iota
+ ArrayEnd
+ MapBegin
+ MapEnd
+)
+func (value ValueTerminal) Atomise(in []Atom) []Atom {
+ return append(in, NewAtomTerminal(value))
+}
+func (value ValueTerminal) 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 Value interface {
+ // Append this values atoms to the input
+ Atomise(in []Atom) []Atom
+ String() string
+}
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