rewrite interpreter recursion within the initial formalism.

This commit is contained in:
Lesenechal Remi 2020-03-12 17:32:49 +01:00
parent 660dcbb79f
commit 3a80fadcc8
4 changed files with 19 additions and 12 deletions

View File

@ -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 |}] ;

View File

@ -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

View File

@ -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

View File

@ -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)