diff --git a/src/elang.ml b/src/elang.ml
index 72b8e18b5c4a94b0226063a502ed274af1822d59..3e6fcf012826f4a0714f8c1d2398dc0a2381ec66 100644
--- a/src/elang.ml
+++ b/src/elang.ml
@@ -6,7 +6,7 @@ type unop = Eneg
 
 type expr =
     Ebinop of binop * expr * expr
-  | Eunop of unop * expr
+  | Eunop of unop * expr (*unused*)
   | Eint of int
   | Evar of string
 
diff --git a/src/elang_gen.ml b/src/elang_gen.ml
index be904b1e67d18e2c0f25d8896b1610cc1dbe287e..86761b7c4a9e47be776d2524366983f78a0b6712 100644
--- a/src/elang_gen.ml
+++ b/src/elang_gen.ml
@@ -44,10 +44,18 @@ let binop_of_tag =
 let rec make_eexpr_of_ast (a: tree) : expr res =
   let res =
     match a with
+    (* TODO *)
+    | IntLeaf i -> OK (Eint i)
+    | StringLeaf s -> OK (Evar s) 
     | Node(t, [e1; e2]) when tag_is_binop t ->
-         Error (Printf.sprintf "Unacceptable ast in make_eexpr_of_ast %s"
-                        (string_of_ast a))
-    | _ -> Error (Printf.sprintf "Unacceptable ast in make_eexpr_of_ast %s"
+        (let res1 = make_eexpr_of_ast e1
+          in let res2 = make_eexpr_of_ast e2
+            in match res1, res2 with
+            | Error msg, _ -> Error msg
+            | _, Error msg -> Error msg
+            | OK expr1, OK expr2 -> OK (Ebinop (binop_of_tag t, expr1, expr2)))
+    | _ -> 
+        Error (Printf.sprintf "Unacceptable ast in make_eexpr_of_ast %s"
                     (string_of_ast a))
   in
   match res with
@@ -59,6 +67,43 @@ let rec make_einstr_of_ast (a: tree) : instr res =
   let res =
     match a with
     (* TODO *)
+    | Node(Tassign, [StringLeaf s; e]) -> 
+      (let res_of_e = make_eexpr_of_ast e 
+        in match res_of_e with 
+        | OK exp -> OK (Iassign (s, exp))
+        | Error msg -> Error msg)
+    | Node(Tif, [e; i1; i2]) -> 
+      (let res_of_e = make_eexpr_of_ast e
+        in let res_of_i1 = make_einstr_of_ast i1
+          in let res_of_i2 = make_einstr_of_ast i2
+            in match res_of_e, res_of_i1, res_of_i2 with 
+            | Error msg, _, _ -> Error msg
+            | _, Error msg, _ -> Error msg
+            | _, _, Error msg -> Error msg
+            | OK exp, OK inst1, OK inst2 -> OK (Iif (exp, inst1, inst2)))
+    | Node(Twhile, [e; i]) -> 
+      (let res_of_e = make_eexpr_of_ast e
+        in let res_of_i = make_einstr_of_ast i
+          in match res_of_e, res_of_i with 
+          | Error msg, _ -> Error msg
+          | _, Error msg -> Error msg
+          | OK exp, OK inst-> OK (Iwhile (exp, inst)))
+    | Node(Tblock, i_list) -> 
+      (let res_of_i_list = list_map_res make_einstr_of_ast i_list
+        in match res_of_i_list with
+        | Error msg -> Error msg
+        | OK instr_list -> OK (Iblock instr_list))
+    | Node(Treturn, [e]) -> 
+      (let res_of_e = make_eexpr_of_ast e 
+        in match res_of_e with 
+        | OK exp -> OK (Ireturn exp)
+        | Error msg -> Error msg)
+    | Node(Tprint, [e]) -> 
+      (let res_of_e = make_eexpr_of_ast e 
+        in match res_of_e with 
+        | OK exp -> OK (Iprint exp)
+        | Error msg -> Error msg)
+    | NullLeaf -> OK (Iblock [])
     | _ -> Error (Printf.sprintf "Unacceptable ast in make_einstr_of_ast %s"
                     (string_of_ast a))
   in
@@ -76,10 +121,11 @@ let make_ident (a: tree) : string res =
 
 let make_fundef_of_ast (a: tree) : (string * efun) res =
   match a with
-  | Node (Tfundef, [StringLeaf fname; Node (Tfunargs, fargs); fbody]) ->
+  | Node (Tfundef, [Node(Tfunname, [StringLeaf fname]); Node (Tfunargs, fargs); Node(Tfunbody, [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))
diff --git a/src/elang_run.ml b/src/elang_run.ml
index 494b2c6ac0da84d327a4e1016b7da8f57b3ae57e..13afe7c5df8d3890b2e4eaf6ef834bd4235c1723 100644
--- a/src/elang_run.ml
+++ b/src/elang_run.ml
@@ -9,17 +9,46 @@ 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
+   | Emul -> fun x y -> x * y
+   | Emod -> fun x y -> x mod y
+   | Exor -> fun x y -> x lxor y
+   | Ediv -> fun x y -> x / y
+   | Esub -> fun x y -> x - y
+   | Eclt -> fun x y -> if x < y then 1 else 0
+   | Ecle -> fun x y -> if x <= y then 1 else 0
+   | Ecgt -> fun x y -> if x > y then 1 else 0
+   | Ecge -> fun x y -> if x >= y then 1 else 0
+   | Eceq -> fun x y -> if x = y then 1 else 0
+   | Ecne -> fun x y -> if x != y then 1 else 0
+
 
 (* [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."
+   match e with
+   | Eint i -> OK i
+   | Evar s -> 
+      (match Hashtbl.find_option st.env s with
+      | Some i -> OK i
+      | None -> Error "Variable is not defined")
+   | Ebinop (b, ex, ey) -> 
+      (let res_x = eval_eexpr st ex
+         in let res_y = eval_eexpr st ey
+            in match res_x, res_y with
+            | Error msg, _ -> Error msg
+            | _, Error msg -> Error msg
+            | OK x, OK y -> OK (eval_binop b x y))
+   | Eunop (u, ex) ->
+      (let res_x = eval_eexpr st ex
+         in match res_x with
+         | Error msg -> Error msg
+         | OK x -> OK (eval_unop u x ))
 
 (* [eval_einstr oc st ins] évalue l'instrution [ins] en partant de l'état [st].
 
@@ -35,7 +64,50 @@ 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."
+   match ins with
+   | Iassign (s, e) -> 
+      (match eval_eexpr st e with
+         | Error msg -> Error msg
+         | OK v -> 
+            let replace st s v =
+                  let new_env = Hashtbl.copy st.env 
+                     in Hashtbl.replace new_env s v; 
+                        {st with env = new_env}  
+               in OK (None, replace st s v))
+   | Iif (e, i1, i2) -> 
+      (match eval_eexpr st e with 
+      | Error msg -> Error msg
+      | OK v -> if v=1 then eval_einstr oc st i1 else eval_einstr oc st i2)
+   | Iwhile (e, i) -> 
+      (match eval_eexpr st e with
+         | Error msg -> Error msg
+         | OK v ->
+            if v=1 
+               then (let res_i = eval_einstr oc st i
+                  in match res_i with
+                  | Error msg -> Error msg
+                  | OK (r_opt, next_st) -> match r_opt with 
+                     | None -> eval_einstr oc next_st (Iwhile (e, i))
+                     | Some r -> OK (r_opt, next_st)) 
+               else OK(None, st))
+   | Iblock i_list -> 
+      (match i_list with
+      | [] -> OK (None, st)
+      | i::rest -> 
+         match eval_einstr oc st i with
+         | Error msg -> Error msg
+         | OK (Some r, next_st) -> OK (Some r, next_st)
+         | OK (None, next_st) -> eval_einstr oc next_st (Iblock rest))
+   | Ireturn e -> 
+      (match eval_eexpr st e with
+      | Error msg -> Error msg
+      | OK v -> OK(Some v, st))  
+   | Iprint e -> 
+      (match eval_eexpr st e with
+      | Error msg -> Error msg
+      | OK v -> 
+         Format.fprintf oc "%d\n" v;
+         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].