diff --git a/generator/Makefile b/generator/Makefile
index 8e532659eea388324e9898509786b30a8c699a08..db83ef9530edf097d8c076b6ba7d0ca42fcee828 100644
--- a/generator/Makefile
+++ b/generator/Makefile
@@ -6,8 +6,14 @@
 # OCAMLBIN=~/shared/ocamleasy/bin/
 # OCAMLLIB=~/shared/ocamleasy/lib
 
-ML_DIRS    := lex parsing tools typing utils
-OCAMLBUILD := ocamlbuild -r -j 4 -classic-display \
+ML_DIRS     := lex parsing tools typing utils stdlib_ml
+STD_DIR	    := stdlib_ml
+TEST_DIR    := tests
+TEST_DIR_JS := tests/js
+ML_TESTS    := $(wildcard $(TEST_DIR)/*.ml)
+
+CC          := ocamlc -c
+OCAMLBUILD  := ocamlbuild -r -j 4 -classic-display \
 	           $(addprefix -I ,$(ML_DIRS)) \
 
 all: main.byte
@@ -18,14 +24,22 @@ main.byte:
 native:
 	$(OCAMLBUILD) main.native
 
-test: main.byte
-	./main.byte _test.ml
+stdlib:
+	$(CC) stdlib_ml/stdlib.mli
 
-interp: main.byte
-	./main.byte _interp.ml
+tests: main.byte stdlib
+	$(foreach mlfile, $(ML_TESTS), ./main.byte $(mlfile);)
+	mv $(TEST_DIR)/*.js $(TEST_DIR_JS)
+
+clean_stdlib:
+	rm -f $(STD_DIR)/*.cmi
+
+clean_tests:
+	rm -f $(TEST_DIR)/*.cmi
+	rm -f $(TEST_DIR_JS)/*.js
 
 clean:
 	rm -rf _build
 	rm -f *.native *.byte
 
-#	rm -f *~
+cleanall: clean clean_tests clean_stdlib
diff --git a/generator/README b/generator/README
deleted file mode 100644
index e263542d23cc94170cc76e65e6eda761d670c8b7..0000000000000000000000000000000000000000
--- a/generator/README
+++ /dev/null
@@ -1,2 +0,0 @@
-All-in-one command:
-$ touch a.cmi && rm *.cm* && make && ocamlc -c stdlib.mli
diff --git a/generator/README.org b/generator/README.org
new file mode 100644
index 0000000000000000000000000000000000000000..a8a68c5e9ccce0c4bec91de58495825ed02a54eb
--- /dev/null
+++ b/generator/README.org
@@ -0,0 +1,62 @@
+* Js_of_ocaml bis
+
+** Why bis? & Purpose
+
+   Because, there is already a tool named `js_of_ocaml` whose job is
+   to produce efficient Javascript from OCaml bytecode.
+
+   Here, we try to translate OCaml syntax to ECMAScript5 syntax, the
+   purpose of it is to generate readable ECMAScript code, so that it
+   could later be use in a step-by-step ECMAScript interpreter.
+
+** Dependencies
+
+   - `node.js` and the `esprima` package. In order to get the esprima
+     package the more convenient way is to get `npm` (/node package
+     manager/) and run `npm install esprima`.
+   - ocaml 4.02.1
+
+** How to run it
+
+#+BEGIN_src
+make
+make tests
+./run tests/js/the_file_you_want_to_run.js
+#+END_src
+
+** How does it work?
+
+   In order to get the statically typed abstract syntax tree (STAST) of
+   OCaml we usethe same files that are used in the compiler of OCaml
+   4.02.1 (hence the dependency).
+
+   On top, of this STAST, there is a custom back-end that
+   transliterate OCaml to ECMAScript. The code written in OCaml cannot
+   rely on code from the typical standard library. Therefore a
+   file named `stdlib.mli` (found in the directory `stdlib_ml`) contains
+   all the required definitions for the exemples to work. This file as
+   a twin which is `stdlib.js` found in `stdlib_js`, in this file the
+   functions whose prototype is in `stdlib.mli` are defined here.
+
+** About the subset of OCaml supported
+
+   * ==Let (rec) == declarations, except `let () = ` and `let _ =`.
+   * ==If then else== statements, as excepted `if then else`
+     statements return a value.
+   * ==Pattern matching==, only one level of pattern matching over
+     arbitrary types.
+   * ==Types declarations==, if a constructor take arguments (one or
+     more), you should add an annotations to provide default names for
+     the parameters. See example below.
+
+#+BEGIN_src
+
+type 'a tree =
+  | Leaf [@f value] of `a
+  | Node [@f left, value, right] of `a tree * `a * `a tree          
+
+#+END_src
+
+Special note: from OCaml 4.02.2 annotations do not have the same
+syntax, but for now we work with OCaml 4.02.1 so the code above
+works and is recommended.
diff --git a/generator/_test.ml b/generator/_test.ml
deleted file mode 100644
index 824e243286732adfcd85fad99c8b878e115e355b..0000000000000000000000000000000000000000
--- a/generator/_test.ml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-let x = 3 in
-let _y = 4 in
-x
\ No newline at end of file
diff --git a/generator/go.sh b/generator/go.sh
deleted file mode 100755
index 8f58e6df93d2fce6854d17b4f850420e967ece40..0000000000000000000000000000000000000000
--- a/generator/go.sh
+++ /dev/null
@@ -1 +0,0 @@
-make
diff --git a/generator/js_of_ast.ml b/generator/js_of_ast.ml
index 1353b7281e751c59454bbe866481204179955088..d9be0fee0333301d0df86f930bf83f3a30a16600 100644
--- a/generator/js_of_ast.ml
+++ b/generator/js_of_ast.ml
@@ -2,7 +2,6 @@ open Misc
 open Asttypes
 open Types
 open Typedtree
-open Mytools
 open Longident
 open Format
 open Print_type
@@ -13,15 +12,8 @@ let hashtlb_size = 256
 let default_value = ["", [""]]
 let type_tbl = Hashtbl.create hashtlb_size;;
 
-let print_tbl () =
-    let rec print_str_list = function
-      | [] -> ""
-      | x :: [] -> (Format.sprintf {|"%s"|} x)
-      | x :: xs -> (Format.sprintf {|"%s", |} x) ^ print_str_list xs
-    in Hashtbl.iter (fun cstr elems -> Printf.printf ({|"%s" : %s -> [%s]|} ^^ "\n") cstr (snd elems) (print_str_list (fst elems))) type_tbl; ()
-
 let unsupported s =
-    failwith ("unsupported language construction: " ^ s ^ ".")
+  failwith ("unsupported language construction: " ^ s ^ ".")
 
 and out_of_scope s =
     failwith (s ^ " are and will not be supported.")
@@ -32,11 +24,11 @@ and error s =
 let rec range i j acc = if i <= j then range i (j - 1) (j :: acc) else acc
 
 let show_list_f f sep l = l
- |> List.map f
- |> List.fold_left (fun acc x -> acc ^ (if acc = "" then "" else sep) ^ x) ""
+  |> List.map f
+  |> List.fold_left (fun acc x -> acc ^ (if acc = "" then "" else sep) ^ x) ""
 
 let show_list sep l =
- List.fold_left (fun acc x -> acc ^ (if acc = "" then "" else sep) ^ x) "" l
+  List.fold_left (fun acc x -> acc ^ (if acc = "" then "" else sep) ^ x) "" l
 
 let js_of_constant = function
   | Const_int n -> string_of_int n
@@ -51,39 +43,35 @@ let js_of_longident loc =
   let res = String.concat "." @@ Longident.flatten loc.txt in
   if res = "()" then "" else res
 
-
-
 let ident_of_pat pat = match pat.pat_desc with
   | Tpat_var (id, _) -> Ident.name id
   | _ -> error "functions can't deconstruct values"
 
-
 let rec js_of_let_pattern pat expr = 
   let expr_type pat expr = match expr.exp_desc with
     | Texp_construct (loc, cd, el) ->
-        let value = js_of_longident loc in
-        if el = [] then
-            if value = "true" || value = "false" then value else Format.sprintf {|{tag: "%s"}|} value
-        else let rec expand_constructor_list fields exprs = match fields, exprs with
-          | [], [] -> []
-          | [], x :: xs | x :: xs , [] -> failwith "argument lists should have the same length."
-          | x :: xs, y :: ys -> Format.sprintf {|%s: %s|} x y :: expand_constructor_list xs ys
-        in let names, typ = Hashtbl.find type_tbl value
-        in Format.sprintf {|{tag: "%s", %s}|} value (show_list ", " (expand_constructor_list names (List.map js_of_expression el)))
+       let value = js_of_longident loc in
+       if el = [] then
+         if value = "true" || value = "false" then value else Format.sprintf "{type: \"%s}\"" value
+       else let rec expand_constructor_list fields exprs = match fields, exprs with
+              | [], [] -> []
+              | [], x :: xs | x :: xs , [] -> failwith "argument lists should have the same length."
+              | x :: xs, y :: ys -> Format.sprintf "@[%s:@,%s@]" x y :: expand_constructor_list xs ys
+            in let names, typ = Hashtbl.find type_tbl value
+            in Format.sprintf "{type: \"%s\",@, %s}" value (show_list ", " (expand_constructor_list names (List.map js_of_expression el)))
     | _ -> string_of_type_exp pat.pat_type in
   let sexpr = js_of_expression expr in
   match pat.pat_desc with
-  | Tpat_var (id, _) -> Format.sprintf "var %s = %s;\n"
-          (Ident.name id) sexpr
-  | Tpat_tuple (pat_l) | Tpat_array (pat_l) ->
-      let l = List.map (function pat -> match pat.pat_desc with
-        | Tpat_var (id, _) -> (Ident.name id, string_of_type_exp pat.pat_type)
-        | _ -> out_of_scope "pattern-matching in arrays") pat_l in
-      Format.sprintf "var __%s = %s;\n " "array" sexpr ^
-      List.fold_left2 (fun acc (name, exp_type) y ->
-          acc ^ Format.sprintf "var %s = __%s[%d];\n"
-          name "array" y)
-      "" l @@ range 0 (List.length l - 1) []
+  | Tpat_var (id, _) ->
+     Format.sprintf "@[<v 0>var %s = %s;@,@]" (Ident.name id) sexpr
+  | Tpat_tuple (pat_l)
+  | Tpat_array (pat_l) ->
+     let l = List.map (function pat -> match pat.pat_desc with
+                                       | Tpat_var (id, _) -> (Ident.name id, string_of_type_exp pat.pat_type)
+                                       | _ -> out_of_scope "pattern-matching in arrays") pat_l in
+     Format.sprintf "@[<v 0>var __%s = %s;@,@]" "array" sexpr ^
+       List.fold_left2 (fun acc (name, exp_type) y -> acc ^ Format.sprintf "@[<v 0>var %s = __%s[%d];@,@]" name "array" y)
+                       "" l @@ range 0 (List.length l - 1) []
   | _ -> error "let can't deconstruct values"
 
 and js_of_pattern pat obj = match pat.pat_desc with
@@ -93,13 +81,13 @@ and js_of_pattern pat obj = match pat.pat_desc with
   | Tpat_alias (_,_,_) -> out_of_scope "alias-pattern"
   | Tpat_tuple (_) -> out_of_scope "tuple matching"
   | Tpat_construct (loc, cd, el) ->
-      let c = js_of_longident loc in
-      let spat = {|case "|} ^ c ^ {|"|}  in
-      let params = fst (Hashtbl.find type_tbl c) in
-      let binders =
-        if List.length el = 0 then ""
-        else "var " ^ show_list ", " (List.map2 (fun x y -> x ^ " = " ^ obj ^ "." ^ y) (List.map (fun x -> fst (js_of_pattern x obj)) el) params) ^ ";" in
-      spat, binders
+     let c = js_of_longident loc in
+     let spat = Format.sprintf "%s" ("case \"" ^ c ^ "\"") in
+     let params = fst (Hashtbl.find type_tbl c) in
+     let binders =
+       if List.length el = 0 then Format.sprintf ""
+       else Format.sprintf "%s@," ("var " ^ show_list ", " (List.map2 (fun x y -> x ^ " = " ^ obj ^ "." ^ y) (List.map (fun x -> fst (js_of_pattern x obj)) el) params) ^ ";") in
+     spat, binders
   | Tpat_variant (_,_,_) -> out_of_scope "polymorphic variants in pattern matching"
   | Tpat_array (_) -> out_of_scope "array-match"
   | Tpat_record (_,_) -> out_of_scope "record"
@@ -110,20 +98,16 @@ and js_of_expression (e:expression) =
   let js_of_branch b obj =
     let spat, binders = js_of_pattern b.c_lhs obj in
     let se = js_of_expression b.c_rhs in
-    Format.sprintf "%s: @ %s @  return %s" spat binders se in
+    Format.sprintf "@[<v 2>%s: @[<v 4>%s@,return %s;@]@,@]" spat binders se in
   match e.exp_desc with
   | Texp_ident (_, loc, _) -> js_of_longident loc
   | Texp_constant c -> js_of_constant c
   | Texp_let (_, vb_l, e) ->
-      let show_val vb = js_of_let_pattern vb.vb_pat vb.vb_expr in
-      let sd = String.concat "\n" @@ List.map show_val @@ vb_l in
-      let se = js_of_expression e in
-      Format.sprintf
-        "(function () {
-            %s
-
-            return %s;
-        })()" sd se
+     let show_val vb = js_of_let_pattern vb.vb_pat vb.vb_expr in
+     let sd = String.concat "\n" @@ List.map show_val @@ vb_l in
+     let se = js_of_expression e in
+     Format.sprintf
+       "@[<v 0>(function () {@,@[<v 4>@,%s@,@,return %s;@,@]@,})()@]" sd se
   | Texp_function (_, c :: [], Total) ->
       let rec explore pats e = match e.exp_desc with
         | Texp_function (_, c :: [], Total) ->
@@ -134,24 +118,18 @@ and js_of_expression (e:expression) =
                js_of_expression e in
       let names, body = explore [c.c_lhs] c.c_rhs in
       Format.sprintf
-        "function (%s) {
-            return %s;
-        }" names body
+        "@[function (%s) {@,@[<v 4>@,return %s;@,@]@,}@]" names body
   | Texp_function (_, _, _) -> out_of_scope "powered-up functions"
   | Texp_apply (f, exp_l) ->
      let sl = exp_l
           |> List.map (fun (_, eo, _) -> match eo with None -> out_of_scope "optional apply arguments" | Some ei -> js_of_expression ei)
           |> String.concat ", " in
      let se = js_of_expression f in
-     Format.sprintf "%s(%s)" se sl
+     Format.sprintf "@[<v 0>%s(%s)@]" se sl
   | Texp_match (exp, l, [], Total) ->
      let se = js_of_expression exp in
-     let sb = List.fold_left (fun acc x -> acc ^ js_of_branch x se ^ ";") "" l in
-    Format.sprintf "(function () {
-        switch (%s.tag) {
-            %s
-        }
-     })()" se sb
+     let sb = List.fold_left (fun acc x -> acc ^ js_of_branch x se) "" l in
+    Format.sprintf "@[<v 0>(function () {@,@[<v 4>@,switch (%s.type) {@,@[<v 4>@,%s@,@]@,}@]@,})()@]" se sb
   | Texp_match (_, _, _, Partial) -> out_of_scope "partial matching"
   | Texp_match (_,_,_,_) -> out_of_scope "matching with exception branches"
   | Texp_try (_, _) -> out_of_scope "exceptions"
@@ -160,13 +138,13 @@ and js_of_expression (e:expression) =
   | Texp_construct (loc, cd, el) -> (*TODO: Modifs*)
         let value = js_of_longident loc in
         if el = [] then
-            if value = "true" || value = "false" then value else Format.sprintf {|{tag: "%s"}|} value
+            if value = "true" || value = "false" then value else Format.sprintf "{type: \"%s\"}" value
         else let rec expand_constructor_list fields exprs = match fields, exprs with
           | [], [] -> []
           | [], x :: xs | x :: xs , [] -> failwith "argument lists should have the same length."
-          | x :: xs, y :: ys -> (if y = "" then Format.sprintf {|%s|} x else Format.sprintf {|%s: %s|} x y) :: expand_constructor_list xs ys
+          | x :: xs, y :: ys -> (if y = "" then Format.sprintf "%s" x else Format.sprintf "%s: %s" x y) :: expand_constructor_list xs ys
         in let names, typ = Hashtbl.find type_tbl value
-        in Format.sprintf {|{tag: "%s", %s}|} value (show_list ", " (expand_constructor_list names (List.map js_of_expression el)))
+        in Format.sprintf "{type: \"%s\", %s}" value (show_list ", " (expand_constructor_list names (List.map js_of_expression el)))
   | Texp_variant (_,_) -> out_of_scope "polymorphic variant"
   | Texp_record (_, _) -> failwith "not implemented yet"
   | Texp_field (_,_,_) -> failwith "not implemented yet"
@@ -174,19 +152,10 @@ and js_of_expression (e:expression) =
   | Texp_array (exp_l) ->
       "["  ^ show_list_f js_of_expression ", " exp_l ^ "]"
   | Texp_ifthenelse (e1, e2, None) -> Format.sprintf
-      "(function () {
-          if (%s) {
-              return  %s;
-          }
-      })()" (js_of_expression e1) (js_of_expression e2)
+      "@[<v 0>(function () {@,@[<v 4>@,if (%s) {@,@[<v 4>@,return  %s;@]@,}@]@,})()@]" (js_of_expression e1) (js_of_expression e2)
   | Texp_ifthenelse (e1, e2, Some e3) -> Format.sprintf
-      "(function () {
-          if (%s) {
-              return %s;
-          } else {
-              return %s;
-          }
-      })()" (js_of_expression e1) (js_of_expression e2) (js_of_expression e3)
+     "@[<v 0>(function () {@,@[<v 4>@,if (%s) {@,@[<v 4>@,return  %s;@]@,} else {@,@[<v 4>@,return  %s;@]@,}@]@]@,})()@]"
+      (js_of_expression e1) (js_of_expression e2) (js_of_expression e3)
   | Texp_sequence (_, _) -> unsupported "sequences"
   | Texp_while (_, _) -> unsupported "while loops"
   | Texp_for (_,_,_,_,_,_) -> unsupported "for loops"
@@ -237,7 +206,7 @@ and js_of_structure_item s = match s.str_desc with
                            Hashtbl.add type_tbl (Ident.name y.cd_id) ((extract_attrs y.cd_attributes), Ident.name x.typ_id); explore_cstrs ys;
             in explore_cstrs cdl
         | _ -> unsupported "records") in
-    explore_type tl; print_tbl (); ""
+    explore_type tl; ""
   | Tstr_primitive _    -> out_of_scope "primitive functions"
   | Tstr_typext _       -> out_of_scope "type extensions"
   | Tstr_exception _    -> out_of_scope "exceptions"
diff --git a/generator/main.ml b/generator/main.ml
index ce83923f7a04e18bf662478b800f2d58ea8c3c7f..42a528278760ee0460525c0cdda7aa4f79c75ced 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -5,11 +5,7 @@ open Parse_type
 (*#########################################################################*)
 
 let debug = ref false
-
-let myflag = ref false
-
 let ppf = Format.std_formatter
-
 let outputfile = ref None
 
 (* err_formatter *)
@@ -18,21 +14,21 @@ let outputfile = ref None
 (*#########################################################################*)
 
 let _ =
-
+  
    (* disable loading of stdlib *)
-   Clflags.nopervasives := true;
+   Clflags.nopervasives := false;
 
    (*---------------------------------------------------*)
    (* parsing of command line *)
 
    let files = ref [] in
    Arg.parse
-     [ ("-I", Arg.String (fun i -> Clflags.include_dirs := i::!Clflags.include_dirs), 
+     [ ("-I", Arg.String (fun i -> Clflags.include_dirs := i :: !Clflags.include_dirs), 
                       "includes a directory where to look for interface files");
-       ("-myflag", Arg.Set myflag, "example of a flag"); 
        ("-o", Arg.String (fun s -> outputfile := Some s), "set the output file name");
-       ("-debug", Arg.Set debug, "trace the various steps") ]
-     (fun f -> files := f::!files)
+       ("-debug", Arg.Set debug, "trace the various steps")
+     ]
+     (fun f -> files := f :: !files)
      ("usage: [-I dir] [..other options..] file.ml");
 
    if List.length !files <> 1 then
@@ -44,13 +40,13 @@ let _ =
    let dirname = Filename.dirname sourcefile in
    let outputfile : string =
      match !outputfile with
-     | None -> Filename.concat dirname ((String.capitalize basename) ^ ".js")
+     | None -> Filename.concat dirname (basename ^ ".js")
      | Some f -> f
    in
 
    (*---------------------------------------------------*)
    (* "reading and typing source file" *)
-   let (opt,inputfile) = process_implementation_file ppf sourcefile in
+   let (opt, inputfile) = process_implementation_file ppf sourcefile in
    let ((parsetree1 : Parsetree.structure), typedtree1) =
       match opt with
       | None -> failwith "Could not read and typecheck input file"
@@ -58,16 +54,3 @@ let _ =
       in
 
    file_put_contents outputfile (Js_of_ast.js_of_structure typedtree1) 
-
-   (* file_put_contents ("_parsed_file.ml") (Print_past.string_of_structure parsetree1);  *)
-
-   (*---------------------------------------------------*)
-   (* typing normalized code
-   let (typedtree2, _ : Typedtree.structure * Typedtree.module_coercion) = 
-      match typecheck_implementation_file ppf sourcefile parsetree2 with
-      | None -> failwith "Could not typecheck the normalized source code\nCheck out the file output/_normalized.ml." 
-      | Some typedtree2 -> typedtree2
-      in
-   file_put_contents (debugdirBase ^ "_normalized_typed.ml") (Print_tast.string_of_structure typedtree2); 
-   ignore (typedtree2);
-   *)
diff --git a/generator/parse_type.ml b/generator/parse_type.ml
index f4491fed172bbcd784366219388fd83b08f89310..b00a50c3bfe48b13def67e6f232d7799013156fb 100644
--- a/generator/parse_type.ml
+++ b/generator/parse_type.ml
@@ -18,7 +18,7 @@ open Typedtree
 
 let init_path () =
   load_path :=
-    "" :: List.rev (Config.standard_library :: !Clflags.include_dirs);
+    "stdlib_ml" :: List.rev (Config.standard_library :: !Clflags.include_dirs);
   Env.reset_cache ()
 
 (** Return the initial environment in which compilation proceeds. *)
@@ -27,7 +27,7 @@ let initial_env () =
   try
     if !Clflags.nopervasives
     then Env.open_pers_signature "Stdlib" Env.initial_unsafe_string
-    else Env.open_pers_signature "Pervasives" Env.initial_unsafe_string
+    else Env.open_pers_signature "Stdlib" Env.initial_unsafe_string
   with Not_found ->
     fatal_error "cannot open pervasives"
 
diff --git a/generator/print_tast.ml b/generator/print_tast.ml
deleted file mode 100644
index 5b3f3925573c01d07ac4fe65df95a2387eddca43..0000000000000000000000000000000000000000
--- a/generator/print_tast.ml
+++ /dev/null
@@ -1,318 +0,0 @@
-open Misc
-open Asttypes
-open Types
-open Typedtree
-open Mytools
-open Longident
-open Format
-open Print_type
-
-(** Printing facility for typed abstract syntax trees produced by the 
-    type-checker*)
-
-(*#########################################################################*)
-(* ** Printing of base values *)
-
-let string_of_ident s = 
-   Ident.name s
-
-let string_of_lident idt =
-   let names = Longident.flatten idt in
-   String.concat "." names
-
-let string_of_constant = function
-  | Const_int n -> string_of_int n
-  | Const_char c -> String.make 1 c
-  | Const_string (s, _) -> s
-  | Const_float f -> f
-  | Const_int32 _ -> unsupported "int32 type"
-  | Const_int64 _ -> unsupported "int64 type"
-  | Const_nativeint _ -> unsupported "native int type"
-
-let string_of_recflag = function
-  | Nonrecursive -> ""
-  | Recursive -> " rec" 
-
-
-
-(*#########################################################################*)
-(* ** Printing of items *)
-
-let string_of_typed_var s t =
-   sprintf "(%s : %s)" s (string_of_type_exp t)
-
-let string_of_path p = 
-   Path.name p
-
-let show_string s = 
-  s
-
-(*#########################################################################*)
-(* ** Printing of patterns *)
-
-let string_of_pattern par p =
-   let rec aux par p =
-     match p.pat_desc with
-     | Tpat_any -> "_"
-     | Tpat_var (id,_) -> string_of_typed_var (string_of_ident id) p.pat_type
-     | Tpat_alias (p, ak, _) -> unsupported "alias patterns"
-       (* let sp = aux false p in
-         begin match ak with 
-         | TPat_alias id -> show_par par (sprintf "%s as %s" (string_of_typed_var (string_of_ident id) p.pat_type) sp) 
-         | TPat_constraint _ -> sp
-         | TPat_type pp -> sp (* ignore type *)
-         end  *)
-     | Tpat_constant c -> 
-         sprintf "%s" (string_of_constant c)
-     | Tpat_tuple l -> 
-         show_par true (sprintf "%s" (show_list (aux false) "," l))
-     | Tpat_construct (p,cd,ps) -> unsupported "construct patterns" 
-        (*
-         let c = string_of_path p in
-         if ps = []
-            then c
-         else if List.length ps = 1 
-            then show_par par (c ^ " " ^ aux true (List.hd ps))
-         else
-            show_par par (sprintf "%s (%s)" c (show_list (aux false) "," ps)) *)
-     | Tpat_or (p1,p2,_) -> 
-         show_par par (sprintf "%s | %s" (aux false p1) (aux false p2))
-     | Tpat_lazy p1 -> 
-        show_par par (sprintf "lazy %s" (aux true p1))
-     | Tpat_variant (_,_,_) -> unsupported "variant patterns"
-     | Tpat_record _ -> unsupported "record patterns"
-     | Tpat_array pats -> unsupported "array patterns"
-     in
-  aux false p
-
-let string_of_let_pattern par fvs p =
-   let typ = p.pat_type in
-   let styp = string_of_type_sch fvs typ in
-   sprintf "%s : %s" (string_of_pattern par p) styp
-   (* 
-   match p.pat_desc with
-   | Tpat_var id -> 
-      let typ = p.pat_type in
-      sprintf "%s : %s" (string_of_ident id) (string_of_type_sch fvs typ)
-   | _ -> unsupported "let-pattern not reduced to a variable"
-   *)  
-
-(*#########################################################################*)
-(* ** Printing of expression *)
-
-let rec string_of_expression par e =
-   let aux ?par e =
-      string_of_expression (bool_of_option par) e in
-   let aux_pat ?par e =
-      string_of_pattern (bool_of_option par) e in
-   let string_of_branch (p,e) =
-      Format.sprintf "@[@[%s@] ->@ @[%s@]@]" (aux_pat p) (aux e) in
-   (*let typ = e.exp_type in*)
-   match e.exp_desc with
-   | Texp_ident (p,loc,vd) -> string_of_path p (*  string_of_typed_var (string_of_path p) vd.val_type*)
-   | Texp_constant c -> string_of_constant c
-   | Texp_let (rf, l, e) ->
-       let show_pe (p,e) =
-          let sp = (string_of_let_pattern false fvs p) in
-          let se = aux e in
-          Format.sprintf "%s =@ @[%s@]" sp se in
-       let sl = show_list show_pe " and " l in
-       let se = aux e in
-       Format.sprintf "@[let%s %s in@ @[%s@]@]" (string_of_recflag rf) sl se 
-   | Texp_function (_,c1::[], pa) ->
-       let p1 = c1.c_lhs in
-       let e1 = c1.c_rhs in
-       let rec explore pats e =
-          match e.exp_desc with 
-          | Texp_function (_,(p1,e1)::[], pa) ->
-             explore (p1::pats) e1
-          | _ -> List.rev pats, e
-          in
-       let pats,body = explore [] e in
-       let sp = show_list aux_pat " " pats in
-       let sb = aux ~par:false body in
-       let s = Format.sprintf "@[fun @[%s@] ->@ @[%s@]@]" sp sb in
-      show_par par s
-   | Texp_function (_,l, pa) ->  
-       Format.sprintf "@[function %s@]" (show_listp string_of_branch "\n  | " l)
-   | Texp_apply (e, l) -> (* todo: afficher les infixes correctement *)
-      let l = List.map (fun (lab,eo,opt) -> match eo with None -> unsupported "optional apply arguments" | Some ei -> ei) l in
-      let se = aux ~par:true e in
-      let show_arg ei =
-         let s_ei = aux ~par:false ei in
-         let t_ei = string_of_type_exp ei.exp_type in
-         sprintf "(%s : %s)" s_ei t_ei in
-      let sl = show_list show_arg " " l in
-      let s = sprintf "%s %s" se sl in
-      show_par par s
-   | Texp_match (e, l, pa) -> 
-       let se = aux e in
-       let s = Format.sprintf "@[match@ @[%s@] with@ @[%s@]@]" 
-          se (show_list string_of_branch " | " l) in
-       show_par par s
-   | Texp_try (e,l) -> unsupported "exceptions"
-   | Texp_tuple l -> 
-       show_par true (show_list aux ", " l)
-   | Texp_construct (p, cd, es) -> 
-         let c = string_of_path p in
-         if es = []
-            then c
-         else if List.length es = 1 
-            then show_par par (c ^ " " ^ aux ~par:true (List.hd es))
-         else
-            show_par par (sprintf "%s (%s)" c (show_list aux "," es))
-   | Texp_variant (l,eo) -> unsupported "variants"
-   | Texp_record (l,Some eo) -> unsupported "record-with"
-   | Texp_record (l,None) ->        
-       let print_item (p,li,ei) = 
-          Format.sprintf "%s = %s" (string_of_path p) (aux ei) in
-       let s = Format.sprintf "@[{%s}@]" (show_list print_item "; " l) in
-       show_par par s
-   | Texp_field (e,p,i) -> 
-       let s = Format.sprintf "@[%s.%s@]" (aux e) (string_of_path p) in
-       show_par par s
-   | Texp_setfield (e,p,i,e2) -> 
-       let s = Format.sprintf "@[%s.%s <- %s@]" (aux e) (string_of_path p) (aux e2) in
-       show_par par s
-   | Texp_array l -> unsupported "array expression" (* Texp_array (List.map aux l)*)
-   | Texp_ifthenelse (e1, e2, None) ->
-       let s = Format.sprintf "@[if %s@ then %s@]" (aux e1) (aux e2) in
-       show_par par s
-   | Texp_ifthenelse (e1, e2, Some e3) ->
-       let s = Format.sprintf "@[if %s@ then %s@ else %s@]" (aux e1) (aux e2) (aux e3) in
-       show_par par s
-   | Texp_when (e1,e2) ->  (*todo:better printing so that compiles *)
-       Format.sprintf "<< when %s >> %s" (aux e1) (aux e2) 
-   | Texp_sequence (e1,e2) -> 
-       let s = Format.sprintf "@[%s@ ; %s@]" (aux e1) (aux e2) in
-       show_par par s
-   | Texp_while (e1,e2) -> 
-       let s = Format.sprintf "@[while %s@ do %s@ done@]" (aux e1) (aux e2) in
-       show_par par s
-   | Texp_for (i,e1,e2,d,e3) -> 
-       let s = Format.sprintf "@[for %s = %s to %s do@ %s@ done@]" (Ident.name i) (aux e1) (aux e2) (aux e3) in
-       show_par par s
-   | Texp_send (_,_,_) -> unsupported "send expression"
-   | Texp_new _ -> unsupported "new expression"
-   | Texp_instvar (_,_) -> unsupported "inst-var expression"
-   | Texp_setinstvar (_,_,_) -> unsupported "set-inst-var expression"
-   | Texp_override _ -> unsupported "Pexp_override expression"
-   | Texp_letmodule (_,_,_) -> unsupported "let-module expression"
-   | Texp_assert e -> 
-       let s = Format.sprintf "@[assert %s@]" (aux e) in
-       show_par par s
-   | Texp_assertfalse -> 
-       show_par par "assert false"
-   | Texp_lazy e -> 
-       let s = Format.sprintf "@[lazy %s@]" (aux e) in
-       show_par par s
-   | Texp_object _ -> unsupported "objects"
-   | Texp_poly (_,_) -> unsupported "poly"
-   | Texp_newtype (_,_) -> unsupported "newtype"
-   | Texp_pack _ -> unsupported "pack"
-   | Texp_open  (_,_) -> unsupported "open"
-   | Texp_constraint (e,_,_) -> aux e
-
-
-(*#########################################################################*)
-(* ** Printing of type declarations *)
-
-(* TODO
-
-let show_core_type par t =
-  let rec aux par t =
-     match t.ctyp_desc with
-     | Ttyp_any -> "_"
-     | Ttyp_var x -> "'"^x
-     | Ttyp_arrow (_,t1,t2) -> show_par par (sprintf "%s -> %s" (aux false t1) (aux false t2))
-     | Ttyp_tuple ts -> show_par true (show_list (aux true) " * " ts)
-     | Ttyp_constr (p,ts) ->
-         let args = match ts with
-           | [] -> ""
-           | [x] -> sprintf "%s" (aux true x)
-           | l -> show_par true (show_list (aux false) ", " l)
-           in
-         sprintf "%s %s" args (string_of_path p) 
-     | Ttyp_object _ -> unsupported "object types"
-     | Ttyp_class _ -> unsupported "class types"
-     | Ttyp_alias _ -> unsupported "alias types"
-     | Ttyp_variant  _ -> unsupported "variant types"
-     | Ttyp_poly _ -> unsupported "poly types"
-     | Ttyp_package _ -> unsupported "package types"
-     in
-  aux par t
-
-
-let show_type_decl (name,decl) =
-   let show_type t = 
-     show_core_type false t in
-   let params = 
-      match decl.typ_params with
-      | [] -> ""
-      | [a] -> sprintf "'%s " a
-      | l -> show_par true (show_list show_string ", " l) ^ " "
-      in
-   let header = sprintf " %s%s" params (string_of_ident name) in
-   match decl.typ_kind with 
-   | Ttype_abstract -> 
-       begin match decl.typ_manifest with
-       | None -> header
-       | Some def -> sprintf "%s = %s" header (show_type def)
-       end 
-   | Ttype_record _ (* (string * mutable_flag * core_type * Location.t) list *) ->
-        unsupported "records type def (todo)"
-   | Ttype_variant branches ->
-       let show_branch (constr, args, _) =
-          match args with
-          | [] -> constr
-          | [a] -> sprintf "%s of %s" constr (show_type a)
-          | l -> sprintf "%s of %s" constr (show_par true (show_list show_type "* " l))
-          in
-       header ^ " = " ^ show_list show_branch " | " branches
-
-let is_simple_type_decl (name,decl) =
-  match decl.typ_kind with
-    Ttype_record _ -> true
-  | Ttype_abstract -> true
-  | _ -> false
-
-*)
-
-(*#########################################################################*)
-(* ** Printing of modules and top-level phrases *)
-
-let rec string_of_module m =
-   match m.mod_desc with
-   | Tmod_ident p -> string_of_path p
-   | Tmod_structure s -> sprintf "struct\n%s\nend\n" (string_of_structure s) 
-   | Tmod_functor (id,mt,me) -> sprintf "%s : _ ==>%s\n" (string_of_ident id) (string_of_module me) 
-   | Tmod_apply (me1,me2,mc) -> sprintf "%s %s" (string_of_module me1) (string_of_module me2)
-   | Tmod_constraint (me,_,mt,mc) -> sprintf "(%s : _)" (string_of_module me)
-   | Tmod_unpack (_,_) -> unsupported "unpack"
-
-and string_of_structure (s:structure) =
-  show_list string_of_structure_item lin2 s.str_items
-
-and string_of_structure_item (si:structure_item) =
-   Printtyp.reset();
-   match si.str_desc with
-   | Tstr_eval e -> sprintf "let _ = %s" (string_of_expression false e)
-   | Tstr_value (r,fvs,l) -> 
-       let show_pe (p,e) =
-          let sp = string_of_let_pattern false fvs p in
-          let se = string_of_expression false e in
-          Format.sprintf "%s =@ @[%s@]" sp se in
-       let sl = show_list show_pe " and " l in
-       Format.sprintf "@[let%s %s@]" (string_of_recflag r) sl 
-      (* Format.sprintf "@[let%s %s =@ @[<2>%s@]@]" *)
-   | Tstr_primitive (id,v) -> sprintf "val %s : _" (string_of_ident id)
-   | Tstr_type l -> sprintf "type _ = _"
-   | Tstr_exception (id,e) -> sprintf "exception %s = _" (string_of_ident id)
-   | Tstr_exn_rebind (id,p) -> unsupported "exception-rebind"
-   | Tstr_module (id,m) -> Format.sprintf "@[module %s =@ @[<2>%s] @]" (string_of_ident id) (string_of_module m)
-   | Tstr_recmodule _ -> unsupported "recursive modules"
-   | Tstr_modtype (id,mt) -> sprintf "module type %s = _" (string_of_ident id)
-   | Tstr_open p -> sprintf "open %s = _" (string_of_path p)
-   | Tstr_class _ -> unsupported "objects"
-   | Tstr_class_type _ -> unsupported "objects"
-   | Tstr_include (m,ids) -> sprintf "include %s" (string_of_module m)
diff --git a/generator/run.debug.sh b/generator/run.debug.sh
new file mode 100755
index 0000000000000000000000000000000000000000..51dec5deca95b3c5ead2715f57e3d755c5af53a4
--- /dev/null
+++ b/generator/run.debug.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+cat stdlib_js/stdlib.debug.js >> _____tmp.js
+cat $1 >> _____tmp.js
+
+node  _____tmp.js
+
+rm  _____tmp.js
diff --git a/generator/run.sh b/generator/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..620e6fd10296863355f837efb6150b6fb7e2699e
--- /dev/null
+++ b/generator/run.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+cat stdlib_js/stdlib.js >> _____tmp.js
+cat $1 >> _____tmp.js
+
+node  _____tmp.js
+
+rm  _____tmp.js
diff --git a/generator/stdlib.mli b/generator/stdlib.mli
deleted file mode 100644
index 23a4eebf3fc051b3426d084a9fad83f673e17005..0000000000000000000000000000000000000000
--- a/generator/stdlib.mli
+++ /dev/null
@@ -1,14 +0,0 @@
-val ( + ) : int -> int -> int
-val ( - ) : int -> int -> int
-val ( * ) : int -> int -> int
-val ( / ) : int -> int -> int
-
-val ( +. ) : float -> float -> float
-val ( -. ) : float -> float -> float
-val ( *. ) : float -> float -> float
-val ( /. ) : float -> float -> float
-
-val ( < ) : 'a -> 'a -> bool
-val ( > ) : 'a -> 'a -> bool
-
-val ( = ) : 'a -> 'a -> unit
diff --git a/generator/stdlib_js/stdlib.debug.js b/generator/stdlib_js/stdlib.debug.js
new file mode 100644
index 0000000000000000000000000000000000000000..aef5f2f8cab6e98b9b8a30a1d7f488492c3b6119
--- /dev/null
+++ b/generator/stdlib_js/stdlib.debug.js
@@ -0,0 +1,49 @@
+
+var add = function (a, b) { return "(" + a + " + " + b + ")" }
+var sub = function (a, b) { return "(" + a + " - " + b + ")" }
+var mul = function (a, b) { return "(" + a + " * " + b + ")" }
+var div = function (a, b) { return "(" + a + " / " + b + ")" }
+
+var eq = function (a, b) { return a === b }
+var le = function (a, b) { return a < b }
+var ge = function (a, b) { return a > b }
+
+var leq = function (a, b) { return a <= b }
+var geq = function (a, b) { return a >= b }
+
+var print = function (x) { console.log(x) }
+
+var to_string = function (x) { return String(x) }
+
+var parse = function (source) {
+    var ast = require('esprima').parse(source).body[0].expression;
+
+    function transform (tree) {
+        if (tree === undefined) {
+        } else {
+            switch (tree.operator) {
+                case '+':
+                    tree.type = "Add"; tree.operator = undefined; break;
+                case '-':
+                    tree.type = "Sub"; tree.operator = undefined; break;
+                case "*":
+                    tree.type = "Mul"; tree.operator = undefined; break;
+                case "/":
+                    tree.type = "Div"; tree.operator = undefined; break;
+                default: break;
+            }
+
+            switch (tree.type) {
+                case "Literal":
+                    tree.type = "Const"; break;
+                default: break;
+            }
+
+            if (tree.left !== undefined) tree.left = transform(tree.left);
+            if (tree.right !== undefined) tree.right = transform(tree.right);
+            return tree;
+        }
+    }
+
+    return transform(ast);
+}
diff --git a/generator/stdlib_js/stdlib.js b/generator/stdlib_js/stdlib.js
new file mode 100644
index 0000000000000000000000000000000000000000..adbab39e9e5756d37808a9ee3e1325c1ce954c54
--- /dev/null
+++ b/generator/stdlib_js/stdlib.js
@@ -0,0 +1,48 @@
+var add = function (a, b) { return a + b }
+var sub = function (a, b) { return a - b }
+var mul = function (a, b) { return a * b }
+var div = function (a, b) { return a / b }
+
+var eq = function (a, b) { return a === b }
+var le = function (a, b) { return a < b }
+var ge = function (a, b) { return a > b }
+
+var leq = function (a, b) { return a <= b }
+var geq = function (a, b) { return a >= b }
+
+var print = function (x) { console.log(x) }
+
+var to_string = function (x) { return String(x) }
+
+var parse = function (source) {
+    var ast = require('esprima').parse(source).body[0].expression;
+
+    function transform (tree) {
+        if (tree === undefined) {
+        } else {
+            switch (tree.operator) {
+                case '+':
+                    tree.type = "Add"; tree.operator = undefined; break;
+                case '-':
+                    tree.type = "Sub"; tree.operator = undefined; break;
+                case "*":
+                    tree.type = "Mul"; tree.operator = undefined; break;
+                case "/":
+                    tree.type = "Div"; tree.operator = undefined; break;
+                default: break;
+            }
+
+            switch (tree.type) {
+                case "Literal":
+                    tree.type = "Const"; break;
+                default: break;
+            }
+
+            if (tree.left !== undefined) tree.left = transform(tree.left);
+            if (tree.right !== undefined) tree.right = transform(tree.right);
+            return tree;
+        }
+    }
+
+    return transform(ast);
+}
diff --git a/generator/stdlib_ml/stdlib.cmi b/generator/stdlib_ml/stdlib.cmi
new file mode 100644
index 0000000000000000000000000000000000000000..2fea646fdf08c348060814fae85299c395212916
Binary files /dev/null and b/generator/stdlib_ml/stdlib.cmi differ
diff --git a/generator/stdlib_ml/stdlib.mli b/generator/stdlib_ml/stdlib.mli
new file mode 100644
index 0000000000000000000000000000000000000000..ab7efeca1340bb672ec00206ec1fa8f2242d8a63
--- /dev/null
+++ b/generator/stdlib_ml/stdlib.mli
@@ -0,0 +1,16 @@
+val add : 'a -> 'a -> 'a
+val sub : 'a -> 'a -> 'a
+val mul : 'a -> 'a -> 'a
+val div : 'a -> 'a -> 'a
+
+val eq : 'a -> 'a -> bool
+val le : 'a -> 'a -> bool
+val ge : 'a -> 'a -> bool
+
+val leq : 'a -> 'a -> bool
+val geq : 'a -> 'a -> bool
+
+val print : 'a -> unit
+
+val to_string : 'a -> string
+val parse : 'a -> 'b
diff --git a/generator/tests/calc.cmi b/generator/tests/calc.cmi
new file mode 100644
index 0000000000000000000000000000000000000000..b5d163858a1c5a56e6c5d588b28221617988266b
Binary files /dev/null and b/generator/tests/calc.cmi differ
diff --git a/generator/tests/calc.ml b/generator/tests/calc.ml
new file mode 100644
index 0000000000000000000000000000000000000000..be11a5da53938c9e1f0982ebf4021f572e101ab4
--- /dev/null
+++ b/generator/tests/calc.ml
@@ -0,0 +1,24 @@
+type expr =
+  | Const [@f value] of int
+  | Add [@f left, right] of expr * expr
+  | Sub [@f left, right] of expr * expr
+  | Mul [@f left, right] of expr * expr
+  | Div [@f left, right] of expr * expr
+
+let rec eval_ expr = match expr with
+  | Const n -> n
+  | Add (ls, rs) -> add (eval_ ls) (eval_ rs)
+  | Sub (ls, rs) -> sub (eval_ ls) (eval_ rs)
+  | Mul (ls, rs) -> mul (eval_ ls) (eval_ rs)
+  | Div (ls, rs) -> div (eval_ ls) (eval_ rs)
+
+let rec print_expr expr = match expr with
+  | Const n -> to_string n
+  | Add (ls, rs) -> (add (add  (add (add "(" (print_expr ls)) ")") " + ") (print_expr rs))
+  | Sub (ls, rs) -> (add (add  (add (add "(" (print_expr ls)) ")") " - ") (print_expr rs))
+  | Mul (ls, rs) -> (add (add  (add (add "(" (print_expr ls)) ")") " * ") (print_expr rs))
+  | Div (ls, rs) -> (add (add  (add (add "(" (print_expr ls)) ")") " / ") (print_expr rs))
+
+let f =
+    let source = parse "((1972 / 29) / 2) + 8" in
+    print (add (add (print_expr source) " = ") (to_string (eval_ source)))
diff --git a/generator/tests/js/calc.js b/generator/tests/js/calc.js
new file mode 100644
index 0000000000000000000000000000000000000000..f525709f0ac683055543b5b8072c85362d67d900
--- /dev/null
+++ b/generator/tests/js/calc.js
@@ -0,0 +1,64 @@
+var eval_ = function (expr) {
+
+    return (function () {
+
+    switch (expr.type) {
+    
+        case "Const": var n = expr.value;
+
+                  return n;
+  case "Add": var ls = expr.left, rs = expr.right;
+
+                return add(eval_(ls), eval_(rs));
+  case "Sub": var ls = expr.left, rs = expr.right;
+
+                return sub(eval_(ls), eval_(rs));
+  case "Mul": var ls = expr.left, rs = expr.right;
+
+                return mul(eval_(ls), eval_(rs));
+  case "Div": var ls = expr.left, rs = expr.right;
+
+                return div(eval_(ls), eval_(rs));
+  
+        
+    }
+})();
+    };
+
+
+var print_expr = function (expr) {
+
+    return (function () {
+
+    switch (expr.type) {
+    
+        case "Const": var n = expr.value;
+
+                  return to_string(n);
+  case "Add": var ls = expr.left, rs = expr.right;
+
+                return add(add(add(add("(", print_expr(ls)), ")"), " + "), print_expr(rs));
+  case "Sub": var ls = expr.left, rs = expr.right;
+
+                return add(add(add(add("(", print_expr(ls)), ")"), " - "), print_expr(rs));
+  case "Mul": var ls = expr.left, rs = expr.right;
+
+                return add(add(add(add("(", print_expr(ls)), ")"), " * "), print_expr(rs));
+  case "Div": var ls = expr.left, rs = expr.right;
+
+                return add(add(add(add("(", print_expr(ls)), ")"), " / "), print_expr(rs));
+  
+        
+    }
+})();
+    };
+
+
+var f = (function () {
+
+    var source = parse("((1972 / 29) / 2) + 8");
+
+    
+    return print(add(add(print_expr(source), " = "), to_string(eval_(source))));
+    
+})();
diff --git a/generator/tests/js/let.js b/generator/tests/js/let.js
new file mode 100644
index 0000000000000000000000000000000000000000..89342f1ab3abd42cabbbed7affa0080889b753ff
--- /dev/null
+++ b/generator/tests/js/let.js
@@ -0,0 +1,54 @@
+(function () {
+
+    var abr = 1;
+
+var bli = 4;
+
+    
+    return (function () {
+
+    if (true) {
+    
+        return  abr;
+    } else {
+    
+        return  bli;
+    }
+})();
+    
+})()
+
+var app = function (x) {
+                  return x;
+                  };
+
+
+var app2 = function (x) {
+                  return x;
+                  };
+
+
+
+
+var affiche = function (x) {
+
+    return (function () {
+
+    switch (x.type) {
+    
+        case "As": 
+               return "As";
+  case "Petite": var n = x.petite;
+
+                   return "Petite";
+  
+        
+    }
+})();
+    };
+
+
+var pet = {type: "Petite", petite: 5};
+
+
+var cinq = 5;
diff --git a/generator/tests/js/mylist.js b/generator/tests/js/mylist.js
new file mode 100644
index 0000000000000000000000000000000000000000..1feb8a096a69d5ee6c3fe492c27ea12de244c4d6
--- /dev/null
+++ b/generator/tests/js/mylist.js
@@ -0,0 +1,190 @@
+var incr = function (i) {
+                  return add(i, 1);
+                  };
+
+
+
+
+var head = function (d, l) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return d;
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return x;
+  
+        
+    }
+})();
+    };
+
+
+var tail = function (d, l) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return d;
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return xs;
+  
+        
+    }
+})();
+    };
+
+
+var init = function (l) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return {type: "Nil"};
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return xs;
+  
+        
+    }
+})();
+    };
+
+
+var last = function (l) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return {type: "Nil"};
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return (function () {
+
+    switch (xs.type) {
+    
+        case "Nil": 
+                return x;
+  default: 
+             return last(xs);
+  
+        
+    }
+})();
+  
+        
+    }
+})();
+    };
+
+
+var fold_left = function (f, acc, l) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return acc;
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return fold_left(f, f(acc, x), xs);
+  
+        
+    }
+})();
+    };
+
+
+var fold_right = function (f, l, acc) {
+
+    return (function () {
+
+    switch (l.type) {
+    
+        case "Nil": 
+                return acc;
+  case "Cons": var x = l.hd, xs = l.tl;
+
+                 return f(fold_right(f, xs, acc), x);
+  
+        
+    }
+})();
+    };
+
+
+var rev_map = function (f, l) {
+
+    return fold_left(function (acc, x) {
+                       return {type: "Cons", hd: f(x), tl: acc};
+                       }, {type: "Nil"}, l);
+    };
+
+
+var map = function (f, l) {
+
+    return fold_right(function (acc, x) {
+                       return {type: "Cons", hd: f(x), tl: acc};
+                       }, l, {type: "Nil"});
+    };
+
+
+var length = function (l) {
+
+    return fold_left(function (acc, x) {
+                       return incr(acc);
+                       }, 0, l);
+    };
+
+
+var range = function (i, j, acc) {
+
+    return (function () {
+
+    if (le(i, j)) {
+    
+        return  range(incr(i), j, {type: "Cons", hd: i, tl: acc});
+    } else {
+    
+        return  acc;
+    }
+})();
+    };
+
+
+var list0 = {type: "Nil"};
+
+
+var list1 = range(0, 1, {type: "Nil"});
+
+
+var list2 = range(1, 5, {type: "Nil"});
+
+
+var sqr = function (x) {
+                  return mul(x, x);
+                  };
+
+
+length(list0)
+
+length(list1)
+
+length(list2)
+
+map(sqr, list0)
+
+map(sqr, list1)
+
+map(sqr, list2)
\ No newline at end of file
diff --git a/generator/tests/let.cmi b/generator/tests/let.cmi
new file mode 100644
index 0000000000000000000000000000000000000000..2528ba236604509d869848c4d2dcce14a17179f0
Binary files /dev/null and b/generator/tests/let.cmi differ
diff --git a/generator/tests/let.ml b/generator/tests/let.ml
new file mode 100644
index 0000000000000000000000000000000000000000..a27ee5d2d7f85eadf71b4b6b7d9700e530bcee32
--- /dev/null
+++ b/generator/tests/let.ml
@@ -0,0 +1,19 @@
+let abr = 1
+and bli = 4 in
+if true then abr else bli
+
+let app x = x
+
+let app2 = fun x -> x
+
+type carte =
+  | As
+  | Petite [@f petite] of int
+
+
+let affiche x = match x with
+  | As -> "As"
+  | Petite n -> "Petite"
+
+let pet = Petite 5
+let cinq = 5
diff --git a/generator/tests/mylist.cmi b/generator/tests/mylist.cmi
new file mode 100644
index 0000000000000000000000000000000000000000..824d5453d1f41e9ad999413e8f5205b93ae00c04
Binary files /dev/null and b/generator/tests/mylist.cmi differ
diff --git a/generator/tests/mylist.ml b/generator/tests/mylist.ml
new file mode 100644
index 0000000000000000000000000000000000000000..7f1277b551ec72d76cd53aa65de7ad842e668ea6
--- /dev/null
+++ b/generator/tests/mylist.ml
@@ -0,0 +1,53 @@
+let incr i = add i 1
+
+type 'a liste =
+  | Nil
+  | Cons [@f hd, tl] of 'a * 'a liste
+
+let head d l = match l with
+ | Nil -> d
+ | Cons (x, xs) -> x
+
+let tail d l = match l with
+ | Nil -> d
+ | Cons (x, xs) -> xs
+
+let init l = match l with
+ | Nil -> Nil
+ | Cons (x, xs) -> xs
+
+let rec last l = match l with
+ | Nil -> Nil
+ | Cons (x, xs) -> (match xs with
+   | Nil -> x
+   | _   -> last xs)
+
+let rec fold_left f acc l = match l with
+ | Nil -> acc
+ | Cons (x, xs) -> fold_left f (f acc x) xs
+
+let rec fold_right f l acc = match l with
+ | Nil -> acc
+ | Cons (x, xs) -> f (fold_right f xs acc) x
+
+let rev_map f l = fold_left (fun acc x -> Cons(f x, acc)) Nil l
+let map f l = fold_right (fun acc x -> Cons(f x, acc)) l Nil
+
+let length l = fold_left (fun acc x -> incr acc) 0 l
+
+let rec range i j acc = if le i j then range (incr i) j (Cons (i, acc)) else acc
+
+(* Test *)
+
+let list0 = Nil
+let list1 = range 0 1 Nil
+let list2 = range 1 5 Nil
+
+let sqr x = mul x x;;
+
+length list0;;
+length list1;;
+length list2;;
+map sqr list0;;
+map sqr list1;;
+map sqr list2;;
diff --git a/generator/transformations.org b/generator/transformations.org
index 4d5a7e4e2105110b5f109011b690a5fcea9bc522..c4ef84bab4624b2cfdecc899f0f0c995212c3604 100644
--- a/generator/transformations.org
+++ b/generator/transformations.org
@@ -1,37 +1,4 @@
 
-* env_record_create_set_mutable_binding
-
-** Coq
-
-Definition env_record_set_mutable_binding runs S C L x v str : result_void :=
-  if_some (pick_option (env_record_binds S L)) (fun E =>
-    match E with
-    | env_record_decl Ed =>
-      if_some (Heap.read_option Ed x) (fun rm =>
-        let '(mu, v_old) := rm in
-        ifb mutability_is_mutable mu then
-          res_void (env_record_write_decl_env S L x mu v)
-        else out_error_or_void S str native_error_type)
-    | env_record_object l pt =>
-      object_put runs S C l x v str
-    end).
-
-** ML
-
-let env_record_set_mutable_binding C L x v str =
-  if_some (pick_option (env_record_binds L)) (fun E ->
-    match E with
-    | env_record_decl Ed ->
-      if_some (Heap.read_option Ed x) (fun rm ->
-        let '(mu, v_old) := rm in
-        ifb mutability_is_mutable mu then
-          res_void (env_record_write_decl_env S L x mu v)
-        else out_error_or_void S str native_error_type)
-    | env_record_object l pt =>
-      object_put runs S C l x v str
-    end).
-
-
 * build_error
 
 ** Coq
@@ -44,49 +11,53 @@ Definition build_error S vproto vmsg : result :=
 
 ** ML
 
-let build_error vproto vmsg =
+let build_error S vproto vmsg =
   let O = object_new vproto "Error" in
-  let l = object_alloc O in
-  if value_compare vmsg undef then val_loc l
+  let (l, S') := object_alloc S O in
+  if value_compare vmsg undef then out_ter S' l
   else result_not_yet_implemented
 
 ** JS
 
-function build_error(vproto, vmsg) {
+function build_error(S, vproto, vmsg) {
   var O = object_new(vproto, "Error");
-  var l = object_alloc(O);
+  var l = object_alloc(S, O).first;
+  var S2 = object_alloc(S, O).second;
   if (value_compare(vmsg, undef) {
-    return val_loc(l);
+    return out_ter(S2, l);
   } else {
-    return result_not_yet_implemented();
+    return result_not_yet_implemented;
   }
 }
 
 ** JS, with log
 
-function build_error(vproto, vmsg) {
+function build_error(S, vproto, vmsg) {
   log_custom({line: line, type: "enter"});
-  var res = build_error__body(vproto, vmsg);
+  var res = build_error__body(S, vproto, vmsg);
   var ctx = ctx_empty();
   ctx = ctx_push(ctx, "res", res, "result");
   log_custom({line: line, type: "exit", ctx: ctx});
   return res;
 }
 
-function build_error__body(vproto, vmsg) {
+function build_error__body(S, vproto, vmsg) {
   var ctx = ctx_empty();
+  ctx = ctx_push(ctx, "S", S, "state");
   ctx = ctx_push(ctx, "vproto", vproto, "value");
   ctx = ctx_push(ctx, "vmsg", vmsg, "value");
   log(1, ctx, "build_error");
   var O = object_new(vproto, "Error");
   ctx = ctx_push(ctx, "O", O, "object");
   log(2, ctx, "var");
-  var l = object_alloc(O);
+  var l = object_alloc(S, O).first;
+  var S2 = object_alloc(S, O).second;
   ctx = ctx_push(ctx, "l", l, "location");
+  ctx = ctx_push(ctx, "S2", S2, "state");
   log(3, ctx, "var");
-  if (value_compare(vmsg, undef)) {
+  if (value_compare(vmsg, undef) {
     log(4, ctx, "case");
-    return val_loc(l);
+    return out_ter(S2, l);
   } else {
     log(5, ctx, "case");
     return result_not_yet_implemented;
@@ -104,37 +75,39 @@ Definition run_error T S ne : specres T :=
 
 ** ML
 
-let run_error ne =
-  if_object (build_error (prealloc_native_error_proto ne) undef) (fun l ->
-    res_throw l)
+let run_error (*T*) S ne =
+  if_object (build_error S (prealloc_native_error_proto ne) undef) (fun S' l ->
+    result_some (specret_out (out_ter S' (res_throw l))))
 
 ** JS
 
-function run_error(ne) {
-  return if_object(build_error(prealloc_native_error_proto(ne), undef), function (l) {
-    return res_throw(l)});
+function run_error(S, ne) {
+  return if_object(build_error(S, prealloc_native_error_proto(ne), undef), function (S2, l) {
+    return result_some(specret_out(out_ter(S2, (res_throw(l)))))});
 }
 
 
 ** JS, with log
 
-function run_error(ne) {
+function run_error(S, ne) {
   log_custom({line: line, type: "enter"});
-  var res = run_error__body(ne);
+  var res = run_error__body(S, ne);
   var ctx = ctx_empty();
   ctx = ctx_push(ctx, "res", res, "result");
   log_custom({line: line, type: "exit", ctx: ctx});
   return res;
 }
 
-function run_error__body(ne) {
+function run_error__body(S, ne) {
   var ctx = ctx_empty();
+  ctx = ctx_push(ctx, "S", S, "state");
   ctx = ctx_push(ctx, "ne", ne, "error");
   log(1, ctx, "run_error");
-  return if_object(build_error(prealloc_native_error_proto(ne), undef), function (l) {
+  return if_object(build_error(S, prealloc_native_error_proto(ne), undef), function (S2, l) {
+    ctx = ctx_push(ctx, "S2", S2, "state");
     ctx = ctx_push(ctx, "l", l, "location");
     log(2, ctx, "fun");
-    return res_throw(l)});
+    return result_some(specret_out(out_ter(S2, (res_throw(l)))))});
 }
 
 * object_proto_is_prototype_of
@@ -149,82 +122,82 @@ Definition object_proto_is_prototype_of runs S l0 l : result :=
       ifb l' = l0
         then out_ter S true
         else runs_type_object_proto_is_prototype_of runs S l0 l'
-    | _ =>
+    | value_prim _ =>
       impossible_with_heap_because S "[run_object_method] returned a primitive in [object_proto_is_prototype_of_body]."
     end).
 
 ** ML
 
-let object_proto_is_prototype_of l0 l =
-  if_some (run_object_method object_proto_ l) (fun B ->
+let object_proto_is_prototype_of S l0 l =
+  if_some (run_object_method object_proto_ S l) (fun B ->
     match B with
-    | value_prim prim_null -> val_bool false
+    | null -> out_ter S false
     | value_object l' ->
       if loc_compare l' l0
-        then val_bool true
-        else object_proto_is_prototype_of l0 l'
-    | _ ->
-      impossible_with_heap_because "[run_object_method] returned a primitive in [object_proto_is_prototype_of_body]."
+        then out_ter S true
+        else runs_type_object_proto_is_prototype_of S l0 l'
+    | value_prim _ ->
+      impossible_with_heap_because S "[run_object_method] returned a primitive in [object_proto_is_prototype_of_body]."
     end)
 
 ** JS
 
-function object_proto_is_prototype_of(l0, l) {
-  return if_some (run_object_method(object_proto_, l), function (B) {
-    if (B.tag === "value_prim" && B.prim.tag === "prim_null") {
-      return val_bool(false);
-    } else if (B.tag === "value_object") {
-      if (loc_compare (B.l, l0)) {
-        return out_val(true);
+function object_proto_is_prototype_of(S, l0, l) {
+  return if_some (run_object_method(object_proto_, S, l), function (B) {
+    switch (B.tag) {
+    case "null": // "prim"?
+      return out_ter(S, false);
+    case "value_object":
+      var l2 = B.l;
+      if (loc_compare (l2, l0)) {
+        return out_ter(S, true);
       } else {
-    	  return runs_type_object_proto_is_prototype_of(l0, B.l);
+    	  return runs_type_object_proto_is_prototype_of(S, l0, l2);
     	}
-    } else {
-      return impossible_with_heap_because("[run_object_method] returned a primitive in [object_proto_is_prototype_of_body].");
-    }
+    case "value_prim":
+      return impossible_with_heap_because(S, "[run_object_method] returned a primitive in [object_proto_is_prototype_of_body].");
     }
   });
 }
 
 ** JS, with log
 
-function object_proto_is_prototype_of(l0, l) {
+function object_proto_is_prototype_of(S, l0, l) {
+  log_custom({line: line, type: "enter"});
+  var res = object_proto_is_prototype_of__body(S, l0, l);
   var ctx = ctx_empty();
-  ctx = ctx_push(ctx, "l0", l0, "location");
-  ctx = ctx_push(ctx, "l", l, "location");
-  log_custom({line: line, type: "enter", ctx: ctx});
-  var res = object_proto_is_prototype_of__body(l0, l);
-  ctx = ctx_push(ctx, "__res", res, "result");
+  ctx = ctx_push(ctx, "res", res, "result");
   log_custom({line: line, type: "exit", ctx: ctx});
   return res;
 }
 
-function object_proto_is_prototype_of__body(l0, l) {
+function object_proto_is_prototype_of__body(S, l0, l) {
   var ctx = ctx_empty();
+  ctx = ctx_push(ctx, "S", S, "state");
   ctx = ctx_push(ctx, "l0", l0, "location");
   ctx = ctx_push(ctx, "l", l, "location");
   log(1, ctx, "object_proto_is_prototype_of");
-  return if_some (run_object_method(object_proto_, l), function (B) {
+  return if_some (run_object_method(object_proto_, S, l), function (B) {
     ctx = ctx_push(ctx, "B", B);
     log(2, ctx, "fun");
     switch (B.tag) {
     case "null": // "prim"?
       log(3, ctx, "case");
-      return out_val(false);
+      return out_ter(S, false);
     case "value_object":
       var l2 = B.l;
       ctx = ctx_push(ctx, "l2", l2);
       log(3, ctx, "case");
       if (loc_compare (l2, l0)) {
         log(4, ctx, "case");
-        return out_val(true);
+        return out_ter(S, true);
       } else {
         log(5, ctx, "case");
-    	return runs_type_object_proto_is_prototype_of(l0, l2);
+    	return runs_type_object_proto_is_prototype_of(S, l0, l2);
       }
     case "value_prim":
       log(6, ctx, "case");
-      return impossible_with_heap_because("[run_object_method] returned a primitive in [object_proto_is_prototype_of_body].");
+      return impossible_with_heap_because(S, "[run_object_method] returned a primitive in [object_proto_is_prototype_of_body].");
     }
   });
 }