aboutsummaryrefslogtreecommitdiff
path: root/object
diff options
context:
space:
mode:
Diffstat (limited to 'object')
-rw-r--r--object/object.go60
-rw-r--r--object/object_test.go22
2 files changed, 82 insertions, 0 deletions
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