aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-10-09 23:54:08 -0500
committerJoel Martin <github@martintribe.org>2015-01-06 21:57:24 -0600
commit61a2c2a7042308cd4046b20d7f198ec7d3fedcbf (patch)
treef57103078050f8f4d35576fe864c19bb90bd4b2c
parent01c9731649a7ed97fad0bdeac9cb75b7323c0ad6 (diff)
downloadmal-61a2c2a7042308cd4046b20d7f198ec7d3fedcbf.tar.gz
mal-61a2c2a7042308cd4046b20d7f198ec7d3fedcbf.zip
Go: add missing env.go
-rw-r--r--go/src/env/env.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/go/src/env/env.go b/go/src/env/env.go
new file mode 100644
index 0000000..4d20857
--- /dev/null
+++ b/go/src/env/env.go
@@ -0,0 +1,59 @@
+package env
+
+import (
+ "errors"
+ //"fmt"
+)
+
+import (
+ . "types"
+)
+
+type Env struct {
+ data map[string]MalType
+ outer EnvType
+}
+
+func NewEnv(outer EnvType, binds_mt MalType, exprs_mt MalType) (EnvType, error) {
+ env := Env{map[string]MalType{}, outer}
+
+ if binds_mt != nil && exprs_mt != nil {
+ binds, e := GetSlice(binds_mt); if e != nil { return nil, e }
+ exprs, e := GetSlice(exprs_mt); if e != nil { return nil, e }
+ // Return a new Env with symbols in binds boudn to
+ // corresponding values in exprs
+ for i := 0; i < len(binds); i+=1 {
+ if (Symbol_Q(binds[i]) && binds[i].(Symbol).Val == "&") {
+ env.data[binds[i+1].(Symbol).Val] = List{exprs[i:],nil}
+ break
+ } else {
+ env.data[binds[i].(Symbol).Val] = exprs[i]
+ }
+ }
+ }
+ //return &et, nil
+ return env, nil
+}
+
+func (e Env) Find(key string) EnvType {
+ if _, ok := e.data[key]; ok {
+ return e
+ } else if (e.outer != nil) {
+ return e.outer.Find(key)
+ } else {
+ return nil
+ }
+}
+
+func (e Env) Set(key string, value MalType) MalType {
+ e.data[key] = value
+ return value
+}
+
+func (e Env) Get(key string) (MalType, error) {
+ env := e.Find(key)
+ if env == nil {
+ return nil, errors.New("'" + key + "' not found")
+ }
+ return env.(Env).data[key], nil
+}