rewrite interpreter recursion within the initial formalism.
This commit is contained in:
parent
660dcbb79f
commit
3a80fadcc8
@ -54,4 +54,6 @@ let%expect_test _ =
|
|||||||
val set_add = { ; 0 = ({ ; 1 : int ; 2 : int ; 3 : int}) ; 1 = ({ ; 1 : int ; 2 : int ; 3 : int ; 4 : int}) ; 2 = ({ ; 1 : int}) }
|
val set_add = { ; 0 = ({ ; 1 : int ; 2 : int ; 3 : int}) ; 1 = ({ ; 1 : int ; 2 : int ; 3 : int ; 4 : int}) ; 2 = ({ ; 1 : int}) }
|
||||||
val set_iter_fail = "set_iter_fail" : failure
|
val set_iter_fail = "set_iter_fail" : failure
|
||||||
val set_mem = { ; 0 = (true) ; 1 = (false) ; 2 = (false) }
|
val set_mem = { ; 0 = (true) ; 1 = (false) ; 2 = (false) }
|
||||||
val recursion = 55 : int |}] ;
|
val recursion_let_rec_in = 55 : int
|
||||||
|
val sum_rec = <rec fun>
|
||||||
|
val top_level_recursion = 55 : int |}] ;
|
@ -272,25 +272,23 @@ and eval : Ast_typed.expression -> env -> value result
|
|||||||
match term.expression_content with
|
match term.expression_content with
|
||||||
| E_application ({expr1 = f; expr2 = args}) -> (
|
| E_application ({expr1 = f; expr2 = args}) -> (
|
||||||
let%bind f' = eval f env in
|
let%bind f' = eval f env in
|
||||||
|
let%bind args' = eval args env in
|
||||||
match f' with
|
match f' with
|
||||||
| V_Func_val (arg_names, body, f_env) ->
|
| V_Func_val (arg_names, body, f_env) ->
|
||||||
let%bind args' = eval args env in
|
|
||||||
let f_env' = Env.extend f_env (arg_names, args') in
|
let f_env' = Env.extend f_env (arg_names, args') in
|
||||||
eval body f_env'
|
eval body f_env'
|
||||||
| V_Func_rec (_fun_name,_fun_type,lambda, _env) ->
|
| V_Func_rec (fun_name, arg_names, body, f_env) ->
|
||||||
let%bind args' = eval args env in
|
let f_env' = Env.extend f_env (arg_names, args') in
|
||||||
let f_env' = Env.extend env (lambda.binder,args') in
|
let f_env'' = Env.extend f_env' (fun_name, f') in
|
||||||
eval lambda.result f_env'
|
eval body f_env''
|
||||||
| _ -> simple_fail "trying to apply on something that is not a function"
|
| _ -> simple_fail "trying to apply on something that is not a function"
|
||||||
)
|
)
|
||||||
| E_lambda {binder; result;} ->
|
| E_lambda {binder; result;} ->
|
||||||
ok @@ V_Func_val (binder,result,env)
|
ok @@ V_Func_val (binder,result,env)
|
||||||
| E_recursive {fun_name; fun_type;lambda} ->
|
| E_let_in {let_binder ; rhs; let_result} -> (
|
||||||
let env' = Env.extend env (fun_name, V_Func_rec(fun_name,fun_type,lambda,env)) in
|
|
||||||
ok @@ V_Func_rec (fun_name,fun_type,lambda,env')
|
|
||||||
| E_let_in { let_binder; rhs; let_result; _} ->
|
|
||||||
let%bind rhs' = eval rhs env in
|
let%bind rhs' = eval rhs env in
|
||||||
eval let_result (Env.extend env (let_binder,rhs'))
|
eval let_result (Env.extend env (let_binder,rhs'))
|
||||||
|
)
|
||||||
| E_map kvlist | E_big_map kvlist ->
|
| E_map kvlist | E_big_map kvlist ->
|
||||||
let%bind kvlist' = bind_map_list
|
let%bind kvlist' = bind_map_list
|
||||||
(fun kv -> bind_map_pair (fun (el:Ast_typed.expression) -> eval el env) kv)
|
(fun kv -> bind_map_pair (fun (el:Ast_typed.expression) -> eval el env) kv)
|
||||||
@ -378,6 +376,8 @@ and eval : Ast_typed.expression -> env -> value result
|
|||||||
| _ -> simple_fail "not yet supported case"
|
| _ -> simple_fail "not yet supported case"
|
||||||
(* ((ctor,name),body) *)
|
(* ((ctor,name),body) *)
|
||||||
)
|
)
|
||||||
|
| E_recursive {fun_name; fun_type=_; lambda} ->
|
||||||
|
ok @@ V_Func_rec (fun_name, lambda.binder, lambda.result, env)
|
||||||
| E_look_up _ ->
|
| E_look_up _ ->
|
||||||
let serr = Format.asprintf "Unsupported construct :\n %a\n" Ast_typed.PP.expression term in
|
let serr = Format.asprintf "Unsupported construct :\n %a\n" Ast_typed.PP.expression term in
|
||||||
simple_fail serr
|
simple_fail serr
|
||||||
|
@ -31,7 +31,7 @@ and constant_val =
|
|||||||
|
|
||||||
and value =
|
and value =
|
||||||
| V_Func_val of (expression_variable * Ast_typed.expression * env)
|
| V_Func_val of (expression_variable * Ast_typed.expression * env)
|
||||||
| V_Func_rec of (expression_variable * Ast_typed.type_expression * Ast_typed.lambda * env)
|
| V_Func_rec of (expression_variable * expression_variable * Ast_typed.expression * env)
|
||||||
| V_Ct of constant_val
|
| V_Ct of constant_val
|
||||||
| V_List of value list
|
| V_List of value list
|
||||||
| V_Record of value label_map
|
| V_Record of value label_map
|
||||||
|
@ -233,9 +233,14 @@ let set_mem =
|
|||||||
Set.mem 4 s,
|
Set.mem 4 s,
|
||||||
Set.mem 1 (Set.empty : int set)
|
Set.mem 1 (Set.empty : int set)
|
||||||
|
|
||||||
let recursion =
|
let recursion_let_rec_in =
|
||||||
let rec sum : int*int -> int = fun ((n,res):int*int) ->
|
let rec sum : int*int -> int = fun ((n,res):int*int) ->
|
||||||
let i = 1 in
|
let i = 1 in
|
||||||
if (n<1) then res else sum (n-i,res+n)
|
if (n<1) then res else sum (n-i,res+n)
|
||||||
in
|
in
|
||||||
sum (10,0)
|
sum (10,0)
|
||||||
|
|
||||||
|
let rec sum_rec ((n,acc):int * int) : int =
|
||||||
|
if (n < 1) then acc else sum_rec (n-1, acc+n)
|
||||||
|
|
||||||
|
let top_level_recursion = sum_rec (10,0)
|
Loading…
Reference in New Issue
Block a user