object.go (3502B)
1 package object 2 3 import ( 4 "bytes" 5 "fmt" 6 "hash/fnv" 7 "umx_compiler/ast" 8 "strings" 9 ) 10 11 type ObjectType string 12 type BuiltinFunction func(args ...Object) Object 13 14 const ( 15 INTEGER_OBJ = "INTEGER" 16 BOOLEAN_OBJ = "BOOLEAN" 17 NULL_OBJ = "NULL" 18 RETURN_VALUE_OBJ = "RETURN_VALUE" 19 ERROR_OBJ = "ERROR" 20 FUNCTION_OBJ = "FUNCTION" 21 STRING_OBJ = "STRING" 22 BUILTIN_OBJ = "BUILTIN" 23 ARRAY_OBJ = "ARRAY" 24 HASH_OBJ = "HASH" 25 ) 26 27 type Object interface { 28 Type() ObjectType 29 Inspect() string 30 } 31 32 type Integer struct { 33 Value int64 34 } 35 36 func (i *Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) } 37 func (i *Integer) Type() ObjectType { return INTEGER_OBJ } 38 39 type Boolean struct { 40 Value bool 41 } 42 43 func (b *Boolean) Inspect() string { return fmt.Sprintf("%t", b.Value) } 44 func (b *Boolean) Type() ObjectType { return BOOLEAN_OBJ } 45 46 type Null struct{} 47 48 func (n *Null) Inspect() string { return "null" } 49 func (n *Null) Type() ObjectType { return NULL_OBJ } 50 51 type ReturnValue struct { 52 Value Object 53 } 54 55 func (rv *ReturnValue) Inspect() string { return rv.Value.Inspect() } 56 func (rv *ReturnValue) Type() ObjectType { return RETURN_VALUE_OBJ } 57 58 type Error struct { 59 Message string 60 } 61 62 func (e *Error) Inspect() string { return "error: " + e.Message } 63 func (e *Error) Type() ObjectType { return ERROR_OBJ } 64 65 type Function struct { 66 Parameters []*ast.Identifier 67 Body *ast.BlockStatement 68 Ctx *Context 69 } 70 71 func (f *Function) Type() ObjectType { return FUNCTION_OBJ } 72 func (f *Function) Inspect() string { 73 var out bytes.Buffer 74 params := []string{} 75 for _, p := range f.Parameters { 76 params = append(params, p.String()) 77 } 78 out.WriteString("fn(") 79 out.WriteString(strings.Join(params, ", ")) 80 out.WriteString(") {\n") 81 out.WriteString(f.Body.String()) 82 out.WriteString("\n}") 83 return out.String() 84 } 85 86 type String struct { 87 Value string 88 } 89 90 func (s *String) Type() ObjectType { return STRING_OBJ } 91 func (s *String) Inspect() string { return s.Value } 92 93 type Builtin struct { 94 Fn BuiltinFunction 95 } 96 97 func (b *Builtin) Type() ObjectType { return BUILTIN_OBJ } 98 func (b *Builtin) Inspect() string { return "builtin function" } 99 100 type Array struct { 101 Elements []Object 102 } 103 104 func (ao *Array) Type() ObjectType { return ARRAY_OBJ } 105 func (ao *Array) Inspect() string { 106 var out bytes.Buffer 107 elements := []string{} 108 for _, e := range ao.Elements { 109 elements = append(elements, e.Inspect()) 110 } 111 out.WriteString("[") 112 out.WriteString(strings.Join(elements, ", ")) 113 out.WriteString("]") 114 return out.String() 115 } 116 117 type HashKey struct { 118 Type ObjectType 119 Value uint64 120 } 121 122 func (s *String) HashKey() HashKey { 123 h := fnv.New64a() 124 h.Write([]byte(s.Value)) 125 return HashKey{Type: s.Type(), Value: h.Sum64()} 126 } 127 func (i *Integer) HashKey() HashKey { 128 return HashKey{Type: i.Type(), Value: uint64(i.Value)} 129 } 130 func (b *Boolean) HashKey() HashKey { 131 var value uint64 132 if b.Value { 133 value = 1 134 } else { 135 value = 0 136 } 137 return HashKey{Type: b.Type(), Value: value} 138 } 139 140 type HashPair struct { 141 Key Object 142 Value Object 143 } 144 type Hash struct { 145 Pairs map[HashKey]HashPair 146 } 147 148 func (h *Hash) Type() ObjectType { return HASH_OBJ } 149 func (h *Hash) Inspect() string { 150 var out bytes.Buffer 151 pairs := []string{} 152 for _, pair := range h.Pairs { 153 pairs = append(pairs, fmt.Sprintf("%s: %s", pair.Key.Inspect(), pair.Value.Inspect())) 154 } 155 out.WriteString("{") 156 out.WriteString(strings.Join(pairs, ", ")) 157 out.WriteString("}") 158 return out.String() 159 } 160 161 type Hashable interface { 162 HashKey() HashKey 163 }