Skip to content

Commit

Permalink
Moved (env) from the core to the builtin package.
Browse files Browse the repository at this point in the history
This will close #99, once complete.
  • Loading branch information
skx committed Nov 22, 2022
1 parent f89cd8c commit 99c71ca
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 27 deletions.
29 changes: 29 additions & 0 deletions builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func PopulateEnvironment(env *env.Environment) {
env.Set("date", &primitive.Procedure{F: dateFn, Help: helpMap["date"]})
env.Set("directory:entries", &primitive.Procedure{F: directoryEntriesFn, Help: helpMap["directory:entries"]})
env.Set("directory?", &primitive.Procedure{F: directoryFn, Help: helpMap["directory?"], Args: []primitive.Symbol{primitive.Symbol("path")}})
env.Set("env", &primitive.Procedure{F: envFn, Help: helpMap["env"], Args: []primitive.Symbol{}})
env.Set("eq", &primitive.Procedure{F: eqFn, Help: helpMap["eq"], Args: []primitive.Symbol{primitive.Symbol("a"), primitive.Symbol("b")}})
env.Set("error", &primitive.Procedure{F: errorFn, Help: helpMap["error"], Args: []primitive.Symbol{primitive.Symbol("message")}})
env.Set("exists?", &primitive.Procedure{F: existsFn, Help: helpMap["exists?"], Args: []primitive.Symbol{primitive.Symbol("path")}})
Expand Down Expand Up @@ -458,6 +459,34 @@ func divideFn(env *env.Environment, args []primitive.Primitive) primitive.Primit
return primitive.Number(v)
}

// envFn returns registered "things" from our environment
func envFn(env *env.Environment, args []primitive.Primitive) primitive.Primitive {
// create a new list
var c primitive.List

for key, val := range env.Items() {

v := val.(primitive.Primitive)

tmp := primitive.NewHash()
tmp.Set(":name", primitive.String(key))
tmp.Set(":value", v)

// Is this a procedure? If so
// add the help-text
proc, ok := v.(*primitive.Procedure)
if ok {
if len(proc.Help) > 0 {
tmp.Set(":help", primitive.String(proc.Help))
}
}

c = append(c, tmp)
}

return c
}

// eqFn implements "eq"
func eqFn(env *env.Environment, args []primitive.Primitive) primitive.Primitive {
if len(args) != 2 {
Expand Down
38 changes: 38 additions & 0 deletions builtins/builtins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,44 @@ func TestEnsureHelpPresent(t *testing.T) {
}
}

// TestEnv tests env
func TestEnv(t *testing.T) {

// Load our standard library
st := stdlib.Contents()
std := string(st)

// Create a new interpreter
l := eval.New(std + "\n")

env := env.New()
l.Evaluate(env)

// No arguments
out := envFn(env, []primitive.Primitive{})

// Will lead to a list
e, ok := out.(primitive.List)
if !ok {
t.Fatalf("expected list, got %v", out)
}

// Ensure our list of items contains only hashes.
for _, x := range e {

// Get the hash
_, ok2 := x.(primitive.Hash)
if !ok2 {
t.Fatalf("env should have a list of hashes, found element %v", x)
}

}

if len(e) < 100 {
t.Fatalf("expected a lot of entries, got %d", len(e))
}
}

// TestEq tests "eq" (non-numerical equality)
func TestEq(t *testing.T) {

Expand Down
4 changes: 4 additions & 0 deletions builtins/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ path, recursively. It is a helper function used to implement directory:walk

See also: directory:walk, glob
%%
env

env returns all the registered symbols from the environment, as a list of hashes.
%%
eq

eq returns true if the two values supplied as parameters have the same type, and string representation.
Expand Down
27 changes: 0 additions & 27 deletions eval/specials.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,33 +90,6 @@ func (ev *Eval) evalSpecialForm(name string, args []primitive.Primitive, e *env.
}
return ret, true

case "env":

// create a new list
var c primitive.List

for key, val := range e.Items() {

v := val.(primitive.Primitive)

tmp := primitive.NewHash()
tmp.Set(":name", primitive.String(key))
tmp.Set(":value", v)

// Is this a procedure? If so
// add the help-text
proc, ok := v.(*primitive.Procedure)
if ok {
if len(proc.Help) > 0 {
tmp.Set(":help", primitive.String(proc.Help))
}
}

c = append(c, tmp)
}

return c, true

case "eval":
if len(args) != 1 {
return primitive.ArityError(), true
Expand Down

0 comments on commit 99c71ca

Please sign in to comment.