<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/walk/atom.go
diff options
context:
space:
mode:
Diffstat (limited to 'walk/atom.go')
-rw-r--r--walk/atom.go95
1 files changed, 95 insertions, 0 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")
+ }
+}