type checking and error handling for builtins improved.
This commit is contained in:
@@ -14,6 +14,36 @@ func (ao *Array) Type() ObjectType {
|
||||
return ARRAY_OBJ
|
||||
}
|
||||
|
||||
func (ao *Array) Bool() bool {
|
||||
return len(ao.Elements) > 0
|
||||
}
|
||||
|
||||
func (a *Array) PopLeft() Object {
|
||||
if len(a.Elements) > 0 {
|
||||
e := a.Elements[0]
|
||||
a.Elements = a.Elements[1:]
|
||||
return e
|
||||
}
|
||||
return &Null{}
|
||||
}
|
||||
|
||||
func (a *Array) PopRight() Object {
|
||||
if len(a.Elements) > 0 {
|
||||
e := a.Elements[(len(a.Elements) - 1)]
|
||||
a.Elements = a.Elements[:(len(a.Elements) - 1)]
|
||||
return e
|
||||
}
|
||||
return &Null{}
|
||||
}
|
||||
|
||||
func (a *Array) Prepend(obj Object) {
|
||||
a.Elements = append([]Object{obj}, a.Elements...)
|
||||
}
|
||||
|
||||
func (a *Array) Append(obj Object) {
|
||||
a.Elements = append(a.Elements, obj)
|
||||
}
|
||||
|
||||
func (ao *Array) Inspect() string {
|
||||
var out bytes.Buffer
|
||||
|
||||
@@ -32,9 +62,9 @@ func (ao *Array) String() string {
|
||||
return ao.Inspect()
|
||||
}
|
||||
|
||||
func (a *Array) Less(i, j int) bool {
|
||||
if cmp, ok := a.Elements[i].(Comparable); ok {
|
||||
return cmp.Compare(a.Elements[j]) == -1
|
||||
func (ao *Array) Less(i, j int) bool {
|
||||
if cmp, ok := ao.Elements[i].(Comparable); ok {
|
||||
return cmp.Compare(ao.Elements[j]) == -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ type Boolean struct {
|
||||
Value bool
|
||||
}
|
||||
|
||||
func (b *Boolean) Bool() bool {
|
||||
return b.Value
|
||||
}
|
||||
|
||||
func (b *Boolean) Type() ObjectType {
|
||||
return BOOLEAN_OBJ
|
||||
}
|
||||
|
||||
@@ -7,12 +7,18 @@ type Builtin struct {
|
||||
Fn BuiltinFunction
|
||||
}
|
||||
|
||||
func (b *Builtin) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *Builtin) Type() ObjectType {
|
||||
return BUILTIN_OBJ
|
||||
}
|
||||
|
||||
func (b *Builtin) Inspect() string {
|
||||
return fmt.Sprintf("<built-in function %s>", b.Name)
|
||||
}
|
||||
|
||||
func (b *Builtin) String() string {
|
||||
return b.Inspect()
|
||||
}
|
||||
|
||||
@@ -11,12 +11,18 @@ type CompiledFunction struct {
|
||||
NumParameters int
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) Type() ObjectType {
|
||||
return COMPILED_FUNCTION_OBJ
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) Inspect() string {
|
||||
return fmt.Sprintf("CompiledFunction[%p]", cf)
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) String() string {
|
||||
return cf.Inspect()
|
||||
}
|
||||
@@ -26,12 +32,18 @@ type Closure struct {
|
||||
Free []Object
|
||||
}
|
||||
|
||||
func (c *Closure) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Closure) Type() ObjectType {
|
||||
return CLOSURE_OBJ
|
||||
}
|
||||
|
||||
func (c *Closure) Inspect() string {
|
||||
return fmt.Sprintf("Closure[%p]", c)
|
||||
}
|
||||
|
||||
func (c *Closure) String() string {
|
||||
return c.Inspect()
|
||||
}
|
||||
|
||||
@@ -4,15 +4,22 @@ type Error struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *Error) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *Error) Type() ObjectType {
|
||||
return ERROR_OBJ
|
||||
}
|
||||
|
||||
func (e *Error) Inspect() string {
|
||||
return "Error: " + e.Message
|
||||
}
|
||||
|
||||
func (e *Error) Clone() Object {
|
||||
return &Error{Message: e.Message}
|
||||
}
|
||||
|
||||
func (e *Error) String() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
@@ -12,9 +12,14 @@ type Function struct {
|
||||
Env *Environment
|
||||
}
|
||||
|
||||
func (f *Function) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *Function) Type() ObjectType {
|
||||
return FUNCTION_OBJ
|
||||
}
|
||||
|
||||
func (f *Function) Inspect() string {
|
||||
var out bytes.Buffer
|
||||
|
||||
@@ -32,6 +37,7 @@ func (f *Function) Inspect() string {
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func (f *Function) String() string {
|
||||
return f.Inspect()
|
||||
}
|
||||
@@ -40,12 +46,18 @@ type ReturnValue struct {
|
||||
Value Object
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) Type() ObjectType {
|
||||
return RETURN_VALUE_OBJ
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) Inspect() string {
|
||||
return rv.Value.Inspect()
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) String() string {
|
||||
return rv.Inspect()
|
||||
}
|
||||
|
||||
@@ -44,6 +44,14 @@ type Hash struct {
|
||||
Pairs map[HashKey]HashPair
|
||||
}
|
||||
|
||||
func (h *Hash) Len() int {
|
||||
return len(h.Pairs)
|
||||
}
|
||||
|
||||
func (h *Hash) Bool() bool {
|
||||
return len(h.Pairs) > 0
|
||||
}
|
||||
|
||||
func (h *Hash) Type() ObjectType {
|
||||
return HASH_OBJ
|
||||
}
|
||||
@@ -62,6 +70,7 @@ func (h *Hash) Inspect() string {
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func (h *Hash) String() string {
|
||||
return h.Inspect()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ type Integer struct {
|
||||
Value int64
|
||||
}
|
||||
|
||||
func (i *Integer) Bool() bool {
|
||||
return i.Value != 0
|
||||
}
|
||||
|
||||
func (i *Integer) Type() ObjectType {
|
||||
return INTEGER_OBJ
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package object
|
||||
|
||||
type Null struct{}
|
||||
|
||||
func (n *Null) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *Null) Type() ObjectType {
|
||||
return NULL_OBJ
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package object
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Type represents the type of an object
|
||||
type ObjectType string
|
||||
|
||||
@@ -25,6 +27,13 @@ type Comparable interface {
|
||||
Compare(other Object) int
|
||||
}
|
||||
|
||||
// Sizeable is the interface for returning the size of an Object.
|
||||
// Object(s) that have a valid size must implement this interface and the
|
||||
// Len() method.
|
||||
type Sizeable interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
// Immutable is the interface for all immutable objects which must implement
|
||||
// the Clone() method used by binding names to values.
|
||||
type Immutable interface {
|
||||
@@ -34,8 +43,9 @@ type Immutable interface {
|
||||
// Object represents a value and implementations are expected to implement
|
||||
// `Type()` and `Inspect()` functions
|
||||
type Object interface {
|
||||
fmt.Stringer
|
||||
Type() ObjectType
|
||||
String() string
|
||||
Bool() bool
|
||||
Inspect() string
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
package object
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"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() ObjectType {
|
||||
return STRING_OBJ
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user