diff --git a/src/exec.ml b/src/exec.ml index 2d91b75..1b33609 100644 --- a/src/exec.ml +++ b/src/exec.ml @@ -37,12 +37,30 @@ let builtin_mem = fun x -> List.assoc x l let builtin_typctx = List.map (function(x,(t,_))->(x,(t,true))) builtins +let rec exp_captures bound = function + | EInt _ | EBool _ | EFnB _ -> [] + | EVar x -> if List.mem x bound then [] else [x] + | EFn (x, _, e) -> exp_captures (x::bound) e + | EApp (e1, e2) -> List.concat_map (exp_captures bound) [e1;e2] + | EIf (b, e1, e2) -> List.concat_map (exp_captures bound) [b;e1;e2] + | EScope s -> fst (stmt_captures bound s) +and stmt_captures bound = function + | SExp e | SAsgn (_, e) -> (exp_captures bound e, bound) + | SDecl (x, _) -> ([], [x]) + | SSeq (s1, s2) -> + let (c1, b1) = stmt_captures bound s1 in + let (c2, b2) = stmt_captures b1 s2 in + (c1@c2, b2) + let rec eval (m: mem) (e: exp) : value = match e with | EInt i -> VInt i | EBool b -> VBool b | EVar x -> m x - | EFn (x, _, e) -> VFn (m, x, e) + | EFn (x, _, e) -> + let c = exp_captures [x] e in + let m x = List.assoc x (List.map (fun x -> (x, m x)) c) in + VFn (m, x, e) | EFnB (_, _, f) -> VFnB (m, f) | EApp (e1, e2) -> (match eval m e1, eval m e2 with