1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-11 13:55:55 +03:00

add & varargs and not

This commit is contained in:
Fabian 2021-04-02 23:42:35 +02:00 committed by Joel Martin
parent c6a73d68f0
commit 75814cb6f4
2 changed files with 21 additions and 4 deletions

View File

@ -29,7 +29,7 @@ and evalIf e [c,a,b] = if truthy (eval e c) then eval e a else eval e b
and evalFn e [(LIST binds),body] = makeFn e binds body
| evalFn e [(VECTOR binds),body] = makeFn e binds body
| evalFn _ _ = raise NotApplicable "fn* needs a list of bindings and a body"
and makeFn e binds body = FN (fn (exprs) => eval (bind (interleave binds exprs) (inside e)) body)
and makeFn e binds body = FN (fn (exprs) => eval (bind' binds exprs (inside e)) body)
and evalApply e (FN f) args = f (map (eval e) args)
| evalApply _ x args = raise NotApplicable (prStr x ^ " is not applicable on " ^ prStr (LIST args))
@ -41,6 +41,11 @@ and bind (SYMBOL s::v::rest) e = (def s (eval e v) e; bind rest e)
| bind [] e = e
| bind _ _ = raise NotApplicable "bindings must be a list of symbol/form pairs"
and bind' [SYMBOL "&", SYMBOL s] vs e = (def s (LIST (map (eval e) vs)) e; e)
| bind' (SYMBOL s::bs) (v::vs) e = (def s (eval e v) e; bind' bs vs e)
| bind' [] _ e = e
| bind' _ _ _ = raise NotApplicable "bindings must be a list of symbol/form pairs"
fun print f =
prReadableStr f
@ -67,4 +72,10 @@ fun repl e =
| NONE => ()
) end
fun main () = repl initEnv
val prelude = " \
\(def! not (fn* (a) (if a false true)))"
fun main () = (
rep initEnv ("(do " ^ prelude ^ " nil)");
repl initEnv
)

View File

@ -29,7 +29,7 @@ and evalIf e [c,a,b] = if truthy (eval e c) then eval e a else eval e b
and evalFn e [(LIST binds),body] = makeFn e binds body
| evalFn e [(VECTOR binds),body] = makeFn e binds body
| evalFn _ _ = raise NotApplicable "fn* needs a list of bindings and a body"
and makeFn e binds body = FN (fn (exprs) => eval (bind (interleave binds exprs) (inside e)) body)
and makeFn e binds body = FN (fn (exprs) => eval (bind' binds exprs (inside e)) body)
and evalApply e (FN f) args = f (map (eval e) args)
| evalApply _ x args = raise NotApplicable (prStr x ^ " is not applicable on " ^ prStr (LIST args))
@ -41,6 +41,11 @@ and bind (SYMBOL s::v::rest) e = (def s (eval e v) e; bind rest e)
| bind [] e = e
| bind _ _ = raise NotApplicable "bindings must be a list of symbol/form pairs"
and bind' [SYMBOL "&", SYMBOL s] vs e = (def s (LIST (map (eval e) vs)) e; e)
| bind' (SYMBOL s::bs) (v::vs) e = (def s (eval e v) e; bind' bs vs e)
| bind' [] _ e = e
| bind' _ _ _ = raise NotApplicable "bindings must be a list of symbol/form pairs"
fun print f =
prReadableStr f
@ -68,6 +73,7 @@ fun repl e =
) end
val prelude = " \
\(def! not (fn* (a) (if a false true))) \
\(def! \
\ load-file \
\ (fn* (f) \
@ -79,7 +85,7 @@ fun main () = (
FN (fn ([x]) => eval initEnv x
| _ => raise NotApplicable "'eval' requires one argument")
] initEnv;
rep initEnv prelude;
rep initEnv ("(do " ^ prelude ^ " nil)");
case CommandLine.arguments () of
prog::args => (
def "*ARGV*" (LIST (map STRING args)) initEnv;