This commit is contained in:
Chuck Smith
2024-01-22 20:41:05 -05:00
parent 069b5ba8cf
commit 5536dbeaaa
10 changed files with 394 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package object
import (
"bytes"
"fmt"
"hash/fnv"
"monkey/ast"
"strings"
)
@@ -19,6 +20,7 @@ const (
STRING_OBJ = "STRING"
BUILTIN_OBJ = "BUILTIN"
ARRAY_OBJ = "ARRAY"
HASH_OBJ = "HASH"
)
type Object interface {
@@ -157,3 +159,63 @@ func (ao Array) Inspect() string {
return out.String()
}
type HashKey struct {
Type ObjectType
Value uint64
}
func (b *Boolean) HashKey() HashKey {
var value uint64
if b.Value {
value = 1
} else {
value = 0
}
return HashKey{Type: b.Type(), Value: value}
}
type Hashable interface {
HashKey() HashKey
}
func (i *Integer) HashKey() HashKey {
return HashKey{Type: i.Type(), Value: uint64(i.Value)}
}
func (s *String) HashKey() HashKey {
h := fnv.New64a()
h.Write([]byte(s.Value))
return HashKey{Type: s.Type(), Value: h.Sum64()}
}
type HashPair struct {
Key Object
Value Object
}
type Hash struct {
Pairs map[HashKey]HashPair
}
func (h *Hash) Type() ObjectType {
return HASH_OBJ
}
func (h *Hash) Inspect() string {
var out bytes.Buffer
pairs := []string{}
for _, pair := range h.Pairs {
pairs = append(pairs, fmt.Sprintf("%s: %s", pair.Key.Inspect(), pair.Value.Inspect()))
}
out.WriteString("{")
out.WriteString(strings.Join(pairs, ", "))
out.WriteString("}")
return out.String()
}

22
object/object_test.go Normal file
View File

@@ -0,0 +1,22 @@
package object
import "testing"
func TestStringHashKey(t *testing.T) {
hello1 := &String{Value: "Hello World"}
hello2 := &String{Value: "Hello World"}
diff1 := &String{Value: "My name is johnny"}
diff2 := &String{Value: "My name is johnny"}
if hello1.HashKey() != hello2.HashKey() {
t.Errorf("string with same content have different hash keys")
}
if diff1.HashKey() != diff2.HashKey() {
t.Errorf("string with same content have different hash keys")
}
if hello1.HashKey() == diff1.HashKey() {
t.Errorf("string with different content have same hash keys")
}
}