aboutsummaryrefslogtreecommitdiff
path: root/go/src/types
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-09 18:05:30 -0500
committerJoel Martin <github@martintribe.org>2014-10-09 18:05:30 -0500
commitd667a1bb2e7294f8722bb31f1e6e8207b971c913 (patch)
treec79dff4e32c3d1a73369ba3203b435f0212aab45 /go/src/types
parent82efc357ba67da1eaf35ca92b6f249a344aae8d5 (diff)
downloadmal-d667a1bb2e7294f8722bb31f1e6e8207b971c913.tar.gz
mal-d667a1bb2e7294f8722bb31f1e6e8207b971c913.zip
go: add stepA_more. try* and more core functions.
Diffstat (limited to 'go/src/types')
-rw-r--r--go/src/types/types.go64
1 files changed, 52 insertions, 12 deletions
diff --git a/go/src/types/types.go b/go/src/types/types.go
index c79810f..a489aa3 100644
--- a/go/src/types/types.go
+++ b/go/src/types/types.go
@@ -3,13 +3,20 @@ package types
import (
"reflect"
"errors"
- //"fmt"
+ "fmt"
)
-//import (
-// "env"
-//)
+// Errors/Exceptions
+type MalError struct {
+ Obj MalType
+}
+
+func (e MalError) Error() string {
+ return fmt.Sprintf("%#v", e.Obj)
+}
+
+// General types
type MalType interface {
}
@@ -20,6 +27,28 @@ type EnvType interface {
Get(key string) (MalType, error)
}
+// Scalars
+func Nil_Q(obj MalType) bool {
+ switch obj.(type) {
+ case nil: return true
+ default: return false
+ }
+}
+
+func True_Q(obj MalType) bool {
+ switch tobj := obj.(type) {
+ case bool: return tobj == true
+ default: return false
+ }
+}
+
+func False_Q(obj MalType) bool {
+ switch tobj := obj.(type) {
+ case bool: return tobj == false
+ default: return false
+ }
+}
+
// Symbols
type Symbol struct {
Val string
@@ -40,7 +69,7 @@ type MalFunc struct {
Env EnvType
Params MalType
IsMacro bool
- GenEnv func(EnvType, []MalType, []MalType) (EnvType, error)
+ GenEnv func(EnvType, MalType, MalType) (EnvType, error)
}
func MalFunc_Q(obj MalType) bool {
@@ -59,12 +88,19 @@ func (f MalFunc) GetMacro() bool {
return f.IsMacro
}
-func (f MalFunc) Apply(a []MalType) (MalType, error) {
- slc, e := GetSlice(f.Params)
- if e != nil { return nil, e }
- env, e := f.GenEnv(f.Env, slc, a)
- if e != nil { return nil, e }
- return f.Eval(f.Exp, env)
+// Take either a MalFunc or regular function and apply it to the
+// arguments
+func Apply(f_mt MalType, a []MalType) (MalType, error) {
+ switch f := f_mt.(type) {
+ case MalFunc:
+ env, e := f.GenEnv(f.Env, f.Params, List{a})
+ if e != nil { return nil, e }
+ return f.Eval(f.Exp, env)
+ case func([]MalType)(MalType, error):
+ return f(a)
+ default:
+ return nil, errors.New("Invalid function to Apply")
+ }
}
@@ -73,6 +109,10 @@ type List struct {
Val []MalType
}
+func NewList(a ...MalType) MalType {
+ return List{a}
+}
+
func List_Q(obj MalType) bool {
switch obj.(type) {
case List: return true
@@ -115,7 +155,7 @@ func _obj_type(obj MalType) string {
}
func Sequential_Q(seq MalType) bool {
- //fmt.Printf("here1 %#v\n", reflect.TypeOf(seq).Name())
+ if seq == nil { return false }
return (reflect.TypeOf(seq).Name() == "List") ||
(reflect.TypeOf(seq).Name() == "Vector")
}