Seperate apply from eval
This commit is contained in:
parent
71bc70d3bc
commit
34eeff4a01
1 changed files with 29 additions and 28 deletions
57
eval.ml
57
eval.ml
|
@ -219,9 +219,9 @@ let binop op l r =
|
|||
|
||||
exception Unbound of string
|
||||
|
||||
(* TODO: refactor eval, split function into parts *)
|
||||
let rec eval env ast =
|
||||
let rec aux = function
|
||||
let aux = eval env in (* eval with current env *)
|
||||
match ast with
|
||||
| Nothing -> Nop
|
||||
| Nint n -> Int n
|
||||
| Nfloat n -> Float n
|
||||
|
@ -241,36 +241,14 @@ let rec eval env ast =
|
|||
|
||||
| Unary (op, v) -> unary op (aux v)
|
||||
| Binop (l, op, r) -> binop op (aux l) (aux r)
|
||||
|
||||
| If (co, th, el) ->
|
||||
begin match aux co with
|
||||
| Bool true -> aux th
|
||||
| Bool false -> aux el
|
||||
| v -> raise @@ Type.Invalid (Value.typeof v)
|
||||
end
|
||||
|
||||
| Apply (v, args) ->
|
||||
begin match aux v with
|
||||
| Function (itself, var, e, env) as f ->
|
||||
begin match args with
|
||||
| [] -> f
|
||||
| a::args ->
|
||||
let env =
|
||||
(* binding itself into env for recursion *)
|
||||
Option.fold
|
||||
~none: env ~some: (fun v -> Env.bind (v, f) env)
|
||||
itself
|
||||
|> Env.bind (var, aux a)
|
||||
in
|
||||
eval env @@ Apply (e, args)
|
||||
end
|
||||
| External f ->
|
||||
let args = List.map aux args in
|
||||
External.apply f args
|
||||
| v ->
|
||||
if args = []
|
||||
then v
|
||||
else raise @@ Type.Invalid (Value.typeof v)
|
||||
end
|
||||
| Apply (v, args) -> apply v args env
|
||||
|
||||
| Set_binop_pre (op, l) ->
|
||||
let l =
|
||||
|
@ -290,9 +268,32 @@ let rec eval env ast =
|
|||
| None -> String "left"
|
||||
| Some a -> String (Parser.assoc_to_string a))
|
||||
| _ -> failwith "Eval.eval"
|
||||
in
|
||||
aux ast
|
||||
|
||||
(* apply args to result of expr *)
|
||||
and apply expr args env =
|
||||
match eval env expr with
|
||||
| Function (itself, var, e, env) as f ->
|
||||
begin match args with
|
||||
| [] -> f
|
||||
| a::args ->
|
||||
let value = eval env a in
|
||||
let env = (* binding itself into env for recursion *)
|
||||
itself
|
||||
|> Option.fold
|
||||
~none: env
|
||||
~some: (fun n -> Env.bind (n, f) env)
|
||||
|> Env.bind (var, value)
|
||||
in
|
||||
eval env @@ Apply (e, args)
|
||||
end
|
||||
| External f ->
|
||||
let args = List.map (eval env) args in
|
||||
External.apply f args
|
||||
| v ->
|
||||
if args = [] then v
|
||||
else raise @@ Type.Invalid (Value.typeof v)
|
||||
|
||||
(* toplevel for global let *)
|
||||
let eval_top env_ref ast =
|
||||
let var, v = match ast with
|
||||
| Let (var, Nfunction (arg, e)) -> (* named function *)
|
||||
|
|
Loading…
Add table
Reference in a new issue