func (*Array) Type() Type {
	return ArrayType
}
Type returns the type of the Array.
package object
import (
	"bytes"
	"fmt"
	"hash/fnv"
	"strconv"
	"strings"
	"github.com/skatsuta/monkey-interpreter/ast"
)
type Type string
const (
	IntegerType Type = "Integer"
	FloatType = "Float"
	BooleanType = "Boolean"
	NilType = "Nil"
	ReturnValueType = "ReturnValue"
	ErrorType = "Error"
	FunctionType = "Function"
	StringType = "String"
	BuiltinType = "Builtin"
	ArrayType = "Array"
	HashType = "Hash"
	QuoteType = "Quote"
	MacroType = "Macro"
)
type Object interface {
	Type() Type
	Inspect() string
}
type HashKey struct {
	Type  Type
	Value uint64
}
type Hashable interface {
	HashKey() HashKey
}
type Integer struct {
	Value int64
}
func (i *Integer) Type() Type {
	return IntegerType
}
func (i *Integer) Inspect() string {
	return strconv.FormatInt(i.Value, 10)
}
func (i *Integer) HashKey() HashKey {
	return HashKey{
		Type:  i.Type(),
		Value: uint64(i.Value),
	}
}
type Float struct {
	Value float64
}
func (f *Float) Type() Type {
	return FloatType
}
func (f *Float) Inspect() string {
	return strconv.FormatFloat(f.Value, 'f', -1, 64)
}
func (f *Float) HashKey() HashKey {
	s := strconv.FormatFloat(f.Value, 'f', -1, 64)
	h := fnv.New64a()
	h.Write([]byte(s))
	return HashKey{
		Type:  f.Type(),
		Value: h.Sum64(),
	}
}
type Boolean struct {
	Value bool
}
func (b *Boolean) Type() Type {
	return BooleanType
}
func (b *Boolean) Inspect() string {
	return strconv.FormatBool(b.Value)
}
func (b *Boolean) HashKey() HashKey {
	key := HashKey{Type: b.Type()}
	if b.Value {
		key.Value = 1
	}
	return key
}
type Nil struct{}
func (n *Nil) Type() Type {
	return NilType
}
func (n *Nil) Inspect() string {
	return "nil"
}
type ReturnValue struct {
	Value Object
}
func (rv *ReturnValue) Type() Type {
	return ReturnValueType
}
func (rv *ReturnValue) Inspect() string {
	return rv.Value.Inspect()
}
type Error struct {
	Message string
}
func (e *Error) Type() Type {
	return ErrorType
}
func (e *Error) Inspect() string {
	return "Error: " + e.Message
}
type Function struct {
	Parameters []*ast.Ident
	Body       *ast.BlockStatement
	Env        Environment
}
func (f *Function) Type() Type {
	return FunctionType
}
func (f *Function) Inspect() string {
	var out bytes.Buffer
	params := make([]string, 0, len(f.Parameters))
	for _, p := range f.Parameters {
		params = append(params, p.String())
	}
	out.WriteString("fn(")
	out.WriteString(strings.Join(params, ", "))
	out.WriteString(") {\n")
	out.WriteString(f.Body.String())
	out.WriteString("\n}")
	return out.String()
}
type String struct {
	Value string
}
func (s *String) Type() Type {
	return StringType
}
func (s *String) Inspect() string {
	return s.Value
}
func (s *String) HashKey() HashKey {
	h := fnv.New64a()
	h.Write([]byte(s.Value))
	return HashKey{
		Type:  s.Type(),
		Value: h.Sum64(),
	}
}
type BuiltinFunction func(args ...Object) Object
type Builtin struct {
	Fn BuiltinFunction
}
func (b *Builtin) Type() Type {
	return BuiltinType
}
func (b *Builtin) Inspect() string {
	return "builtin function"
}
type Array struct {
	Elements []Object
}