From bd5524c6aca0d8ec8791c51571753650231f5e36 Mon Sep 17 00:00:00 2001 From: Steve Kemp Date: Sun, 16 Oct 2022 07:11:32 +0300 Subject: [PATCH] Allow easier aliasing. Rather than using "(set! new-name old-name)", which works, we should use an "(alias new-name old-name)" function which expresses our intent more cleanly. This closes #38. --- eval/eval.go | 18 ++++++++++++++++++ eval/eval_test.go | 8 +++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/eval/eval.go b/eval/eval.go index 4458f0c..c71379d 100644 --- a/eval/eval.go +++ b/eval/eval.go @@ -500,6 +500,24 @@ func (ev *Eval) eval(exp primitive.Primitive, e *env.Environment, expandMacro bo // first token/symbol switch listExp[0] { + // (alias ..) + case primitive.Symbol("alias"): + if len(listExp) != 3 { + return primitive.Error("Expected two arguments") + } + + // Name we'll use + name := listExp[1] + + // Existing function. + val := listExp[2] + + old, ok := e.Get(val.ToString()) + if ok { + e.Set(name.ToString(), old) + } + return primitive.Nil{} + // (do ..) case primitive.Symbol("do"): var ret primitive.Primitive diff --git a/eval/eval_test.go b/eval/eval_test.go index 8a9d803..ad1307e 100644 --- a/eval/eval_test.go +++ b/eval/eval_test.go @@ -194,6 +194,10 @@ a {`(split "steve" "")`, `(s t e v e)`}, {`(join (list "s" "t" "e" "v" "e"))`, `steve`}, + // alias + {`(alias explode split) (explode "steve" "")`, `(s t e v e)`}, + {`(alias ** #) (** 3 3)`, `27`}, + // comparison {"(< 1 3)", "#t"}, {"(< 10 3)", "#f"}, @@ -203,7 +207,7 @@ a {"(= 10 10)", "#t"}, {"(= -1 -1)", "#t"}, - // we have a LOT of built ins, but not 100 + // we have a LOT of built ins, but not 200 {"(> (length (env)) 10)", "#t"}, {"(> (length (env)) 50)", "#t"}, {"(< (length (env)) 200)", "#t"}, @@ -266,6 +270,8 @@ a {"{ :age 333 ", "nil"}, {"}}}}}}", "nil"}, + {"(alias foo)", "ERROR{Expected two arguments}"}, + // try / catch {"(try 3)", "ERROR{arity-error: not enough arguments for (try ..)}"}, {"(try 3 3)", "ERROR{expected a list for argument, got 3}"},