type checking and error handling for builtins improved.
Some checks failed
Build / build (push) Successful in 11m16s
Test / build (push) Failing after 17m0s

This commit is contained in:
Chuck Smith
2024-03-25 16:18:08 -04:00
parent 1c99d2198b
commit 6d234099d1
52 changed files with 650 additions and 433 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -2,6 +2,10 @@ package object
type Null struct{}
func (n *Null) Bool() bool {
return false
}
func (n *Null) Type() ObjectType {
return NULL_OBJ
}

View File

@@ -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
}

View File

@@ -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
}