mirror of
https://github.com/kanaka/mal.git
synced 2024-09-11 13:55:55 +03:00
cleanup closures after env changes
This commit is contained in:
parent
9fc9f1c112
commit
4b3d031f4c
@ -107,9 +107,8 @@ val coreAtom = [
|
||||
| _ => raise NotApplicable "'reset!' requires an atom argument"),
|
||||
|
||||
SYMBOL "swap!",
|
||||
CLOSURE (fn e => (fn (ATOM a::(FN f)::args) => let val x = f ((!a)::args) in (a := x; x) end
|
||||
| (ATOM a::(CLOSURE f)::args) => let val x = f e ((!a)::args) in (a := x; x) end
|
||||
| _ => raise NotApplicable "'reset!' requires an atom argument"))
|
||||
FN (fn (ATOM a::(FN f)::args) => let val x = f ((!a)::args) in (a := x; x) end
|
||||
| _ => raise NotApplicable "'reset!' requires an atom argument")
|
||||
]
|
||||
|
||||
val coreNs = List.concat [
|
||||
|
@ -7,7 +7,6 @@ fun prStr NIL = "nil"
|
||||
| prStr (STRING s) = s
|
||||
| prStr (LIST l) = "(" ^ (String.concatWith " " (map prStr l)) ^ ")" (* N.B. not tail recursive *)
|
||||
| prStr (FN _) = "#<function>"
|
||||
| prStr (CLOSURE _) = "#<function>"
|
||||
|
||||
fun prReadableStr (STRING s) = "\"" ^ (malEscape s) ^ "\""
|
||||
| prReadableStr (ATOM x) = "(atom " ^ (prReadableStr (!x)) ^ ")"
|
||||
|
@ -23,12 +23,11 @@ and evalIf e [c,a,b] = if truthy (eval e c) then eval e a else eval e b
|
||||
| evalIf e [c,a] = evalIf e [c,a,NIL]
|
||||
| evalIf _ _ = raise NotApplicable "if needs two or three arguments"
|
||||
|
||||
and evalFn c [(LIST binds),body] = CLOSURE (fn (e) => fn (exprs) => eval (bind (interleave binds exprs) (inside (wrap e c))) body)
|
||||
and evalFn e [(LIST binds),body] = FN (fn (exprs) => eval (bind (interleave binds exprs) (inside e)) body)
|
||||
| evalFn _ _ = raise NotApplicable "fn* needs a list of bindings and a body"
|
||||
|
||||
and evalApply e (CLOSURE (f)) args = f e (map (eval e) args)
|
||||
| evalApply e (FN f) args = f (map (eval e) args)
|
||||
| evalApply _ x args = raise NotApplicable (prStr x ^ " is not applicable on " ^ prStr (LIST args))
|
||||
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))
|
||||
|
||||
and evalSymbol e s = valOrElse (lookup e s)
|
||||
(fn _ => raise NotDefined ("symbol '" ^ s ^ "' not found"))
|
||||
|
@ -23,12 +23,11 @@ and evalIf e [c,a,b] = if truthy (eval e c) then eval e a else eval e b
|
||||
| evalIf e [c,a] = evalIf e [c,a,NIL]
|
||||
| evalIf _ _ = raise NotApplicable "if needs two or three arguments"
|
||||
|
||||
and evalFn c [(LIST binds),body] = CLOSURE (fn (e) => fn (exprs) => eval (bind (interleave binds exprs) (inside (wrap e c))) body)
|
||||
and evalFn e [(LIST binds),body] = FN (fn (exprs) => eval (bind (interleave binds exprs) (inside e)) body)
|
||||
| evalFn _ _ = raise NotApplicable "fn* needs a list of bindings and a body"
|
||||
|
||||
and evalApply e (CLOSURE (f)) args = f e (map (eval e) args)
|
||||
| evalApply e (FN f) args = f (map (eval e) args)
|
||||
| evalApply _ x args = raise NotApplicable (prStr x ^ " is not applicable on " ^ prStr (LIST args))
|
||||
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))
|
||||
|
||||
and evalSymbol e s = valOrElse (lookup e s)
|
||||
(fn _ => raise NotDefined ("symbol '" ^ s ^ "' not found"))
|
||||
|
@ -6,7 +6,6 @@ datatype mal_type = NIL
|
||||
| LIST of mal_type list
|
||||
| ATOM of mal_type ref
|
||||
| FN of mal_type list -> mal_type
|
||||
| CLOSURE of mal_env -> mal_type list -> mal_type
|
||||
|
||||
and mal_ns = NS of (string * mal_type) list ref
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user