diff --git a/README.md b/README.md
index e220cd91f1d2e5f9372c0e6638958ba78f25e0ee..e1efc9044f6ee0037731b08510b0038b33d5cdd5 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,10 @@ pour lancer fouine sur le fichier `basic.ml` :
 ```
 dune exec ./main.exe < tests/basic.ml
 ```
+ou
+```
+dune exec ./main.exe tests/basic.ml
+```
 
 pour lancer fouine sur tous les fichiers de tests/ :
 ```
@@ -55,7 +59,7 @@ for fichier in tests/*
 do
     echo "Contenu puis test du fichier $fichier :"
     cat $fichier
-    dune exec ./main.exe < $fichier
+    dune exec ./main.exe $fichier
 done
 ```
 
diff --git a/affichage.ml b/affichage.ml
index 38567529a651c1d9d373404fcd2ac3b48dbe5528..68aef94c2c8471ccd334f7c543b88068af84ecbe 100644
--- a/affichage.ml
+++ b/affichage.ml
@@ -1,9 +1,5 @@
 open Expr
 
 let str_of_val = function
-  | Vi(i) -> String.concat "" ["int : ";string_of_int i]
-  | Vb(b) -> String.concat "" ["bool : ";string_of_bool b]
-  | VFun(x, _, _) -> String.concat "" ["Function of ";x]
-  | Vunit -> "unit"
-  | Vref(i) -> String.concat "" ["ref : ";string_of_int i]
-
+  | Vi(i) -> string_of_int i
+  | _ -> raise (Type "Attempt to print non-int")
diff --git a/eval.ml b/eval.ml
index a87d2861cbdf22f8c18fae1812a3356ecb505eea..ce767eedf93d5f1fc0bb5ce300ff12599114841f 100644
--- a/eval.ml
+++ b/eval.ml
@@ -12,6 +12,7 @@ let rec pop_var name = function
   | _::t -> pop_var name t
   
 (* Add a function in its own environment under the name func_name *)
+(* TODO : comment in README *)
 let recursify_fun fv func_name =
 	let varname, expr, env = f_of_v fv in
 	let rec recenv = (func_name, VFun(varname, expr, recenv))::env in
@@ -23,9 +24,9 @@ let rec eval env =
   | IntConst k -> Vi(k)
   | BoolConst b -> Vb(b)
   | ArithmeticBinary(op, e1, e2) -> Vi(op (i_of_v (eval env e1)) (i_of_v (eval env e2)))
-  | Ternary(b, e1, e2) -> Vi(if b_of_v (eval env b)
-                             then i_of_v (eval env e1)
-                             else i_of_v (eval env e2))
+  | Ternary(b, e1, e2) -> if b_of_v (eval env b)
+                             then (eval env e1)
+                             else (eval env e2)
   | ArithmeticCompareBinary(op, e1, e2) -> Vb(op (i_of_v(eval env e1)) (i_of_v(eval env e2)))
   | CompareBinary(op, e1, e2) -> Vb((cmp_fun op) (eval env e1) (eval env e2))
   | BoolBinary(op, e1, e2) -> Vb(op (b_of_v(eval env e1)) (b_of_v(eval env e2)))
@@ -33,17 +34,18 @@ let rec eval env =
   | Var s -> pop_var s env
   | VarDecl (_, "_", ve, e) -> begin ignore (eval env ve); eval env e end
   | VarDecl (isrec, v, ve, e) -> let varval = eval env ve in
-  	let v_rec = if isrec then recursify_fun varval v else varval in 
+  	let v_rec = if isrec then recursify_fun varval v else varval in
+  	check_val_close v_rec; 
   	eval ((v, v_rec)::env) e
   | Neg b -> Vb(not (b_of_v (eval env b)))
   | PrInt e -> let v = eval env e in print_string (str_of_val v); print_newline (); v 
-  | Fun (x, e) -> VFun(x, e, env)
+  | Fun (x, e) ->  VFun(x, e, env)
   | App (f, arg) -> let x, fexpr, fenv = f_of_v (eval env f) in eval ((x, eval env arg)::fenv) fexpr
   
-  |Ref(e) -> if !i=Array.length tab then raise Plus_de_place_dans_le_tas
+  | Ref(e) -> if !i=Array.length tab then raise Plus_de_place_dans_le_tas
              else tab.(!i) <- eval env e; i:=!i+1; Vref(!i-1)
-  |Unit -> Vunit
-  |Assign(e1, e2) -> tab.(ref_of_v (eval env e1)) <- eval env e2; Vunit
-  |Dereference(e) -> tab.(ref_of_v (eval env e))
+  | Unit -> Vunit
+  | Assign(e1, e2) -> tab.(ref_of_v (eval env e1)) <- eval env e2; Vunit
+  | Dereference(e) -> tab.(ref_of_v (eval env e))
   
 
diff --git a/expr.ml b/expr.ml
index 707d8962af2a8fd89c3c467c9dad275054dea74e..3e56b3f85252cec758c1d0363a1facbe98457560 100644
--- a/expr.ml
+++ b/expr.ml
@@ -26,16 +26,46 @@ type expr =
   | Assign of expr * expr
   | Unit
   | Ref of expr
+  
+let rec remove_list elem = function
+  | [] -> []
+  | p::q when p = elem -> remove_list elem q
+  | p::q -> p::remove_list elem q
+  
+let rec freevar = function
+  | IntConst _ | BoolConst _ -> []
+  | ArithmeticBinary (_, a, b) | ArithmeticCompareBinary (_, a, b) | CompareBinary (_, a, b) | BoolBinary (_, a, b) | Assign (a, b) -> freevar a @ freevar b
+  | Ternary (a, b, c) -> freevar a @ freevar b @ freevar c
+  | Var s -> [s]
+  | VarDecl (_, n, ve, e) -> freevar ve @ (remove_list n (freevar e))
+  | Ref e | Dereference e | Neg e | PrInt e -> freevar e
+  | Fun (x, e) -> remove_list x (freevar e)
+  | App (fe, ve) -> freevar fe @ freevar ve
+  | Unit -> []
 
 type valeur =
   | Vi of int
   | Vb of bool
+  (* Arg name, expression, environment *)
   | VFun of string*expr*((string*valeur) list)
   | Vunit
   | Vref of int
 
+let env_vars = List.map fst;;
+
 exception Type of string
 exception Undefined of string
+
+(* Check function value has no free variables *)
+let check_val_close = function
+  | VFun (varname, expr, env) -> let fv = ref (freevar expr) in
+  	fv := remove_list varname !fv;
+  	List.iter (fun x -> fv := remove_list x !fv) (env_vars env);
+  	if !fv <> [] then
+  		raise (Undefined (String.concat " " ("Undefined variables in definition of"::varname::":"::(!fv))))
+  	else
+  		()
+  | _ -> ()
         
 let b_of_v = function
   | Vb b -> b
diff --git a/main.ml b/main.ml
index a202f9c3b929820354ce6c6d394dd3e5bbf23536..ea5cb16350d03de6278ee414e0883f135b974017 100644
--- a/main.ml
+++ b/main.ml
@@ -1,12 +1,13 @@
 open Eval
-open Affichage
 
 let interpret e = eval [] e
 
 (* stdin désigne l'entrée standard (le clavier) *)
 (* lexbuf est un canal ouvert sur stdin *)
 
-let lexbuf = Lexing.from_channel stdin
+let channel = if Array.length (Sys.argv) == 1 then stdin else open_in (Sys.argv.(1))
+
+let lexbuf = Lexing.from_channel channel
 
 (* on enchaîne les tuyaux: lexbuf est passé à Lexer.token,
    et le résultat est donné à Parser.main *)
@@ -16,8 +17,7 @@ let parse () = Parser.main Lexer.token lexbuf
 (* la fonction que l'on lance ci-dessous *)
 let calc () =
   let result = parse () in
-  print_string (str_of_val (interpret result));
-  print_newline ();
+  ignore (interpret result);
   flush stdout (* on ignore car sinon, on a un val et on ne sait pas quoi en faire pour le moment *)
 
 let _ = calc()
diff --git a/parser.mly b/parser.mly
index c93f26dda34117f5765261a740000b8c651d37da..f66a70fde05c9a384f3f75ce5444748eb1a16694 100644
--- a/parser.mly
+++ b/parser.mly
@@ -31,12 +31,12 @@ open Expr   (* rappel: dans expr.ml:
 
 %left RIGHTARROW
 
+%left IN /* in le plus à gauche en premier */
+
 %left SEMICOLON
 
 %left ASSIGN
 
-%left IN /* in le plus à gauche en premier */
-
 %left ELSE /* Else le plus à gauche en premier */
 
 /* Faudra l'interpreter comme une fonction */
@@ -51,8 +51,6 @@ open Expr   (* rappel: dans expr.ml:
       PLUS et MINUS, car est sur une ligne située plus bas */
 
 %left TIMES DIVIDE
- 
-%nonassoc DEREF
            
 %nonassoc UMINUS  /* un "faux token", que l'on utilise pour le MINUS unaire */
                   /* cf. son usage plus bas : il sert à "marquer" une règle pour lui donner la
@@ -76,10 +74,17 @@ sexpr:
   | FALSE 							{ BoolConst(false) }
   | v=VARNAME 								{ Var(v) }
   | LPAREN e=expression RPAREN { e }
+  | LPAREN RPAREN                               { Unit }
+  | d=deref							{ d }
+
+deref:
+  | DEREF v=VARNAME                   { Dereference(Var(v)) }
+  | DEREF LPAREN e=expression RPAREN                   { Dereference(e) }
 
 applic:
   | LPAREN e=expression RPAREN e1=sexpr   { App(e, e1) }
   | f=VARNAME e=sexpr                         { App(Var(f), e) }
+  | f=deref e=sexpr                         { App(f, e) }
   | applic sexpr                          { App($1,$2) }
 
 
@@ -118,9 +123,7 @@ expression:			    /* règles de grammaire pour les expressions */
   		VarDecl(b, v, vexpr, e)
   	}
   | e1=expression SEMICOLON e2=expression       { VarDecl(false, "_", e1, e2) }
-  | DEREF ref=expression                        { Dereference(ref) }
   | e1=expression ASSIGN e2=expression          { Assign(e1, e2) }
-  | LPAREN RPAREN                               { Unit }
   | REF e=expression                            { Ref(e) }
 
 (* variable / function assignment part of a `let in` statement *)