90 lines
1.6 KiB
Go
90 lines
1.6 KiB
Go
package object
|
|
|
|
import (
|
|
"fmt"
|
|
"hash/fnv"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type String struct {
|
|
Value string
|
|
}
|
|
|
|
func (s String) Len() int {
|
|
return utf8.RuneCountInString(s.Value)
|
|
}
|
|
|
|
func (s String) Bool() bool {
|
|
return s.Value != ""
|
|
}
|
|
|
|
func (s String) Type() Type {
|
|
return StringType
|
|
}
|
|
|
|
func (s String) Inspect() string {
|
|
return fmt.Sprintf("%#v", s.Value)
|
|
}
|
|
|
|
func (s String) Copy() Object {
|
|
return String{Value: s.Value}
|
|
}
|
|
|
|
// Hash implements the Hasher interface
|
|
func (s String) Hash() HashKey {
|
|
h := fnv.New64a()
|
|
h.Write([]byte(s.Value))
|
|
|
|
return HashKey{Type: s.Type(), Value: h.Sum64()}
|
|
}
|
|
|
|
func (s String) String() string {
|
|
return s.Value
|
|
}
|
|
|
|
func (s String) Add(other Object) (Object, error) {
|
|
switch obj := other.(type) {
|
|
case String:
|
|
return String{s.Value + obj.Value}, nil
|
|
default:
|
|
return nil, NewBinaryOpError(s, other, "+")
|
|
}
|
|
}
|
|
|
|
func (s String) Mul(other Object) (Object, error) {
|
|
switch obj := other.(type) {
|
|
case Integer:
|
|
return String{strings.Repeat(s.Value, int(obj.Value))}, nil
|
|
default:
|
|
return nil, NewBinaryOpError(s, other, "*")
|
|
}
|
|
}
|
|
|
|
func (s String) Get(index Object) (Object, error) {
|
|
if !AssertTypes(index, IntegerType) {
|
|
return nil, fmt.Errorf("invalid type for string index, expected Integer got %s", index.Type())
|
|
}
|
|
|
|
i := int(index.(Integer).Value)
|
|
if i < 0 || i >= len(s.Value) {
|
|
return String{}, nil
|
|
}
|
|
|
|
return String{string(s.Value[i])}, nil
|
|
}
|
|
|
|
func (s String) Compare(other Object) int {
|
|
if obj, ok := other.(String); ok {
|
|
switch {
|
|
case s.Value < obj.Value:
|
|
return -1
|
|
case s.Value > obj.Value:
|
|
return 1
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
return 1
|
|
}
|