diff options
Diffstat (limited to 'walk/atom.go')
-rw-r--r-- | walk/atom.go | 95 |
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") + } +} |