From ca46690f9166681e4b32af90e28fb215c12f76c0 Mon Sep 17 00:00:00 2001 From: Bobby Date: Wed, 10 Apr 2024 20:42:41 +0000 Subject: hashes --- object/object.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ object/object_test.go | 22 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 object/object_test.go (limited to 'object') diff --git a/object/object.go b/object/object.go index 9fe896e..22d0441 100644 --- a/object/object.go +++ b/object/object.go @@ -3,6 +3,7 @@ package object import ( "bytes" "fmt" + "hash/fnv" "mana/ast" "strings" ) @@ -19,6 +20,7 @@ const ( ERROR_OBJ = "ERROR" BUILTIN_OBJ = "BUILTIN" ARRAY_OBJ = "ARRAY" + HASH_OBJ = "HASH" ) type Object interface { @@ -144,3 +146,61 @@ 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} +} + +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() +} + +type Hashable interface { + HashKey() HashKey +} diff --git a/object/object_test.go b/object/object_test.go new file mode 100644 index 0000000..3d08c8b --- /dev/null +++ b/object/object_test.go @@ -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("strings with same content have different hash keys") + } + + if diff1.HashKey() != diff2.HashKey() { + t.Errorf("strings with same content have different hash keys") + } + + if hello1.HashKey() == diff1.HashKey() { + t.Errorf("strings with different content have same hash keys") + } +} \ No newline at end of file -- cgit v1.2.3