aboutsummaryrefslogtreecommitdiff
path: root/go/src/core/core.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/src/core/core.go')
-rw-r--r--go/src/core/core.go686
1 files changed, 411 insertions, 275 deletions
diff --git a/go/src/core/core.go b/go/src/core/core.go
index 2acca69..159acc7 100644
--- a/go/src/core/core.go
+++ b/go/src/core/core.go
@@ -1,380 +1,516 @@
package core
import (
- "errors"
- "io/ioutil"
- "fmt"
- "time"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "time"
)
import (
- . "types"
- "reader"
- "printer"
- "readline"
+ "printer"
+ "reader"
+ "readline"
+ . "types"
)
// Errors/Exceptions
func throw(a []MalType) (MalType, error) {
- return nil, MalError{a[0]}
+ return nil, MalError{a[0]}
}
-
// String functions
func pr_str(a []MalType) (MalType, error) {
- return printer.Pr_list(a, true, "", "", " "), nil
+ return printer.Pr_list(a, true, "", "", " "), nil
}
func str(a []MalType) (MalType, error) {
- return printer.Pr_list(a, false, "", "", ""), nil
+ return printer.Pr_list(a, false, "", "", ""), nil
}
func prn(a []MalType) (MalType, error) {
- fmt.Println(printer.Pr_list(a, true, "", "", " "))
- return nil, nil
+ fmt.Println(printer.Pr_list(a, true, "", "", " "))
+ return nil, nil
}
func println(a []MalType) (MalType, error) {
- fmt.Println(printer.Pr_list(a, false, "", "", " "))
- return nil, nil
+ fmt.Println(printer.Pr_list(a, false, "", "", " "))
+ return nil, nil
}
func slurp(a []MalType) (MalType, error) {
- b, e := ioutil.ReadFile(a[0].(string))
- if e != nil { return nil, e }
- return string(b), nil
+ b, e := ioutil.ReadFile(a[0].(string))
+ if e != nil {
+ return nil, e
+ }
+ return string(b), nil
}
// Number functions
func time_ms(a []MalType) (MalType, error) {
- return int(time.Now().UnixNano() / int64(time.Millisecond)), nil
+ return int(time.Now().UnixNano() / int64(time.Millisecond)), nil
}
-
// Hash Map functions
-func copy_hash_map(hm HashMap) (HashMap) {
- new_hm := HashMap{map[string]MalType{},nil}
- for k, v := range hm.Val { new_hm.Val[k] = v }
- return new_hm
+func copy_hash_map(hm HashMap) HashMap {
+ new_hm := HashMap{map[string]MalType{}, nil}
+ for k, v := range hm.Val {
+ new_hm.Val[k] = v
+ }
+ return new_hm
}
func assoc(a []MalType) (MalType, error) {
- if len(a) <3 { return nil, errors.New("assoc requires at least 3 arguments") }
- if (len(a) % 2 != 1) { return nil, errors.New("assoc requires odd number of arguments") }
- if !HashMap_Q(a[0]) { return nil, errors.New("assoc called on non-hash map") }
- new_hm := copy_hash_map(a[0].(HashMap))
- for i := 1; i < len(a); i+=2 {
- key := a[i]
- if !String_Q(key) { return nil, errors.New("assoc called with non-string key") }
- new_hm.Val[key.(string)] = a[i+1]
- }
- return new_hm, nil
+ if len(a) < 3 {
+ return nil, errors.New("assoc requires at least 3 arguments")
+ }
+ if len(a)%2 != 1 {
+ return nil, errors.New("assoc requires odd number of arguments")
+ }
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("assoc called on non-hash map")
+ }
+ new_hm := copy_hash_map(a[0].(HashMap))
+ for i := 1; i < len(a); i += 2 {
+ key := a[i]
+ if !String_Q(key) {
+ return nil, errors.New("assoc called with non-string key")
+ }
+ new_hm.Val[key.(string)] = a[i+1]
+ }
+ return new_hm, nil
}
func dissoc(a []MalType) (MalType, error) {
- if len(a) <2 { return nil, errors.New("dissoc requires at least 3 arguments") }
- if !HashMap_Q(a[0]) { return nil, errors.New("dissoc called on non-hash map") }
- new_hm := copy_hash_map(a[0].(HashMap))
- for i := 1; i < len(a); i+=1 {
- key := a[i]
- if !String_Q(key) { return nil, errors.New("dissoc called with non-string key") }
- delete(new_hm.Val,key.(string))
- }
- return new_hm, nil
+ if len(a) < 2 {
+ return nil, errors.New("dissoc requires at least 3 arguments")
+ }
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("dissoc called on non-hash map")
+ }
+ new_hm := copy_hash_map(a[0].(HashMap))
+ for i := 1; i < len(a); i += 1 {
+ key := a[i]
+ if !String_Q(key) {
+ return nil, errors.New("dissoc called with non-string key")
+ }
+ delete(new_hm.Val, key.(string))
+ }
+ return new_hm, nil
}
func get(a []MalType) (MalType, error) {
- if len(a) != 2 { return nil, errors.New("get requires 2 arguments") }
- if Nil_Q(a[0]) { return nil, nil }
- if !HashMap_Q(a[0]) { return nil, errors.New("get called on non-hash map") }
- if !String_Q(a[1]) { return nil, errors.New("get called with non-string key") }
- return a[0].(HashMap).Val[a[1].(string)], nil
+ if len(a) != 2 {
+ return nil, errors.New("get requires 2 arguments")
+ }
+ if Nil_Q(a[0]) {
+ return nil, nil
+ }
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("get called on non-hash map")
+ }
+ if !String_Q(a[1]) {
+ return nil, errors.New("get called with non-string key")
+ }
+ return a[0].(HashMap).Val[a[1].(string)], nil
}
func contains_Q(hm MalType, key MalType) (MalType, error) {
- if Nil_Q(hm) { return false, nil }
- if !HashMap_Q(hm) { return nil, errors.New("get called on non-hash map") }
- if !String_Q(key) { return nil, errors.New("get called with non-string key") }
- _, ok := hm.(HashMap).Val[key.(string)]
- return ok, nil
+ if Nil_Q(hm) {
+ return false, nil
+ }
+ if !HashMap_Q(hm) {
+ return nil, errors.New("get called on non-hash map")
+ }
+ if !String_Q(key) {
+ return nil, errors.New("get called with non-string key")
+ }
+ _, ok := hm.(HashMap).Val[key.(string)]
+ return ok, nil
}
func keys(a []MalType) (MalType, error) {
- if !HashMap_Q(a[0]) { return nil, errors.New("keys called on non-hash map") }
- slc := []MalType{}
- for k, _ := range a[0].(HashMap).Val {
- slc = append(slc, k)
- }
- return List{slc,nil}, nil
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("keys called on non-hash map")
+ }
+ slc := []MalType{}
+ for k, _ := range a[0].(HashMap).Val {
+ slc = append(slc, k)
+ }
+ return List{slc, nil}, nil
}
func vals(a []MalType) (MalType, error) {
- if !HashMap_Q(a[0]) { return nil, errors.New("keys called on non-hash map") }
- slc := []MalType{}
- for _, v := range a[0].(HashMap).Val {
- slc = append(slc, v)
- }
- return List{slc,nil}, nil
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("keys called on non-hash map")
+ }
+ slc := []MalType{}
+ for _, v := range a[0].(HashMap).Val {
+ slc = append(slc, v)
+ }
+ return List{slc, nil}, nil
}
-
// Sequence functions
func cons(a []MalType) (MalType, error) {
- val := a[0]
- lst, e := GetSlice(a[1]); if e != nil { return nil, e }
+ val := a[0]
+ lst, e := GetSlice(a[1])
+ if e != nil {
+ return nil, e
+ }
- return List{append([]MalType{val}, lst...),nil}, nil
+ return List{append([]MalType{val}, lst...), nil}, nil
}
func concat(a []MalType) (MalType, error) {
- if len(a) == 0 { return List{}, nil }
- slc1, e := GetSlice(a[0]); if e != nil { return nil, e }
- for i := 1; i < len(a); i+=1 {
- slc2, e := GetSlice(a[i]); if e != nil { return nil, e }
- slc1 = append(slc1, slc2...)
- }
- return List{slc1,nil}, nil
+ if len(a) == 0 {
+ return List{}, nil
+ }
+ slc1, e := GetSlice(a[0])
+ if e != nil {
+ return nil, e
+ }
+ for i := 1; i < len(a); i += 1 {
+ slc2, e := GetSlice(a[i])
+ if e != nil {
+ return nil, e
+ }
+ slc1 = append(slc1, slc2...)
+ }
+ return List{slc1, nil}, nil
}
func nth(a []MalType) (MalType, error) {
- slc, e := GetSlice(a[0]); if e != nil { return nil, e }
- idx := a[1].(int)
- if idx < len(slc) {
- return slc[idx], nil
- } else {
- return nil, errors.New("nth: index out of range")
- }
+ slc, e := GetSlice(a[0])
+ if e != nil {
+ return nil, e
+ }
+ idx := a[1].(int)
+ if idx < len(slc) {
+ return slc[idx], nil
+ } else {
+ return nil, errors.New("nth: index out of range")
+ }
}
func first(a []MalType) (MalType, error) {
- if len(a) == 0 { return nil, nil }
- slc, e := GetSlice(a[0]); if e != nil { return nil, e }
- if len(slc) == 0 { return nil, nil }
- return slc[0], nil
+ if len(a) == 0 {
+ return nil, nil
+ }
+ slc, e := GetSlice(a[0])
+ if e != nil {
+ return nil, e
+ }
+ if len(slc) == 0 {
+ return nil, nil
+ }
+ return slc[0], nil
}
func rest(a []MalType) (MalType, error) {
- slc, e := GetSlice(a[0]); if e != nil { return nil, e }
- if len(slc) == 0 { return List{}, nil }
- return List{slc[1:],nil}, nil
+ slc, e := GetSlice(a[0])
+ if e != nil {
+ return nil, e
+ }
+ if len(slc) == 0 {
+ return List{}, nil
+ }
+ return List{slc[1:], nil}, nil
}
-
func empty_Q(a []MalType) (MalType, error) {
- switch obj := a[0].(type) {
- case List: return len(obj.Val) == 0, nil
- case Vector: return len(obj.Val) == 0, nil
- case nil: return true, nil
- default: return nil, errors.New("Count called on non-sequence")
- }
+ switch obj := a[0].(type) {
+ case List:
+ return len(obj.Val) == 0, nil
+ case Vector:
+ return len(obj.Val) == 0, nil
+ case nil:
+ return true, nil
+ default:
+ return nil, errors.New("Count called on non-sequence")
+ }
}
func count(a []MalType) (MalType, error) {
- switch obj := a[0].(type) {
- case List: return len(obj.Val), nil
- case Vector: return len(obj.Val), nil
- case map[string]MalType: return len(obj), nil
- case nil: return 0, nil
- default: return nil, errors.New("Count called on non-sequence")
- }
+ switch obj := a[0].(type) {
+ case List:
+ return len(obj.Val), nil
+ case Vector:
+ return len(obj.Val), nil
+ case map[string]MalType:
+ return len(obj), nil
+ case nil:
+ return 0, nil
+ default:
+ return nil, errors.New("Count called on non-sequence")
+ }
}
func apply(a []MalType) (MalType, error) {
- if len(a) < 2 { return nil, errors.New("apply requires at least 2 args") }
- f := a[0]
- args := []MalType{}
- for _, b := range a[1:len(a)-1] {
- args = append(args, b)
- }
- last, e := GetSlice(a[len(a)-1]); if e != nil { return nil, e }
- args = append(args, last...)
- return Apply(f, args)
+ if len(a) < 2 {
+ return nil, errors.New("apply requires at least 2 args")
+ }
+ f := a[0]
+ args := []MalType{}
+ for _, b := range a[1 : len(a)-1] {
+ args = append(args, b)
+ }
+ last, e := GetSlice(a[len(a)-1])
+ if e != nil {
+ return nil, e
+ }
+ args = append(args, last...)
+ return Apply(f, args)
}
func do_map(a []MalType) (MalType, error) {
- if len(a) != 2 { return nil, errors.New("map requires 2 args") }
- f := a[0]
- results := []MalType{}
- args, e := GetSlice(a[1]); if e != nil { return nil, e }
- for _, arg := range args {
- res, e := Apply(f, []MalType{arg})
- results = append(results, res)
- if e != nil { return nil, e }
- }
- return List{results,nil}, nil
+ if len(a) != 2 {
+ return nil, errors.New("map requires 2 args")
+ }
+ f := a[0]
+ results := []MalType{}
+ args, e := GetSlice(a[1])
+ if e != nil {
+ return nil, e
+ }
+ for _, arg := range args {
+ res, e := Apply(f, []MalType{arg})
+ results = append(results, res)
+ if e != nil {
+ return nil, e
+ }
+ }
+ return List{results, nil}, nil
}
func conj(a []MalType) (MalType, error) {
- if len(a) <2 { return nil, errors.New("conj requires at least 2 arguments") }
- switch seq := a[0].(type) {
- case List:
- new_slc := []MalType{}
- for i := len(a)-1 ; i > 0 ; i-=1 {
- new_slc = append(new_slc, a[i])
- }
- return List{append(new_slc, seq.Val...),nil}, nil
- case Vector:
- new_slc := seq.Val
- for _, x := range a[1:] {
- new_slc = append(new_slc, x)
- }
- return Vector{new_slc,nil}, nil
- }
-
- if !HashMap_Q(a[0]) { return nil, errors.New("dissoc called on non-hash map") }
- new_hm := copy_hash_map(a[0].(HashMap))
- for i := 1; i < len(a); i+=1 {
- key := a[i]
- if !String_Q(key) { return nil, errors.New("dissoc called with non-string key") }
- delete(new_hm.Val,key.(string))
- }
- return new_hm, nil
+ if len(a) < 2 {
+ return nil, errors.New("conj requires at least 2 arguments")
+ }
+ switch seq := a[0].(type) {
+ case List:
+ new_slc := []MalType{}
+ for i := len(a) - 1; i > 0; i -= 1 {
+ new_slc = append(new_slc, a[i])
+ }
+ return List{append(new_slc, seq.Val...), nil}, nil
+ case Vector:
+ new_slc := seq.Val
+ for _, x := range a[1:] {
+ new_slc = append(new_slc, x)
+ }
+ return Vector{new_slc, nil}, nil
+ }
+
+ if !HashMap_Q(a[0]) {
+ return nil, errors.New("dissoc called on non-hash map")
+ }
+ new_hm := copy_hash_map(a[0].(HashMap))
+ for i := 1; i < len(a); i += 1 {
+ key := a[i]
+ if !String_Q(key) {
+ return nil, errors.New("dissoc called with non-string key")
+ }
+ delete(new_hm.Val, key.(string))
+ }
+ return new_hm, nil
}
-
-
// Metadata functions
func with_meta(a []MalType) (MalType, error) {
- if len(a) != 2 { return nil, errors.New("with-meta requires 2 args") }
- obj := a[0]; m := a[1]
- switch tobj := obj.(type) {
- case List: return List{tobj.Val,m}, nil
- case Vector: return Vector{tobj.Val,m}, nil
- case HashMap: return HashMap{tobj.Val,m}, nil
- case Func: return Func{tobj.Fn,m}, nil
- case MalFunc: fn := tobj; fn.Meta = m; return fn, nil
- default: return nil, errors.New("with-meta not supported on type")
- }
+ if len(a) != 2 {
+ return nil, errors.New("with-meta requires 2 args")
+ }
+ obj := a[0]
+ m := a[1]
+ switch tobj := obj.(type) {
+ case List:
+ return List{tobj.Val, m}, nil
+ case Vector:
+ return Vector{tobj.Val, m}, nil
+ case HashMap:
+ return HashMap{tobj.Val, m}, nil
+ case Func:
+ return Func{tobj.Fn, m}, nil
+ case MalFunc:
+ fn := tobj
+ fn.Meta = m
+ return fn, nil
+ default:
+ return nil, errors.New("with-meta not supported on type")
+ }
}
func meta(a []MalType) (MalType, error) {
- obj := a[0]
- switch tobj := obj.(type) {
- case List: return tobj.Meta, nil
- case Vector: return tobj.Meta, nil
- case HashMap: return tobj.Meta, nil
- case Func: return tobj.Meta, nil
- case MalFunc: return tobj.Meta, nil
- default: return nil, errors.New("meta not supported on type")
- }
+ obj := a[0]
+ switch tobj := obj.(type) {
+ case List:
+ return tobj.Meta, nil
+ case Vector:
+ return tobj.Meta, nil
+ case HashMap:
+ return tobj.Meta, nil
+ case Func:
+ return tobj.Meta, nil
+ case MalFunc:
+ return tobj.Meta, nil
+ default:
+ return nil, errors.New("meta not supported on type")
+ }
}
-
// Atom functions
func deref(a []MalType) (MalType, error) {
- if !Atom_Q(a[0]) { return nil, errors.New("deref called with non-atom") }
- return a[0].(*Atom).Val, nil
+ if !Atom_Q(a[0]) {
+ return nil, errors.New("deref called with non-atom")
+ }
+ return a[0].(*Atom).Val, nil
}
func reset_BANG(a []MalType) (MalType, error) {
- if !Atom_Q(a[0]) { return nil, errors.New("reset! called with non-atom") }
- a[0].(*Atom).Set(a[1])
- return a[1], nil
+ if !Atom_Q(a[0]) {
+ return nil, errors.New("reset! called with non-atom")
+ }
+ a[0].(*Atom).Set(a[1])
+ return a[1], nil
}
func swap_BANG(a []MalType) (MalType, error) {
- if !Atom_Q(a[0]) { return nil, errors.New("swap! called with non-atom") }
- if len(a) < 2 { return nil, errors.New("swap! requires at least 2 args") }
- atm := a[0].(*Atom)
- args := []MalType{atm.Val}
- f := a[1]
- args = append(args, a[2:]...)
- res, e := Apply(f, args)
- if e != nil { return nil, e }
- atm.Set(res)
- return res, nil
+ if !Atom_Q(a[0]) {
+ return nil, errors.New("swap! called with non-atom")
+ }
+ if len(a) < 2 {
+ return nil, errors.New("swap! requires at least 2 args")
+ }
+ atm := a[0].(*Atom)
+ args := []MalType{atm.Val}
+ f := a[1]
+ args = append(args, a[2:]...)
+ res, e := Apply(f, args)
+ if e != nil {
+ return nil, e
+ }
+ atm.Set(res)
+ return res, nil
}
-
// core namespace
var NS = map[string]MalType{
- "=": func(a []MalType) (MalType, error) {
- return Equal_Q(a[0], a[1]), nil },
- "throw": throw,
- "nil?": func(a []MalType) (MalType, error) {
- return Nil_Q(a[0]), nil },
- "true?": func(a []MalType) (MalType, error) {
- return True_Q(a[0]), nil },
- "false?": func(a []MalType) (MalType, error) {
- return False_Q(a[0]), nil },
- "symbol": func(a []MalType) (MalType, error) {
- return Symbol{a[0].(string)}, nil },
- "symbol?": func(a []MalType) (MalType, error) {
- return Symbol_Q(a[0]), nil },
- "keyword": func(a []MalType) (MalType, error) {
- return NewKeyword(a[0].(string)) },
- "keyword?": func(a []MalType) (MalType, error) {
- return Keyword_Q(a[0]), nil },
-
- "pr-str": func(a []MalType) (MalType, error) { return pr_str(a) },
- "str": func(a []MalType) (MalType, error) { return str(a) },
- "prn": func(a []MalType) (MalType, error) { return prn(a) },
- "println": func(a []MalType) (MalType, error) { return println(a) },
- "read-string": func(a []MalType) (MalType, error) {
- return reader.Read_str(a[0].(string)) },
- "slurp": slurp,
- "readline": func(a []MalType) (MalType, error) {
- return readline.Readline(a[0].(string)) },
-
- "<": func(a []MalType) (MalType, error) {
- return a[0].(int) < a[1].(int), nil },
- "<=": func(a []MalType) (MalType, error) {
- return a[0].(int) <= a[1].(int), nil },
- ">": func(a []MalType) (MalType, error) {
- return a[0].(int) > a[1].(int), nil },
- ">=": func(a []MalType) (MalType, error) {
- return a[0].(int) >= a[1].(int), nil },
- "+": func(a []MalType) (MalType, error) {
- return a[0].(int) + a[1].(int), nil },
- "-": func(a []MalType) (MalType, error) {
- return a[0].(int) - a[1].(int), nil },
- "*": func(a []MalType) (MalType, error) {
- return a[0].(int) * a[1].(int), nil },
- "/": func(a []MalType) (MalType, error) {
- return a[0].(int) / a[1].(int), nil },
- "time-ms": time_ms,
-
- "list": func(a []MalType) (MalType, error) {
- return List{a,nil}, nil },
- "list?": func(a []MalType) (MalType, error) {
- return List_Q(a[0]), nil },
- "vector": func(a []MalType) (MalType, error) {
- return Vector{a,nil}, nil },
- "vector?": func(a []MalType) (MalType, error) {
- return Vector_Q(a[0]), nil },
- "hash-map": func(a []MalType) (MalType, error) {
- return NewHashMap(List{a,nil}) },
- "map?": func(a []MalType) (MalType, error) {
- return HashMap_Q(a[0]), nil },
- "assoc": assoc,
- "dissoc": dissoc,
- "get": get,
- "contains?": func(a []MalType) (MalType, error) {
- return contains_Q(a[0], a[1]) },
- "keys": keys,
- "vals": vals,
-
- "sequential?": func(a []MalType) (MalType, error) {
- return Sequential_Q(a[0]), nil },
- "cons": cons,
- "concat": concat,
- "nth": nth,
- "first": first,
- "rest": rest,
- "empty?": empty_Q,
- "count": count,
- "apply": apply,
- "map": do_map,
- "conj": conj,
-
- "with-meta": with_meta,
- "meta": meta,
- "atom": func(a []MalType) (MalType, error) {
- return &Atom{a[0],nil}, nil },
- "atom?": func(a []MalType) (MalType, error) {
- return Atom_Q(a[0]), nil },
- "deref": deref,
- "reset!": reset_BANG,
- "swap!": swap_BANG,
- }
+ "=": func(a []MalType) (MalType, error) {
+ return Equal_Q(a[0], a[1]), nil
+ },
+ "throw": throw,
+ "nil?": func(a []MalType) (MalType, error) {
+ return Nil_Q(a[0]), nil
+ },
+ "true?": func(a []MalType) (MalType, error) {
+ return True_Q(a[0]), nil
+ },
+ "false?": func(a []MalType) (MalType, error) {
+ return False_Q(a[0]), nil
+ },
+ "symbol": func(a []MalType) (MalType, error) {
+ return Symbol{a[0].(string)}, nil
+ },
+ "symbol?": func(a []MalType) (MalType, error) {
+ return Symbol_Q(a[0]), nil
+ },
+ "keyword": func(a []MalType) (MalType, error) {
+ return NewKeyword(a[0].(string))
+ },
+ "keyword?": func(a []MalType) (MalType, error) {
+ return Keyword_Q(a[0]), nil
+ },
+
+ "pr-str": func(a []MalType) (MalType, error) { return pr_str(a) },
+ "str": func(a []MalType) (MalType, error) { return str(a) },
+ "prn": func(a []MalType) (MalType, error) { return prn(a) },
+ "println": func(a []MalType) (MalType, error) { return println(a) },
+ "read-string": func(a []MalType) (MalType, error) {
+ return reader.Read_str(a[0].(string))
+ },
+ "slurp": slurp,
+ "readline": func(a []MalType) (MalType, error) {
+ return readline.Readline(a[0].(string))
+ },
+
+ "<": func(a []MalType) (MalType, error) {
+ return a[0].(int) < a[1].(int), nil
+ },
+ "<=": func(a []MalType) (MalType, error) {
+ return a[0].(int) <= a[1].(int), nil
+ },
+ ">": func(a []MalType) (MalType, error) {
+ return a[0].(int) > a[1].(int), nil
+ },
+ ">=": func(a []MalType) (MalType, error) {
+ return a[0].(int) >= a[1].(int), nil
+ },
+ "+": func(a []MalType) (MalType, error) {
+ return a[0].(int) + a[1].(int), nil
+ },
+ "-": func(a []MalType) (MalType, error) {
+ return a[0].(int) - a[1].(int), nil
+ },
+ "*": func(a []MalType) (MalType, error) {
+ return a[0].(int) * a[1].(int), nil
+ },
+ "/": func(a []MalType) (MalType, error) {
+ return a[0].(int) / a[1].(int), nil
+ },
+ "time-ms": time_ms,
+
+ "list": func(a []MalType) (MalType, error) {
+ return List{a, nil}, nil
+ },
+ "list?": func(a []MalType) (MalType, error) {
+ return List_Q(a[0]), nil
+ },
+ "vector": func(a []MalType) (MalType, error) {
+ return Vector{a, nil}, nil
+ },
+ "vector?": func(a []MalType) (MalType, error) {
+ return Vector_Q(a[0]), nil
+ },
+ "hash-map": func(a []MalType) (MalType, error) {
+ return NewHashMap(List{a, nil})
+ },
+ "map?": func(a []MalType) (MalType, error) {
+ return HashMap_Q(a[0]), nil
+ },
+ "assoc": assoc,
+ "dissoc": dissoc,
+ "get": get,
+ "contains?": func(a []MalType) (MalType, error) {
+ return contains_Q(a[0], a[1])
+ },
+ "keys": keys,
+ "vals": vals,
+
+ "sequential?": func(a []MalType) (MalType, error) {
+ return Sequential_Q(a[0]), nil
+ },
+ "cons": cons,
+ "concat": concat,
+ "nth": nth,
+ "first": first,
+ "rest": rest,
+ "empty?": empty_Q,
+ "count": count,
+ "apply": apply,
+ "map": do_map,
+ "conj": conj,
+
+ "with-meta": with_meta,
+ "meta": meta,
+ "atom": func(a []MalType) (MalType, error) {
+ return &Atom{a[0], nil}, nil
+ },
+ "atom?": func(a []MalType) (MalType, error) {
+ return Atom_Q(a[0]), nil
+ },
+ "deref": deref,
+ "reset!": reset_BANG,
+ "swap!": swap_BANG,
+}