diff --git a/builtin.go b/builtin.go index 8c69394..f765a3f 100644 --- a/builtin.go +++ b/builtin.go @@ -228,3 +228,11 @@ var cdr = builtin{ return s.items[1:], nil }, } + +var names = builtin{ + name: "names", + arity: 0, + fn: func(vals []interface{}) (interface{}, error) { + return universe.keys(), nil + }, +} diff --git a/env.go b/env.go index ab44e02..2273629 100644 --- a/env.go +++ b/env.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "sort" ) type UnknownSymbolError struct{ symbol } @@ -40,6 +41,15 @@ func (e environment) set(key symbol, val interface{}) { e.items[key] = val } +func (e environment) keys() []string { + keys := make([]string, 0, len(e.items)) + for key, _ := range e.items { + keys = append(keys, string(key)) + } + sort.Strings(keys) + return keys +} + func (e environment) defined(key symbol) bool { _, err := e.get(key) return err == nil diff --git a/skeam.go b/skeam.go index cc93c23..6a1adab 100644 --- a/skeam.go +++ b/skeam.go @@ -85,6 +85,10 @@ var universe = &environment{map[symbol]interface{}{ symbol(set.name): set, }, nil} +func init() { + universe.set(symbol(names.name), names) +} + // parses the string lexeme into a value that can be eval'd func atom(t token) (interface{}, error) { switch t.t {