Commit 99868eaf authored by Armillon Damien's avatar Armillon Damien
Browse files

Elang interpreter

parent 3a60e544
......@@ -117,8 +117,8 @@ let make_fundef_of_ast (a: tree) : (string * efun) res =
match a with
| Node (Tfundef, [StringLeaf fname; Node (Tfunargs, fargs); fbody]) ->
list_map_res make_ident fargs >>= fun fargs ->
(* TODO *)
Error "make_fundef_of_ast: Not implemented, yet."
make_einstr_of_ast fbody >>= fun fbody ->
OK((fname, {funargs= fargs; funbody = fbody}))
| _ ->
Error (Printf.sprintf "make_fundef_of_ast: Expected a Tfundef, got %s."
(string_of_ast a))
......
......@@ -12,17 +12,39 @@ let binop_bool_to_int f x y = if f x y then 1 else 0
et [y]. *)
let eval_binop (b: binop) : int -> int -> int =
match b with
| _ -> fun x y -> 0
| Eadd -> fun x y -> x + y
| Esub -> fun x y -> x - y
| Emul -> fun x y -> x * y
| Ediv -> fun x y -> x / y
| Emod -> fun x y -> (x mod y)
| Exor -> fun x y -> x lxor y
| Eclt -> fun x y -> binop_bool_to_int (<) x y
| Ecle -> fun x y -> binop_bool_to_int (<=) x y
| Ecgt -> fun x y -> binop_bool_to_int (>) x y
| Ecge -> fun x y -> binop_bool_to_int (>=) x y
| Eceq -> fun x y -> binop_bool_to_int (=) x y
| Ecne -> fun x y -> binop_bool_to_int (!=) x y
(* [eval_unop u x] évalue l'opération unaire [u] sur l'argument [x]. *)
let eval_unop (u: unop) : int -> int =
match u with
| _ -> fun x -> 0
| Eneg -> fun x -> -x
(* [eval_eexpr st e] évalue l'expression [e] dans l'état [st]. Renvoie une
erreur si besoin. *)
let rec eval_eexpr st (e : expr) : int res =
Error "eval_eexpr not implemented yet."
let {env} = st in
match e with
| Ebinop(op,expr1,expr2) ->
eval_eexpr st expr1 >>= fun value1 ->
eval_eexpr st expr2 >>= fun value2 ->
OK(eval_binop op value1 value2)
| Eunop(op,expr) -> eval_eexpr st expr >>= fun value -> OK(eval_unop op value)
| Evar(str) ->
(match Hashtbl.find_option env str with
| None -> Error (Format.sprintf "variable not %s found" str)
| Some(n) -> OK(n))
| Eint(n) -> OK(n)
(* [eval_einstr oc st ins] évalue l'instrution [ins] en partant de l'état [st].
......@@ -38,7 +60,32 @@ let rec eval_eexpr st (e : expr) : int res =
- [st'] est l'état mis à jour. *)
let rec eval_einstr oc (st: int state) (ins: instr) :
(int option * int state) res =
Error "eval_einstr not implemented yet."
let {env} = st in
let rec eval_list_instrs st li : (int option * int state) res =
match li with
| [] -> OK(None,st)
| instr::next_instrs -> eval_einstr oc st instr >>= fun result ->
match result with
| (None, st) -> eval_list_instrs st next_instrs
| (Some(n), st) -> OK(result)
in
let rec eval_while st e i: (int option * int state) res =
eval_eexpr st e >>= fun condition ->
if condition=1 then
eval_einstr oc st i >>= fun result_loop ->
match result_loop with
| (None, st)-> (eval_while st e i)
| (Some(n), st) -> OK(result_loop)
else OK(None, st)
in
match ins with
| Iassign(str, expr) -> eval_eexpr st expr >>= fun value -> Hashtbl.replace env str value; OK(None,st)
| Iif(expr,instr1,instr2) -> eval_eexpr st expr >>=
fun condition -> if condition=1 then eval_einstr oc st instr1 else eval_einstr oc st instr2
| Iwhile(expr,instr) -> eval_while st expr instr
| Iblock(instrs) -> eval_list_instrs st instrs
| Ireturn(expr) -> eval_eexpr st expr >>= fun result -> OK(Some(result), st)
| Iprint(expr) -> eval_eexpr st expr >>= fun result -> Format.fprintf oc "%d\n" result; OK(None, st)
(* [eval_efun oc st f fname vargs] évalue la fonction [f] (dont le nom est
[fname]) en partant de l'état [st], avec les arguments [vargs].
......@@ -88,5 +135,8 @@ let eval_eprog oc (ep: eprog) (memsize: int) (params: int list)
(* ne garde que le nombre nécessaire de paramètres pour la fonction "main". *)
let n = List.length f.funargs in
let params = take n params in
let { env } = st in
let { funargs } = f in
List.iter2 (fun argname argval -> Hashtbl.replace env argname argval) funargs params;
eval_efun oc st f "main" params >>= fun (v, st) ->
OK v
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment