-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathhash-table.go
More file actions
117 lines (104 loc) · 2.44 KB
/
hash-table.go
File metadata and controls
117 lines (104 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) 2022, Peter Ohler, All rights reserved.
package slip
import (
"strconv"
)
// HashTableSymbol is the symbol with a value of "hash-table".
const HashTableSymbol = Symbol("hash-table")
// HashTable of Objects.
type HashTable map[Object]Object
// String representation of the Object.
func (obj HashTable) String() string {
return string(obj.Append([]byte{}))
}
// Append a buffer with a representation of the Object.
func (obj HashTable) Append(b []byte) []byte {
b = append(b, "#<hash-table eql "...)
b = strconv.AppendInt(b, int64(len(obj)), 10)
return append(b, "/-->"...)
}
// Simplify the Object into a []any.
func (obj HashTable) Simplify() any {
out := map[string]any{}
for k, v := range obj {
switch tk := k.(type) {
case String:
if v == nil {
out[string(tk)] = nil
} else {
out[string(tk)] = v.Simplify()
}
case Symbol:
if v == nil {
out[string(tk)] = nil
} else {
out[string(tk)] = v.Simplify()
}
default:
key := ObjectString(k)
if v == nil {
out[key] = nil
} else {
out[key] = v.Simplify()
}
}
}
return out
}
// Equal returns true if this Object and the other are equal in value.
func (obj HashTable) Equal(other Object) (eq bool) {
if to, ok := other.(HashTable); ok {
if len(obj) == len(to) {
eq = true
for k, v := range obj {
vo, has := to[k]
if !has {
eq = false
break
}
if v == nil {
if vo != nil {
eq = false
break
}
} else {
if !v.Equal(vo) {
eq = false
break
}
}
}
}
}
return
}
// Hierarchy returns the class hierarchy as symbols for the instance.
func (obj HashTable) Hierarchy() []Symbol {
return []Symbol{HashTableSymbol, TrueSymbol}
}
// Length returns the length of the object.
func (obj HashTable) Length() int {
return len(obj)
}
// Eval returns self.
func (obj HashTable) Eval(s *Scope, depth int) Object {
return obj
}
// LoadForm returns a form that can be evaluated to create the object.
func (obj HashTable) LoadForm() Object {
tsym := Symbol("table")
form := List{
Symbol("let"),
List{List{tsym, List{Symbol("make-hash-table")}}},
}
for k, v := range obj {
switch k.(type) {
case Symbol:
form = append(form, List{Symbol("setf"), List{Symbol("gethash"), List{quoteSymbol, k}, tsym}, v})
case String, Number, nil:
form = append(form, List{Symbol("setf"), List{Symbol("gethash"), k, tsym}, v})
}
}
form = append(form, Symbol("table"))
return form
}