diff --git a/.gitignore b/.gitignore
index e0a90a616458144f6a50e14980bc66911eeac522..42765851f67e460d370e8baed8a80bb4998717c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,53 +1,9 @@
-tests/**/*.ast
-tests/**/*.cfg
-tests/**/*.cfg0
-tests/**/*.cfg1
-tests/**/*.cfg2
-tests/**/*.cfg3
-tests/**/*.e.dump
-tests/**/*.e.html
-tests/**/*.exe
-tests/**/*.json
-tests/**/*.lex
-tests/**/*.linear
-tests/**/*.linear1
-tests/**/*.ltl
-tests/**/*.rig
-tests/**/*.rtl
-tests/**/*.s
-tests/**/*.svg
-tests/results.html
-tests/__pycache__
 src/_build
-alpaga/_build
 grammar.html
 src/generated_parser.ml
 src/config.ml
 **/*.native
-alpaga/ml_parser_generator
-alpaga/alpaga
-alpaga/ml_parser_generator.native
-tykernel/*.ast
-tykernel/*.cfg
-tykernel/*.cfg0
-tykernel/*.cfg1
-tykernel/*.cfg2
-tykernel/*.e.dump
-tykernel/*.e.html
-tykernel/*.exe
-tykernel/*.lex
-tykernel/*.linear
-tykernel/*.linear1
-tykernel/*.ltl
-tykernel/*.rtl
-tykernel/*.s
-tykernel/*.svg
 skeleton
-sujet/_minted-tp
-sujet/*.aux
-sujet/*.fdb_latexmk
-sujet/*.fls
-sujet/*.log
-sujet/*.out
-sujet/*.pdf
-sujet/*.synctex.gz
+src/.vscode/
+.vscode/
+Makefile.config
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 1cac3804801bbfad3bd8f9844b2e2217cdaf3fc1..413254d16f14a82cc0f073a5d7b718366b1d26c9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,19 @@
 all: main.native
 
 .PHONY: main.native
-main.native:
+
+src/config.ml: configure
+	./configure
+
+main.native: src/config.ml
 	make -C alpaga
 	./alpaga/alpaga \
 			-g expr_grammar_action.g \
 			-pml src/generated_parser.ml \
 			-t grammar.html
-	./configure
 	make -C src
 	ln -sf src/main.native main.native
 
-
 clean:
 	make -C alpaga clean
 	rm -f src/generated_parser.ml
diff --git a/Sujet.pdf b/Sujet.pdf
index 3f1222d0362a2e74c1a5e13ded8a8368fb4d15e8..c0f06c0fb79bd3db8474acf83339bd618ec2783a 100644
Binary files a/Sujet.pdf and b/Sujet.pdf differ
diff --git a/alpaga/ml_parser_generator.ml b/alpaga/ml_parser_generator.ml
index 01a8a705f9e87a9d827ed34c180a97d48961e7bf..4b0c6d8b92ffd987ed756f488dc5a4de6ab4414d 100644
--- a/alpaga/ml_parser_generator.ml
+++ b/alpaga/ml_parser_generator.ml
@@ -68,7 +68,8 @@ let make_nt (table: string*string -> lltype list) (toks,nts,rules) oc n () =
         ) (a::r);
       Printf.fprintf oc "Printf.sprintf \"}\" ^ \n"
   end;
-  Printf.fprintf oc "  Printf.sprintf \" but got '%%s' instead.\\n\" got\n";
+  Printf.fprintf oc "  Printf.sprintf \" but got '%%s' instead.\\n\" got\n ^ ";
+  Printf.fprintf oc "  Printf.sprintf \" '%%s' \\n\" (String.concat \",\" (List.map (fun (x, _) -> string_of_symbol x) (List.take 10 tokens)))\n";
   Printf.fprintf oc "  )";
   Printf.fprintf oc "\n  end\n\n"
 
diff --git a/configure b/configure
index 8e49ee87b4aa6aa5be7987eb0984158907672ef4..42d40d9cc10cf698bc80e95bad227a1d5a6ab5e3 100755
--- a/configure
+++ b/configure
@@ -2,5 +2,16 @@
 
 RUNTIME=$(pwd)/runtime
 
+RVAS=$(which -a riscv64-unknown-linux-gnu-as riscv64-unknown-elf-as riscv64-linux-gnu-as 2>/dev/null | grep -v "not found" | head -n1)
+RVLD=$(which -a riscv64-unknown-linux-gnu-ld riscv64-unknown-elf-ld riscv64-linux-gnu-ld 2>/dev/null | grep -v "not found" | head -n1)
+QEMU32=$(which -a qemu-riscv32-static 2>/dev/null | grep -v "not found" | head -n1)
+QEMU64=$(which -a qemu-riscv64-static 2>/dev/null | grep -v "not found" | head -n1)
+
+
 echo "let runtime_dir = \"${RUNTIME}\"" > src/config.ml
-echo "let qemu_path = \"/usr/local/bin/qemu-riscv\"" >> src/config.ml
+echo "let qemu32 = \"${QEMU32}\"" >> src/config.ml
+echo "let qemu64 = \"${QEMU64}\"" >> src/config.ml
+echo "let rv_as = \"${RVAS}\"" >> src/config.ml
+echo "let rv_ld = \"${RVLD}\"" >> src/config.ml
+echo "let os_target = \"linux\"" >> src/config.ml
+
diff --git a/ldb/ldb.html b/ldb/ldb.html
index f4fea01ffa82c0dd73e622a183989d993d60edd6..efcdd8ee2bdf96ca51cd686745a0371b478831ba 100644
--- a/ldb/ldb.html
+++ b/ldb/ldb.html
@@ -44,7 +44,7 @@
             <div id="memstate"></div>
         </div>
             <div id="expr">
-                <input type="text" id="expr_input" size="30" /><br>
+                <input type="text" id="expr_input" size="20" /><br>
                 Result: <span id="expr_res"></span><hr>
                 <div id="subexprs"></div>
             </div>
diff --git a/ldb/ldb.js b/ldb/ldb.js
index a5709d16485e8a23834b925be881d93e66e9b42b..a1320381695f964ed4ea0cef96816545749e3082 100644
--- a/ldb/ldb.js
+++ b/ldb/ldb.js
@@ -678,10 +678,10 @@ function handle_command(d){
 
             for(let [evar,loc] of Object.entries(fb['vars'])){
                 if(Object.keys(loc).includes("reg")){
-                    p.insert("span").html("Var "+evar+": "+loc["reg"])
+                    p.insert("span").html("Var "+evar+": Reg "+loc["reg"])
                         .insert("br");
                 } else {
-                    p.insert("span").html("Var "+evar+": "+loc["stk"])
+                    p.insert("span").html("Var "+evar+": Stk "+loc["stk"])
                         .insert("br");
                 }
             }
diff --git a/ldb/style.css b/ldb/style.css
index 3828332e4203f7ece26d1fc1f40eeb03f275f631..036b6c9856d48022239e634c21d7925bdd9e9b86 100644
--- a/ldb/style.css
+++ b/ldb/style.css
@@ -54,7 +54,7 @@ html {
 }
 #body{
     display: grid;
-    grid-template-columns: [ctrl] 300px [code] 250px [outcfg] 600px [state] 700px;
+    grid-template-columns: [ctrl] 250px [code] 400px [outcfg] 500px [state] 700px;
     grid-template-rows: [row1] 200px [row2] 200px [row3] 400px [row4];
 }
 #code {
diff --git a/runtime/lib32.s b/runtime/lib32.s
index e5ad73a5bb14f27d11322752602d5e8180f90fa0..1249dd2695e39b72383836cf596e32c41fca1bf5 100644
--- a/runtime/lib32.s
+++ b/runtime/lib32.s
@@ -1,3 +1,4 @@
+	.include "syscall_numbers.s"
 	  .global atoi
 	  .global print_int
 	  .global println
@@ -66,7 +67,7 @@ li a3, 0
 li a4, 0
 li a5, 0
 li a6, 0
-li a7, 64
+li a7, SYSCALL_WRITE
 ecall
 jr ra
 print_char:
diff --git a/runtime/lib64.s b/runtime/lib64.s
index f407f9da3dff0a64590d61a11717054ed298f607..8a4710e71379bfcf163554cbd98dfbb4c718d25e 100644
--- a/runtime/lib64.s
+++ b/runtime/lib64.s
@@ -1,3 +1,4 @@
+.include "syscall_numbers.s"
   .global atoi
   .global print_int
   .global println
@@ -55,6 +56,7 @@ jal ra, print_a1
 ld ra, 0(sp)
 addi sp, sp, 8
 jr ra
+
 print_a1:
 addi sp, sp, -8
 sd ra,0(sp)
@@ -68,9 +70,10 @@ li a3, 0
 li a4, 0
 li a5, 0
 li a6, 0
-li a7, 64
+li a7, 	SYSCALL_WRITE
 ecall
 jr ra
+
 print_char:
 addi sp, sp, -8
 sd ra, 0(sp)
diff --git a/src/Makefile b/src/Makefile
index f972d566c1f3d4468cb26cd3d8c829265a4efe72..94e5b1b038cd1a3184de3bb2016872cd86755b61 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,11 +1,11 @@
 SRC=archi.ml ast.ml builtins.ml config.ml cfg_constprop.ml cfg_dead_assign.ml	\
-cfg.ml cfg_print.ml cfg_gen.ml cfg_liveness.ml cfg_loops.ml cfg_nop_elim.ml		\
-cfg_run.ml elang.ml elang_print.ml elang_gen.ml elang_run.ml e_regexp.ml			\
+cfg.ml cfg_print.ml cfg_gen.ml cfg_liveness.ml cfg_nop_elim.ml cfg_run.ml			\
+elang.ml elang_print.ml elang_gen.ml elang_run.ml e_regexp.ml									\
 generated_parser.ml lexer_generator.ml linear_dse.ml linear_liveness.ml				\
 linear.ml linear_print.ml linear_gen.ml linear_run.ml ltl.ml ltl_print.ml			\
 ltl_gen.ml ltl_run.ml ltl_debug.ml main.ml options.ml parser.ml prog.ml				\
 regalloc.ml report.ml riscv.ml rtl.ml rtl_print.ml rtl_gen.ml rtl_run.ml			\
-symbols.ml utils.ml
+symbols.ml tokenize.ml utils.ml
 
 TG = main.native
 
diff --git a/src/archi.ml b/src/archi.ml
index b65dc347734eb5a8f70b752557906564f5f4c1ea..988790064fc6218be79355941aaed39e8ed720ab 100644
--- a/src/archi.ml
+++ b/src/archi.ml
@@ -1,29 +1,61 @@
+open Config
+
 type archi = A64 | A32
 
-let wordsize = ref 8
-let assembler = ref "riscv64-unknown-elf-gcc"
-let instrsuffix = ref 'd'
 let archi = ref A64
-let nbits = ref 64
+let nbits () =
+  match !archi with
+  | A64 -> 64
+  | A32 -> 32
+
+let wordsize () = nbits () / 8
+
+let assembler () =
+  let opts =
+    match !archi with
+    | A64 -> "-march=rv64imafdc -mabi=lp64d"
+    | A32 -> "-march=rv32imafdc -mabi=ilp32"
+  in
+  Format.sprintf "%s %s" Config.rv_as opts
+
+let linker () =
+  let opts =
+    match !archi with
+      A64 -> "-melf64lriscv"
+    | A32 -> "-melf32lriscv"
+  in
+  Format.sprintf "%s %s" Config.rv_ld opts
+
+let instrsuffix () =
+  match !archi with
+  | A64 -> 'd'
+  | A32 -> 'w'
+
+let qemu () =
+  match !archi with
+  | A64 -> Config.qemu64
+  | A32 -> Config.qemu32
 
 let heapstart = ref 8
 
-let init_archi a () =
-  begin match a with
-    | A64 ->
-      begin
-        wordsize := 8;
-        assembler := "riscv64-unknown-elf-gcc";
-        instrsuffix := 'd';
-        archi := A64;
-      end
-    | A32 ->
-      begin
-        wordsize := 4;
-        assembler := "riscv32-unknown-elf-gcc";
-        instrsuffix := 'w';
-        archi := A32;
-      end
-  end
-  ;
-  nbits := !wordsize *8;
+type target_system =
+  | Linux
+  | Xv6
+
+let target = ref Linux
+
+let lib_syscall () =
+  match !target with
+  | Linux -> "linux"
+  | Xv6 -> "xv6"
+
+let target_data_segment t =
+  match t with
+  | Linux -> "8000000"
+  | Xv6 -> "2000"
+
+let runtime_lib_include_path () =
+  Format.sprintf "%s/%s" Config.runtime_dir (lib_syscall ())
+
+let runtime_lib_path () =
+  Format.sprintf "%s/lib%d.s" Config.runtime_dir (nbits ())
diff --git a/src/cfg_constprop.ml b/src/cfg_constprop.ml
index 524f8b1f4d6e67cbd5da16c2461a652e5953ab66..55440c63ee32a4817c641659b92670c3c0abceee 100644
--- a/src/cfg_constprop.ml
+++ b/src/cfg_constprop.ml
@@ -3,6 +3,9 @@ open Cfg
 open Elang_run
 open Prog
 open Utils
+open Report
+open Cfg_print
+open Options
 
 (* [simple_eval_eexpr e] evaluates an expression [e] with no variables. Raises
    an exception if the expression contains variables. *)
@@ -46,3 +49,10 @@ let constant_propagation_gdef = function
 
 let constant_propagation p =
   assoc_map constant_propagation_gdef p
+
+let pass_constant_propagation p =
+  let cfg = constant_propagation p in
+  record_compile_result "Constprop";
+  dump (!cfg_dump >*> fun s -> s ^ "1") dump_cfg_prog cfg
+    (call_dot "cfg-after-cstprop" "CFG after Constant Propagation");
+  OK cfg
diff --git a/src/cfg_dead_assign.ml b/src/cfg_dead_assign.ml
index abd0f0420c56af9dfa4408246744c514dce57d8c..e319094bc62d967d2cdbff918bb0e7d8d2e2aa64 100644
--- a/src/cfg_dead_assign.ml
+++ b/src/cfg_dead_assign.ml
@@ -3,6 +3,9 @@ open Cfg
 open Prog
 open Utils
 open Cfg_liveness
+open Report
+open Cfg_print
+open Options
 
 (* Dead Assign Elimination  -- Élimination des affectations mortes *)
 
@@ -32,3 +35,10 @@ let dead_assign_elimination_gdef = function
 
 let dead_assign_elimination p =
   assoc_map dead_assign_elimination_gdef p
+
+let pass_dead_assign_elimination cfg =
+  let cfg = dead_assign_elimination cfg in
+  record_compile_result "DeadAssign";
+  dump (!cfg_dump >*> fun s -> s ^ "2") dump_cfg_prog cfg
+    (call_dot "cfg-after-dae" "CFG after DAE");
+  OK cfg
diff --git a/src/cfg_gen.ml b/src/cfg_gen.ml
index e3d6b17c3aa8443830e453164d0e0067787acbd5..b20b93392d02bcde3a7e0a8f599991289fd51f54 100644
--- a/src/cfg_gen.ml
+++ b/src/cfg_gen.ml
@@ -3,6 +3,9 @@ open Elang
 open Cfg
 open Utils
 open Prog
+open Report
+open Cfg_print
+open Options
 
 (* [cfg_expr_of_eexpr e] converts an [Elang.expr] into a [expr res]. This should
    always succeed and be straightforward.
@@ -104,3 +107,12 @@ let cfg_gdef_of_edef gd =
 
 let cfg_prog_of_eprog (ep: eprog) : cfg_fun prog res =
   assoc_map_res (fun fname -> cfg_gdef_of_edef) ep
+
+let pass_cfg_gen ep =
+  match cfg_prog_of_eprog ep with
+  | Error msg ->
+    record_compile_result ~error:(Some msg) "CFG"; Error msg
+  | OK cfg ->
+    record_compile_result "CFG";
+    dump !cfg_dump dump_cfg_prog cfg (call_dot "cfg" "CFG");
+    OK cfg
diff --git a/src/cfg_nop_elim.ml b/src/cfg_nop_elim.ml
index 9de89ece4322c73f0282b39c0d55b1c74242b98d..aae822522f4fb120370e58b9a32f93c5383a3b74 100644
--- a/src/cfg_nop_elim.ml
+++ b/src/cfg_nop_elim.ml
@@ -3,6 +3,9 @@ open Batteries
 open Prog
 open Utils
 open Cfg
+open Report
+open Cfg_print
+open Options
 
 (* Élimination des NOPs. *)
 
@@ -77,3 +80,11 @@ let nop_elim_gdef gd =
 
 let nop_elimination cp =
   assoc_map nop_elim_gdef cp
+
+
+let pass_nop_elimination cfg =
+  let cfg = nop_elimination cfg in
+  record_compile_result "NopElim";
+  dump (!cfg_dump >*> fun s -> s ^ "3") dump_cfg_prog cfg
+    (call_dot "cfg-after-nop" "CFG after NOP elim");
+  OK cfg
diff --git a/src/elang_gen.ml b/src/elang_gen.ml
index e8f9cd6922ac226fc7496be037d92ae7f351f476..eb6615b109ae955bbfacc6f310fa77caf1a3325b 100644
--- a/src/elang_gen.ml
+++ b/src/elang_gen.ml
@@ -2,6 +2,9 @@ open Ast
 open Elang
 open Prog
 open Utils
+open Report
+open Elang_print
+open Options
 
 let tag_is_binop =
   function
@@ -86,3 +89,13 @@ let make_eprog_of_ast (a: tree) : eprog res =
   | _ ->
     Error (Printf.sprintf "make_fundef_of_ast: Expected a Tlistglobdef, got %s."
              (string_of_ast a))
+
+let pass_elang ast =
+  match make_eprog_of_ast ast with
+  | Error msg ->
+    record_compile_result ~error:(Some msg) "Elang";
+    Error msg
+  | OK  ep ->
+    dump !e_dump dump_e ep (fun file () ->
+        add_to_report "e" "E" (Code (file_contents file))); OK ep
+
diff --git a/src/lexer_generator.ml b/src/lexer_generator.ml
index bd37e8489758ca694c62dbb7fa5063f2fa7c57b5..f79e1dbf2bf4305a159b886dc73cb407b5ded0ac 100644
--- a/src/lexer_generator.ml
+++ b/src/lexer_generator.ml
@@ -63,7 +63,7 @@ let star_nfa n t =
 (* [nfa_of_regexp r freshstate t] construit un NFA qui reconnaît le même langage
    que l'expression régulière [r].
    [freshstate] correspond à un entier pour lequel il n'y a pas encore d'état dans 
-   le nfa. Il suffit d'incrémenter [freshstate] pour obtenir de nouveaux état non utilisés.
+   le nfa. Il suffit d'incrémenter [freshstate] pour obtenir de nouveaux états non utilisés.
    [t] est une fonction du type [string -> token option] utile pour les état finaux.
 *)
 let rec nfa_of_regexp r freshstate t =
@@ -447,11 +447,6 @@ let dfa_to_dot oc (n : dfa) (cl: char list): unit =
     ) n.dfa_states;
   Printf.fprintf oc "}\n"
 
-let alts l =
-  match l with
-    [] -> Eps
-  | a::r -> List.fold_left (fun acc r -> Alt(acc,r)) a l
-
 let nfa_of_list_regexp l =
   let (n, fs) = List.fold_left (fun (nfa, fs) (r,t) ->
       let n,fs = nfa_of_regexp r fs t in
diff --git a/src/linear_dse.ml b/src/linear_dse.ml
index 1f4e0e0a1e893c7d623881aea3f893469543016a..e0ac6d97bf1576b80f8390ccc96b14342cc7cf96 100644
--- a/src/linear_dse.ml
+++ b/src/linear_dse.ml
@@ -5,6 +5,9 @@ open Batteries
 open BatList
 open Prog
 open Utils
+open Report
+open Linear_print
+open Options
 
 let dse_instr (ins: rtl_instr) live =
    [ins]
@@ -26,3 +29,12 @@ let dse_prog p live =
         let f = dse_fun live f in
         (fname, Gfun f)
       ) p
+
+let pass_linear_dse linear lives =
+  let linear = dse_prog linear lives in
+  record_compile_result "DSE";
+  dump (!linear_dump >*> fun s -> s ^ "1")
+    (fun oc -> dump_linear_prog oc (Some lives)) linear
+    (fun file () -> add_to_report "linear-after-dse" "Linear after DSE"
+        (Code (file_contents file)));
+  OK linear
diff --git a/src/linear_gen.ml b/src/linear_gen.ml
index 8c049a3ce341f532d347c10a8cf7b766e0a76ad1..c12bd04588cfef6a06de11d299bd2ebcd26c09c3 100644
--- a/src/linear_gen.ml
+++ b/src/linear_gen.ml
@@ -3,7 +3,10 @@ open Rtl
 open Linear
 open Prog
 open Utils
-
+open Report
+open Linear_print
+open Options
+open Linear_liveness
 
 let succs_of_rtl_instr (i: rtl_instr) =
   match i with
@@ -55,3 +58,10 @@ let linear_of_rtl_gdef = function
 
 let linear_of_rtl r =
   assoc_map linear_of_rtl_gdef r
+
+let pass_linearize rtl =
+  let linear = linear_of_rtl rtl in
+  let lives = liveness_linear_prog linear in
+  dump !linear_dump (fun oc -> dump_linear_prog oc (Some lives)) linear
+    (fun file () -> add_to_report "linear" "Linear" (Code (file_contents file)));
+  OK (linear, lives)
diff --git a/src/ltl.ml b/src/ltl.ml
index a1344a5b960ae72516df1c6251bb15173a1cd8af..6082bfb5b45f4a311e6c8a681e20676c5509c3a9 100644
--- a/src/ltl.ml
+++ b/src/ltl.ml
@@ -53,10 +53,10 @@ let reg_ret = reg_a0
 type ltl_instr =
     LAddi of ltl_reg * ltl_reg * int
   | LSubi of ltl_reg * ltl_reg * int
-  | LStore of ltl_reg * int * ltl_reg * int (* LStore(rd, rofs, rs, sz) : store
+  | LStore of ltl_reg * int * ltl_reg * mem_access_size (* LStore(rd, rofs, rs, sz) : store
                                                value in [rs] on [sz] bytes at
                                                address [rd+rofs] *)
-  | LLoad of ltl_reg * ltl_reg * int * int (* LLoad(rd, rs, rofs, sz) : load
+  | LLoad of ltl_reg * ltl_reg * int * mem_access_size (* LLoad(rd, rs, rofs, sz) : load
                                               value at address [rs+rofs] on [sz]
                                               bytes in register [rd]. *)
   | LMov of ltl_reg * ltl_reg   (* LMov(rd, rs) : move value of [rs] into [rd].
diff --git a/src/ltl_gen.ml b/src/ltl_gen.ml
index 68fb1e7de8184a903b30ce3c0227e0de4faeb932..06edd325206226d5cfb63a11d9fcd6e3ace70c27 100644
--- a/src/ltl_gen.ml
+++ b/src/ltl_gen.ml
@@ -7,6 +7,8 @@ open Prog
 open Utils
 open Regalloc
 open Linear_liveness
+open Report
+open Options
 
 (* list of registers used to store arguments. [a0-a7] *)
 let arg_registers =
@@ -18,12 +20,12 @@ let arg_registers =
 *)
 
 let make_push r =
-  [LSubi(reg_sp, reg_sp, !Archi.wordsize);
-   LStore(reg_sp, 0, r, !Archi.wordsize)]
+  [LSubi(reg_sp, reg_sp, (Archi.wordsize ()));
+   LStore(reg_sp, 0, r, (archi_mas ()))]
 
 let make_pop r =
-  [LLoad(r, reg_sp, 0, !Archi.wordsize);
-   LAddi(reg_sp, reg_sp, !Archi.wordsize)]
+  [LLoad(r, reg_sp, 0, (archi_mas ()));
+   LAddi(reg_sp, reg_sp, (Archi.wordsize ()))]
 
 let make_sp_sub v =
   [LSubi(reg_sp, reg_sp, v)]
@@ -39,12 +41,12 @@ let make_loc_mov src dst =
   match src, dst with
   | Stk osrc , Stk odst ->
     let rtmp = reg_tmp1 in
-    [LLoad(rtmp, reg_fp, !Archi.wordsize * osrc, !Archi.wordsize);
-     LStore(reg_fp, !Archi.wordsize * odst, rtmp, !Archi.wordsize)]
+    [LLoad(rtmp, reg_fp, (Archi.wordsize ()) * osrc, (archi_mas ()));
+     LStore(reg_fp, (Archi.wordsize ()) * odst, rtmp, (archi_mas ()))]
   | Stk osrc, Reg rdst ->
-    [LLoad(rdst, reg_fp, !Archi.wordsize * osrc, !Archi.wordsize)]
+    [LLoad(rdst, reg_fp, (Archi.wordsize ()) * osrc, (archi_mas ()))]
   | Reg rsrc, Stk ofst ->
-    [LStore(reg_fp, !Archi.wordsize * ofst, rsrc, !Archi.wordsize)]
+    [LStore(reg_fp, (Archi.wordsize ()) * ofst, rsrc, (archi_mas ()))]
   | Reg rsrc, Reg rdst ->
     [LMov(rdst,rsrc)]
 
@@ -54,7 +56,7 @@ let load_loc tmp allocation r =
   match Hashtbl.find_option allocation r with
   | None ->
     Error (Format.sprintf "Unable to allocate RTL register r%d." r)
-  | Some (Stk o) -> OK ([LLoad(tmp, reg_fp, !Archi.wordsize * o, !Archi.wordsize)], tmp)
+  | Some (Stk o) -> OK ([LLoad(tmp, reg_fp, (Archi.wordsize ()) * o, (archi_mas ()))], tmp)
   | Some (Reg r) -> OK ([], r)
 
 (* store_loc tmp allocation r = (l, r'). I want to write in RTL register r.
@@ -63,7 +65,7 @@ let store_loc tmp allocation r =
   match Hashtbl.find_option allocation r with
   | None ->
     Error (Format.sprintf "Unable to allocate RTL register r%d." r)
-  | Some (Stk o) -> OK ([LStore(reg_fp, !Archi.wordsize * o, tmp, !Archi.wordsize)], tmp)
+  | Some (Stk o) -> OK ([LStore(reg_fp, (Archi.wordsize ()) * o, tmp, (archi_mas ()))], tmp)
   | Some (Reg r) -> OK ([], r)
 
 (* saves registers in [to_save] on the stack at offsets [fp + 8 * o, fp + 8 * (o
@@ -73,14 +75,14 @@ let store_loc tmp allocation r =
    - the list of store instructions - the next offset to be written. *)
 let save_caller_save to_save ofs =
   List.fold_left (fun (instrs, arg_saved, ofs) reg ->
-      (instrs @ [LStore(reg_fp, !Archi.wordsize * ofs, reg, !Archi.wordsize)],
+      (instrs @ [LStore(reg_fp, (Archi.wordsize ()) * ofs, reg, (archi_mas ()))],
        (reg,ofs)::arg_saved, ofs - 1)
     ) ([], [], ofs) to_save
 
 (* Given a list [(reg,ofs)], loads [fp+ofs] into [reg]. *)
 let restore_caller_save arg_saved =
   List.map
-    (fun (reg, ofs) -> LLoad(reg, reg_fp, !Archi.wordsize * ofs, !Archi.wordsize))
+    (fun (reg, ofs) -> LLoad(reg, reg_fp, (Archi.wordsize ()) * ofs, (archi_mas ())))
     arg_saved
 
 let num_parameters_passed_on_stack regs =
@@ -192,13 +194,13 @@ let pass_parameters rargs allocation arg_saved =
           begin match src with
             | Reg rs ->  (rd::overwritten, [LMov(rd, rs)],[], npush)
             | Stk o -> (rd::overwritten,
-                        [LLoad(rd, reg_fp, !Archi.wordsize * o, !Archi.wordsize)],
+                        [LLoad(rd, reg_fp, (Archi.wordsize ()) * o, (archi_mas ()))],
                         [], npush)
           end else
           begin match src with
             | Reg rs -> (overwritten, [], make_push rs@pushes, npush+1)
             | Stk o ->  (overwritten, [],
-                         LLoad(reg_tmp1, reg_fp, !Archi.wordsize * o, !Archi.wordsize)
+                         LLoad(reg_tmp1, reg_fp, (Archi.wordsize ()) * o, (archi_mas ()))
                          ::make_push reg_tmp1 @ pushes,
                          npush+1)
           end
@@ -307,11 +309,11 @@ let ltl_instrs_of_linear_instr fname live_out allocation
       match Hashtbl.find_option allocation r with
       | None -> Error (Format.sprintf "Could not find allocation for register %d\n" r)
       | Some (Reg rs) -> OK [LMov(reg_a0, rs)]
-      | Some (Stk o) -> OK [LLoad(reg_a0, reg_fp, !Archi.wordsize * o, !Archi.wordsize)]
+      | Some (Stk o) -> OK [LLoad(reg_a0, reg_fp, (Archi.wordsize ()) * o, (archi_mas ()))]
     in
     parameter_passing >>= fun parameter_passing ->
     OK (LComment "Saving a0-a7,t0-t6" :: save_a_regs @
-        LAddi(reg_sp, reg_s0, !Archi.wordsize * (ofs + 1)) ::
+        LAddi(reg_sp, reg_s0, (Archi.wordsize ()) * (ofs + 1)) ::
         parameter_passing @
         LCall "print" ::
         LComment "Restoring a0-a7,t0-t6" :: restore_caller_save arg_saved)
@@ -364,7 +366,7 @@ let ltl_fun_of_linear_fun linprog
   let prologue =
     List.concat (List.map make_push (Set.to_list callee_saved_regs)) @
     LMov (reg_fp, reg_sp) ::
-    make_sp_sub (numspilled * !Archi.wordsize) @
+    make_sp_sub (numspilled * (Archi.wordsize ())) @
     [LComment "end prologue"] in
   let epilogue = LLabel epilogue_label ::
                  LMov(reg_sp, reg_fp) ::
@@ -411,3 +413,11 @@ let ltl_prog_of_linear lp =
     ) lp in
   prog
 
+let pass_ltl_gen linear =
+  match ltl_prog_of_linear linear with
+  | Error msg -> record_compile_result ~error:(Some msg) "LTL"; Error msg
+  | OK ltl ->
+    record_compile_result "LTL";
+    dump !ltl_dump dump_ltl_prog ltl
+      (fun file () -> add_to_report "ltl" "LTL" (Code (file_contents file)));
+    OK ltl
diff --git a/src/ltl_print.ml b/src/ltl_print.ml
index bdabe2569a3d8f27638ba06ee2f40cf0380c7a14..57869ea001c1cd7872fbd8858e836306c3d0ca17 100644
--- a/src/ltl_print.ml
+++ b/src/ltl_print.ml
@@ -83,9 +83,9 @@ let dump_ltl_instr oc (i: ltl_instr) =
     Format.fprintf oc "%s <- %s %s"
       (print_reg rd) (print_unop u)  (print_reg rs)
   | LStore(rt, i, rs, sz) ->
-    Format.fprintf oc "%s{%d}[%d] <- %s" (print_reg rt) sz i (print_reg rs)
+    Format.fprintf oc "%s%s[%d] <- %s" (print_reg rt) (string_of_mem_access_size sz) i (print_reg rs)
   | LLoad(rd, rt, i, sz) ->
-    Format.fprintf oc "%s <- %s{%d}[%d]" (print_reg rd) (print_reg rt) sz i
+    Format.fprintf oc "%s <- %s%s[%d]" (print_reg rd) (print_reg rt) (string_of_mem_access_size sz) i
   | LMov(rd, rs) ->
     Format.fprintf oc "%s <- %s" (print_reg rd) (print_reg rs)
   | LLabel l ->
diff --git a/src/ltl_run.ml b/src/ltl_run.ml
index 669033ddf153edbb3fe3bf39e3179a27170229fb..187fd87e33b8381c75061da070cbeb72246027fc 100644
--- a/src/ltl_run.ml
+++ b/src/ltl_run.ml
@@ -101,11 +101,11 @@ let exec_ltl_instr oc ip st : (int option) res =
   | LStore(rt, i, rs, sz) ->
     get_reg st rt $ fun vt ->
       get_reg st rs $ fun vs ->
-        Mem.write_bytes st.mem (vt + i)  (split_bytes sz vs) >>= fun _ ->
+        Mem.write_bytes st.mem (vt + i)  (split_bytes (size_of_mas sz) vs) >>= fun _ ->
         next ip
   | LLoad(rd, rt, i, sz) ->
     get_reg st rt $ fun vt ->
-      Mem.read_bytes_as_int st.mem (vt + i) sz >>= fun (v) ->
+      Mem.read_bytes_as_int st.mem (vt + i) (size_of_mas sz) >>= fun (v) ->
       Array.set st.regs rd v;
       next ip
   | LMov(rd, rs) ->
@@ -201,9 +201,9 @@ let init_state memsize lp params =
   List.iteri (fun i p ->
       if i >= number_of_arguments_passed_in_registers
       then begin
-        let sp = Array.get regs reg_sp - !Archi.wordsize in
+        let sp = Array.get regs reg_sp - (Archi.wordsize ()) in
         Array.set regs reg_sp sp;
-        Mem.write_bytes mem sp (split_bytes !Archi.wordsize p) >>!
+        Mem.write_bytes mem sp (split_bytes (Archi.wordsize ()) p) >>!
         ignore
       end else
         begin
@@ -211,7 +211,7 @@ let init_state memsize lp params =
         end
     ) params;
   let mem_next = ref (codesize + 8) in
-  Mem.write_bytes mem codesize (split_bytes !Archi.wordsize !mem_next) >>!
+  Mem.write_bytes mem codesize (split_bytes (Archi.wordsize ()) !mem_next) >>!
   fun _ ->
   Printf.eprintf "numlabels = %d\n" (Hashtbl.length labels);
   Printf.eprintf "labels = %s\n" (Hashtbl.keys labels |> List.of_enum |> String.concat ", ");
diff --git a/src/main.ml b/src/main.ml
index dcc6443e91d74bffbbb95463eecce131502f979b..abae9ca260acc9f72fcb64233144a76eac8b1b4e 100644
--- a/src/main.ml
+++ b/src/main.ml
@@ -35,12 +35,7 @@ open Archi
 open Report
 open Options
 open Lexer_generator
-
-open Cfg_loops
-
-let tokenize file =
-  Lexer_generator.tokenize_file file >>= fun tokens ->
-  OK (List.map (fun tok -> (tok, None)) tokens)
+open Tokenize
 
 let speclist =
   [
@@ -51,7 +46,6 @@ let speclist =
     ("-e-run", Arg.Set e_run, "Run Elang program.");
     ("-cfg-dump", Arg.String (fun s -> cfg_dump := Some s), "Output CFG file.");
     ("-cfg-run", Arg.Set cfg_run, "Run CFG program.");
-    ("-cfg-run-after-loop", Arg.Set cfg_run_after_loop, "Run CFG program after loop optimization.");
     ("-cfg-run-after-cp", Arg.Set cfg_run_after_cp, "Run CFG program after constant propagation.");
     ("-cfg-run-after-dae", Arg.Set cfg_run_after_dae, "Run CFG program after dead assign elimination.");
     ("-cfg-run-after-ne", Arg.Set cfg_run_after_ne, "Run CFG program after nop elimination.");
@@ -70,12 +64,15 @@ let speclist =
     ("-clever-regalloc", Arg.Unit (fun () -> naive_regalloc := false), "Use the graph coloring algorithm for register allocation.");
     ("-naive-regalloc", Arg.Unit (fun () -> naive_regalloc := true),
      "Use the naive algorithm for register allocation (all pseudo-registers go on the stack).");
+    ("-no-cfg-constprop", Arg.Set no_cfg_constprop, "Disable CFG constprop");
+    ("-no-cfg-dae", Arg.Set no_cfg_dae, "Disable CFG Dead Assign Elimination");
+    ("-no-cfg-ne", Arg.Set no_cfg_ne, "Disable CFG Nop Elimination");
+    ("-no-linear-dse", Arg.Set no_linear_dse, "Disable Linear Dead Store Elimination");
     ("-rig-dump", Arg.String (fun s -> rig_dump := Some s),
     "Path to output the register interference graph");
     ("-all-run", Arg.Unit (fun () ->
          e_run := true;
          cfg_run := true;
-         cfg_run_after_loop := true;
          cfg_run_after_cp := true;
          cfg_run_after_dae := true;
          cfg_run_after_ne := true;
@@ -94,106 +91,11 @@ let speclist =
     ("-nostart", Arg.Set nostart, "Don't output _start code.");
     ("-nostats", Arg.Set nostats, "Don't output stats.");
     ("-nomul", Arg.Unit (fun _ -> has_mul := false), "Target architecture without mul instruction.");
+    ("-linux", Arg.Unit (fun _ -> target := Linux), "emit linux syscalls");
+    ("-xv6", Arg.Unit (fun _ -> target := Xv6), "emit xv6 syscalls");
     ("--", Arg.Rest (fun p -> params := int_of_string p::!params), "Run parameters.")
   ]
 
-
-
-type run_result = {
-  step: string;
-  retval: int option;
-  output: string;
-  error: string option;
-  time: float;
-}
-
-type compile_result = {
-  step: string;
-  error: string option;
-  data: Yojson.t
-}
-
-type result = RunRes of run_result
-            | CompRes of compile_result
-
-
-let results = ref []
-
-let run step flag eval p =
-  if flag then begin
-    let starttime = Unix.gettimeofday () in
-    let res = match eval Format.str_formatter p !heapsize !params with
-      | exception e ->
-        Error (Printexc.to_string e)
-      | e -> e in
-    let timerun = Unix.gettimeofday () -. starttime in
-    begin match res with
-      | OK v ->
-        let output = Format.flush_str_formatter () in
-        results := !results @ [RunRes { step ; retval = v; output; error = None; time = timerun}];
-        add_to_report step ("Run " ^ step) (
-          Paragraph 
-            (
-              Printf.sprintf "With parameters : [%s]<br>\n" (String.concat"," (List.map string_of_int !params))
-              ^ Printf.sprintf "Mem size : %d bytes<br>\n" !heapsize
-              ^ Printf.sprintf "Return value : %s<br>\n" (match v with | Some v -> string_of_int v | _ -> "none")
-              ^ Printf.sprintf "Output : <pre style=\"padding: 1em; background-color: #ccc;\">%s</pre>\n" output
-              ^ Printf.sprintf "Time : %f seconds<br>\n" timerun
-            )
-        )
-      | Error msg ->
-        let output  = Format.flush_str_formatter () in
-        results := !results @ [RunRes { step ; retval = None; output; error = Some msg; time = timerun}];
-        add_to_report step ("Run " ^ step) (
-          Paragraph 
-            (
-              Printf.sprintf "With parameters : [%s]<br>\n" (String.concat"," (List.map string_of_int !params))
-              ^ Printf.sprintf "Mem size : %d bytes<br>\n" !heapsize
-              ^ Printf.sprintf "Return value : none<br>\n"
-              ^ Printf.sprintf "Output : <pre style=\"padding: 1em; background-color: #ccc;\">%s</pre>\n" output
-              ^ Printf.sprintf "Error : <pre style=\"padding: 1em; background-color: #fcc;\">\n%s</pre>\n" msg
-              ^ Printf.sprintf "Time : %f seconds<br>\n" timerun
-            )
-        )
-
-    end
-  end
-
-let record_compile_result ?error:(error=None) ?data:(data=[]) step =
-  let data = if not !Options.nostats then `List data else `Null in
-  results := !results @ [CompRes { step; error; data}]
-
-
-
-let process_output_to_list2 = fun command ->
-  let chan = Unix.open_process_in command in
-  let res = ref ([] : string list) in
-  let rec process_otl_aux () =
-    let e = input_line chan in
-    res := e::!res;
-    process_otl_aux() in
-  try process_otl_aux ()
-  with End_of_file ->
-    let stat = Unix.close_process_in chan in (List.rev !res,stat)
-
-let cmd_to_list command =
-  let (l,_) = process_output_to_list2 command in l
-
-let file_contents file =
-  match
-    let ic = open_in file in
-    let rec aux s () =
-      try
-        let line = input_line ic in  (* read line from in_channel and discard \n *)
-        aux (s ^ line ^ "\n") ()   (* close the input channel *)
-      with e ->                      (* some unexpected exception occurs *)
-        close_in_noerr ic;           (* emergency closing *)
-        s in
-    aux "" ()
-  with
-  | exception Sys_error _ -> failwith (Printf.sprintf "Could not open file %s\n" file)
-  | x -> x
-
 let set_default r v suff =
   match !r with
     None -> r := Some (v ^ suff)
@@ -201,13 +103,28 @@ let set_default r v suff =
 
 let compile_rv basename asmfile () =
   if not !Options.nostart then begin
-    let out, _ =
-      Format.sprintf
-        "%s -nostdlib -nostartfiles -T %s/link.ld -o \"%s.exe\" \"%s\" %s/lib%d.s %s/mul%d.S 2>&1"
-        !Archi.assembler Config.runtime_dir basename asmfile 
-        Config.runtime_dir !Archi.nbits
-        Config.runtime_dir !Archi.nbits
-      |> process_output_to_list2 in
+    let obj_file_prog = Filename.temp_file ~temp_dir:"/tmp" "" ".o" in
+    let cmdas_prog = Format.sprintf "%s -I%s -o %s %s"
+        (Archi.assembler ())
+        (Archi.runtime_lib_include_path ())
+        obj_file_prog asmfile in
+    let obj_file_lib = Filename.temp_file ~temp_dir:"/tmp" "" ".o" in
+    let cmdas_lib = Format.sprintf "%s -I%s -o %s %s"
+        (Archi.assembler ())
+        (Archi.runtime_lib_include_path ())
+        obj_file_lib (Archi.runtime_lib_path ()) in
+    let cmdld = Format.sprintf "%s -T %s/link.ld %s %s -o %s.exe"
+        (Archi.linker ())
+        Config.runtime_dir
+        obj_file_prog obj_file_lib
+        basename in
+    Printf.printf "AS: %s\n" cmdas_prog;
+    Printf.printf "AS: %s\n" cmdas_lib;
+    Printf.printf "LD: %s\n" cmdld;
+    let out_as_prog = cmd_to_list cmdas_prog in
+    let out_as_lib = cmd_to_list cmdas_lib in
+    let out_ld = cmd_to_list cmdld in
+    let out = out_as_prog @ out_as_lib @ out_ld in
     match out with
       [] -> None
     | _ -> Some (String.concat "\n" out)
@@ -223,17 +140,12 @@ let exec_rv_prog ltl basename oc rvp heapsize params =
       f
   in
   let error = ref None in
-  dump (Some rvp) (fun oc p ->
-      match dump_riscv_prog oc p with
-      | OK _ -> ()
-      | Error msg -> error := Some msg
-    ) ltl (fun file () ->
-      if !error = None
-      then error := compile_rv basename file ());
+  dump (Some rvp) (dump_riscv_prog !Archi.target) ltl (fun file () ->
+      error := compile_rv basename file ());
   match !error with
   | Some e -> Error ("RiscV generation error:\n" ^e)
   | None ->
-    let l = cmd_to_list (Format.sprintf "%s%d-static \"%s.exe\" %s" Config.qemu_path !Archi.nbits basename
+    let l = cmd_to_list (Format.sprintf "%s \"%s.exe\" %s" (Archi.qemu ())  basename
                            (params |> List.map string_of_int |> String.concat " " )) in
     try
       let all_but_last = l |> List.rev |> List.tl |> List.rev in
@@ -245,7 +157,7 @@ let exec_rv_prog ltl basename oc rvp heapsize params =
 
 let _ =
   Arg.parse speclist (fun s -> ()) "Usage";
-  init_archi !archi ();
+  Archi.archi := !archi;
   match !input_file with
   | None -> failwith "No input file specified.\n"
   | Some input ->
@@ -255,142 +167,54 @@ let _ =
       None -> failwith
                 (Format.sprintf "File (%s) should end in .e" input)
     | Some basename ->
-      begin
-        params := List.rev !params;
-        set_default riscv_dump basename ".s";
-        if not !no_dump then begin
-          set_default show_tokens basename ".lex";
-          set_default ast_tree basename ".ast";
-          set_default e_dump basename ".e.dump";
-          set_default cfg_dump basename ".cfg";
-          set_default rtl_dump basename ".rtl";
-          set_default linear_dump basename ".linear";
-          set_default rig_dump basename ".rig";
-          set_default ltl_dump basename ".ltl";
-        end;
-
-        tokenize input >>* (fun msg ->
-            record_compile_result ~error:(Some msg) "Lexing";
-          ) $ fun tokens ->
-            record_compile_result "Lexing";
-            dump !show_tokens (fun oc tokens ->
-                List.iter (fun (tok,_) ->
-                    Format.fprintf oc "%s\n" (string_of_symbol tok)
-                  ) tokens) tokens (fun f () -> add_to_report "lexer" "Lexer" (Code (file_contents f)));
-            parse tokens () >>* (fun msg ->
-                record_compile_result ~error:(Some msg) "Parsing";
-              ) $ fun (ast, tokens) ->
-                record_compile_result "Parsing";
-                dump !ast_tree draw_ast_tree ast (call_dot "ast" "AST");
-                if !ast_dump then Format.printf "%s\n" (string_of_ast ast) else ();
-
-                match make_eprog_of_ast ast with
-                | Error msg -> record_compile_result ~error:(Some msg) "Elang"
-                | OK  ep ->
-                  dump !e_dump dump_e ep (fun file () ->
-                      add_to_report "e" "E" (Code (file_contents file)));
-                  run "Elang" !e_run eval_eprog ep;
-
-                  match cfg_prog_of_eprog ep with
-                  | Error msg ->
-                    record_compile_result ~error:(Some msg) "CFG";
-                  | OK cfg ->
-                    record_compile_result ~data:([(`Assoc (List.map (fun (fname,Prog.Gfun cfgfun) -> (fname, `Int (Cfg.size_fun cfgfun.cfgfunbody))) cfg))]) "CFG";
-
-                    dump !cfg_dump dump_cfg_prog cfg (call_dot "cfg" "CFG");
-                    run "CFG" !cfg_run eval_cfgprog cfg;
-
-                    let cfg = optimize_loop_cfg cfg in
-                    record_compile_result ~data:([(`Assoc (List.map (fun (fname,Prog.Gfun cfgfun) -> (fname, `Int (Cfg.size_fun cfgfun.cfgfunbody))) cfg))]) "CFG loops";
-                    dump (!cfg_dump >*> fun s -> s ^ "0") dump_cfg_prog cfg
-                      (call_dot "cfg-after-loop" "CFG after loop optim");
-                    run "CFG after loop optim" !cfg_run_after_loop eval_cfgprog cfg;
-
-
-                    let cfg = constant_propagation cfg in
-                    record_compile_result ~data:([(`Assoc (List.map (fun (fname,Prog.Gfun cfgfun) -> (fname, `Int (Cfg.size_fun cfgfun.cfgfunbody))) cfg))]) "Constprop";
-                    dump (!cfg_dump >*> fun s -> s ^ "1") dump_cfg_prog cfg
-                      (call_dot "cfg-after-cstprop" "CFG after Constant Propagation");
-                    run "CFG after constant_propagation" !cfg_run_after_cp eval_cfgprog cfg;
-
-                    let cfg = dead_assign_elimination cfg in
-                    record_compile_result ~data:([(`Assoc (List.map (fun (fname,Prog.Gfun cfgfun) -> (fname, `Int (Cfg.size_fun cfgfun.cfgfunbody))) cfg))]) "DeadAssign";
-                    dump (!cfg_dump >*> fun s -> s ^ "2") dump_cfg_prog cfg
-                      (call_dot "cfg-after-dae" "CFG after DAE");
-                    run "CFG after dead_assign_elimination" !cfg_run_after_dae eval_cfgprog cfg;
-
-                    let cfg = nop_elimination cfg in
-                    record_compile_result ~data:([(`Assoc (List.map (fun (fname,Prog.Gfun cfgfun) -> (fname, `Int (Cfg.size_fun cfgfun.cfgfunbody))) cfg))]) "NopElim";
-                    dump (!cfg_dump >*> fun s -> s ^ "3") dump_cfg_prog cfg
-                      (call_dot "cfg-after-nop" "CFG after NOP elim");
-                    run "CFG after nop_elimination" !cfg_run_after_ne eval_cfgprog cfg;
-
-
-                    let rtl = rtl_of_cfg cfg in
-                    dump !rtl_dump dump_rtl_prog rtl
-                      (fun file () -> add_to_report "rtl" "RTL" (Code (file_contents file)));
-                    run "RTL" !rtl_run exec_rtl_prog rtl;
-
-                    let linear = linear_of_rtl rtl in
-                    let lives = liveness_linear_prog linear in
-                    dump !linear_dump (fun oc -> dump_linear_prog oc (Some lives)) linear
-                      (fun file () -> add_to_report "linear" "Linear" (Code (file_contents file)));
-                    run "Linear" !linear_run exec_linear_prog linear;
-
-                    let linear = dse_prog linear lives in
-                    record_compile_result "DSE";
-                    dump (!linear_dump >*> fun s -> s ^ "1")
-                      (fun oc -> dump_linear_prog oc (Some lives)) linear
-                      (fun file () -> add_to_report "linear-after-dse" "Linear after DSE"
-                          (Code (file_contents file)));
-                    run "Linear after DSE" !linear_run_after_dse exec_linear_prog linear;
-
-                    match ltl_prog_of_linear linear with
-                    | Error msg -> record_compile_result ~error:(Some msg) "LTL"
-                    | OK ltl ->
-                      dump !ltl_dump dump_ltl_prog ltl
-                        (fun file () -> add_to_report "ltl" "LTL" (Code (file_contents file)));
-                      run "LTL" !ltl_run (exec_ltl_prog) ltl;
-                      (if !ltl_debug then debug_ltl_prog input ltl !heapsize !params);
-
-                      dump !riscv_dump (fun oc p ->
-                          match dump_riscv_prog oc p with
-                          | OK _ -> ()
-                          | Error msg -> record_compile_result ~error:(Some msg) "RISCV"
-                        ) ltl (fun file () ->
-                          add_to_report "riscv" "RISC-V" (Code (file_contents file));
-                          ignore (compile_rv basename file ()));
-                      if not !Options.nostart then begin
-                        run "Risc-V" !riscv_run (exec_rv_prog ltl basename) !riscv_dump
-                      end;
-
+      params := List.rev !params;
+      set_default riscv_dump basename ".s";
+      if not !no_dump then begin
+        set_default show_tokens basename ".lex";
+        set_default ast_tree basename ".ast";
+        set_default e_dump basename ".e.dump";
+        set_default cfg_dump basename ".cfg";
+        set_default rtl_dump basename ".rtl";
+        set_default linear_dump basename ".linear";
+        set_default rig_dump basename ".rig";
+        set_default ltl_dump basename ".ltl";
       end;
 
-      let json_output_string = 
-        let open Yojson in
-        let jstring_of_ostring o =
-          match o with
-          | None -> `Null
-          | Some s -> `String s
-        in
-        let j = `List (List.map (function
-            | RunRes { step; retval; output; error; time } ->
-              `Assoc [("runstep",`String step);
-                      ("retval", match retval with Some r -> `Int r | None -> `Null);
-                      ("output", `String output);
-                      ("error", jstring_of_ostring error);
-                      ("time", `Float time)
-                     ]
-            | CompRes { step; error; data } ->
-              `Assoc [("compstep",`String step);
-                      ("error", jstring_of_ostring error);
-                      ("data", data)
-                     ]
-          ) !results) in
-        (Yojson.pretty_to_string j) in
-
-
+      let compiler_res =
+        pass_tokenize input >>= fun tokens ->
+        pass_parse tokens >>= fun (ast, _) ->
+        pass_elang ast >>= fun ep ->
+        run "Elang" !e_run eval_eprog ep;
+        pass_cfg_gen ep >>= fun cfg ->
+        run "CFG" !cfg_run eval_cfgprog cfg;
+        pass_constant_propagation cfg >>= fun cfg ->
+        run "CFG after constant_propagation" !cfg_run_after_cp eval_cfgprog cfg;
+        pass_dead_assign_elimination cfg >>= fun cfg ->
+        run "CFG after dead_assign_elimination" !cfg_run_after_dae eval_cfgprog cfg;
+        pass_nop_elimination cfg >>= fun cfg ->
+        run "CFG after nop_elimination" !cfg_run_after_ne eval_cfgprog cfg;
+        pass_rtl_gen cfg >>= fun rtl ->
+        run "RTL" !rtl_run exec_rtl_prog rtl;
+        pass_linearize rtl >>= fun (linear, lives) ->
+        run "Linear" !linear_run exec_linear_prog linear;
+        pass_linear_dse linear lives >>= fun linear ->
+        run "Linear after DSE" !linear_run_after_dse exec_linear_prog linear;
+        pass_ltl_gen linear
+      in
+      begin
+        match compiler_res with
+        | Error msg -> ()
+        | OK ltl ->
+          run "LTL" !ltl_run (exec_ltl_prog) ltl;
+          (if !ltl_debug then debug_ltl_prog input ltl !heapsize !params);
+          dump !riscv_dump (dump_riscv_prog !Archi.target) ltl (fun file () ->
+              add_to_report "riscv" "RISC-V" (Code (file_contents file));
+              ignore (compile_rv basename file ()));
+          if not !Options.nostart then begin
+            run "Risc-V" !riscv_run (exec_rv_prog ltl basename) !riscv_dump
+          end
+      end;
       dump (Some !output_json) (fun oc p ->
           Format.fprintf oc "%s\n" p
-        ) json_output_string (fun _ () -> ());
+        ) (json_output_string ()) (fun _ () -> ());
       make_report input report ()
diff --git a/src/options.ml b/src/options.ml
index b6bdd51360827630c4e5ca2f18a02186ac4bef2f..1c0772e2985065c16d018eacab623a88eb3439c5 100644
--- a/src/options.ml
+++ b/src/options.ml
@@ -30,6 +30,10 @@ let nostats = ref false
 let has_mul = ref true
 let no_dump = ref false
 let no_dot = ref false
+let no_cfg_constprop = ref false
+let no_cfg_dae = ref false
+let no_cfg_ne = ref false
+let no_linear_dse = ref false
 
 let alloc_order_st = ref true
 let naive_regalloc = ref true
diff --git a/src/parser.ml b/src/parser.ml
index 12a2a612370ccf93cad7214497156be05f1c90c2..8f0a0bae497d6afb406f5cdf744b04801ee44dcb 100644
--- a/src/parser.ml
+++ b/src/parser.ml
@@ -1,3 +1,16 @@
 open Generated_parser
+open Report
+open Utils
+open Options
+open Ast
 
 let parse = parse_S
+
+let pass_parse tokens =
+  match parse tokens () with
+  | Error msg -> record_compile_result ~error:(Some msg) "Parsing"; Error msg
+  | OK (ast, tokens) ->
+    record_compile_result "Parsing";
+    dump !ast_tree draw_ast_tree ast (call_dot "ast" "AST");
+    if !ast_dump then Format.printf "%s\n" (string_of_ast ast) else ();
+    OK (ast, tokens)
diff --git a/src/prog.ml b/src/prog.ml
index 99b33608a8101c34a92cefb93a105ed21aa71e8a..ffe49805f8df8110f0786f8950f80bc6fd99bdfc 100644
--- a/src/prog.ml
+++ b/src/prog.ml
@@ -1,5 +1,37 @@
 open Utils
 
+
+type mem_access_size =
+  | MAS1
+  | MAS4
+  | MAS8
+
+let string_of_mem_access_size mas =
+  match mas with
+  | MAS1 -> "{1}"
+  | MAS4 -> "{4}"
+  | MAS8 -> "{8}"
+
+let mas_of_size n =
+  match n with
+  | 1 -> OK MAS1
+  | 4 -> OK MAS4
+  | 8 -> OK MAS8
+  | _ -> Error (Printf.sprintf "Unknown memory access size for size = %d" n)
+
+
+let size_of_mas mas =
+  match mas with
+  | MAS1 -> 1
+  | MAS4 -> 4
+  | MAS8 -> 8
+
+let archi_mas () =
+  match !Archi.archi with
+  | A64 -> MAS8
+  | A32 -> MAS4
+
+
 type 'a gdef = Gfun of 'a
 
 type 'a prog = (string * 'a gdef) list
diff --git a/src/report.ml b/src/report.ml
index b60bb9c5a854c1b56c1ae7bba4906d8c5cb27730..94d927de878c060bb77cd7dfcb308de09e913dd9 100644
--- a/src/report.ml
+++ b/src/report.ml
@@ -1,3 +1,5 @@
+open Options
+open Utils
 
 type html_node =
   | Img of string
@@ -45,3 +47,88 @@ let call_dot report_sectid report_secttitle file () : unit =
     add_to_report report_sectid report_secttitle (Img (Filename.basename file^".svg"));
     ignore r
   end
+
+(*  *)
+
+
+type run_result = {
+  step: string;
+  retval: int option;
+  output: string;
+  error: string option;
+  time: float;
+}
+
+type compile_result = {
+  step: string;
+  error: string option;
+  data: Yojson.t
+}
+
+type result = RunRes of run_result
+            | CompRes of compile_result
+
+
+let results : result list ref = ref []
+
+
+let record_compile_result ?error:(error=None) ?data:(data=[]) step =
+  let data = if not !Options.nostats then `List data else `Null in
+  results := !results @ [CompRes { step; error; data}]
+
+
+let run step flag eval p =
+  if flag then begin
+    let starttime = Unix.gettimeofday () in
+    let res = match eval Format.str_formatter p !heapsize !params with
+      | exception e ->
+        Error (Printexc.to_string e)
+      | e -> e in
+    let timerun = Unix.gettimeofday () -. starttime in
+    let output = Format.flush_str_formatter () in
+    let rres = { step ; retval = None; output; error = None; time = timerun} in
+    let rres =
+    begin match res with
+      | OK v ->  { rres with retval = v }
+      | Error msg -> { rres with error = Some msg }
+    end in
+    results := !results @ [RunRes rres];
+    add_to_report step ("Run " ^ step) (
+      Paragraph
+        (
+          Printf.sprintf "With parameters : [%s]<br>\n" (String.concat"," (List.map string_of_int !params))
+          ^ Printf.sprintf "Mem size : %d bytes<br>\n" !heapsize
+          ^ Printf.sprintf "Return value : %s<br>\n" (match rres.retval with | Some v -> string_of_int v | _ -> "none")
+          ^ Printf.sprintf "Output : <pre style=\"padding: 1em; background-color: #ccc;\">%s</pre>\n" output
+          ^
+          (match rres.error with
+           | Some msg -> Printf.sprintf "Error : <pre style=\"padding: 1em; background-color: #fcc;\">\n%s</pre>\n" msg
+           | _ -> "")
+          ^ Printf.sprintf "Time : %f seconds<br>\n" timerun
+        )
+    )
+  end
+
+
+let json_output_string () =
+  let open Yojson in
+  let jstring_of_ostring o =
+    match o with
+    | None -> `Null
+    | Some s -> `String s
+  in
+  let j = `List (List.map (function
+      | RunRes { step; retval; output; error; time } ->
+        `Assoc [("runstep",`String step);
+                ("retval", match retval with Some r -> `Int r | None -> `Null);
+                ("output", `String output);
+                ("error", jstring_of_ostring error);
+                ("time", `Float time)
+               ]
+      | CompRes { step; error; data } ->
+        `Assoc [("compstep",`String step);
+                ("error", jstring_of_ostring error);
+                ("data", data)
+               ]
+    ) !results) in
+  (Yojson.pretty_to_string j)
diff --git a/src/riscv.ml b/src/riscv.ml
index 9c6402b8330dd0d2e0a96cdcef04c198d312a764..c38276f44b0a8dea9de009f1daf0af7dccaebd35 100644
--- a/src/riscv.ml
+++ b/src/riscv.ml
@@ -7,6 +7,7 @@ open Ltl_print
 open Utils
 open Prog
 open Options
+open Archi
 
 (* This file performs the translation from LTL programs to RISC-V assembly
    programs. The languages are basically the same, so the only thing to do here
@@ -45,166 +46,126 @@ let print_binop (b: binop) =
   | Elang.Exor -> "xor"
   | Elang.Ediv -> "divu"
   | Elang.Esub -> "sub"
-  | _ -> assert false
+  | _ -> failwith "Unexpected binop"
 
 let print_unop (u: unop) =
   match u with
   | Elang.Eneg -> "neg"
 
 let instrsuffix_of_size sz =
-  match !Archi.archi, sz with
-  | _, 1 -> OK 'b'
-  | _, 4 -> OK 'w'
-  | A64, 8 -> OK 'd'
-  | _, _ ->
-    Error (Format.sprintf "Impossible write size (%d) in archi (%d)"
-                sz !Archi.nbits)
+  match sz with
+  | MAS1 -> 'b'
+  | MAS4 -> 'w'
+  | MAS8 -> 'd'
 
 let dump_riscv_instr oc (i: ltl_instr) =
   match i with
   | LAddi(rd, rs, i) ->
-    Format.fprintf oc "addi %s, %s, %d\n" (print_reg rd) (print_reg rs) i;
-    OK ()
+    Format.fprintf oc "addi %s, %s, %d\n" (print_reg rd) (print_reg rs) i
   | LSubi(rd, rs, i) ->
-    Format.fprintf oc "addi %s, %s, %d\n" (print_reg rd) (print_reg rs) (-i);
-    OK ()
+    Format.fprintf oc "addi %s, %s, %d\n" (print_reg rd) (print_reg rs) (-i)
   | LBinop(b, rd, rs1, rs2) ->
     begin match b with
-      | Elang.Eclt ->
+     | Elang.Eclt ->
         Format.fprintf oc "slt %s, %s, %s\n"
-          (print_reg rd) (print_reg rs1) (print_reg rs2);
-        OK ()
+          (print_reg rd) (print_reg rs1) (print_reg rs2)
       | Elang.Ecgt ->
         Format.fprintf oc "slt %s, %s, %s\n"
-          (print_reg rd) (print_reg rs2) (print_reg rs1);
-        OK ()
+          (print_reg rd) (print_reg rs2) (print_reg rs1)
       | Elang.Ecle ->
-        (* 'rd <- rs1 <= rs2' == 'rd <- rs2 < rs1; rd <- not rd' *)
+        (* 'rd <- rs1 <= rs2' == 'rd <- rs2 < rs1; rd <- seqz rd' *)
         Format.fprintf oc "slt %s, %s, %s\n"
           (print_reg rd) (print_reg rs2) (print_reg rs1);
         Format.fprintf oc "seqz %s, %s\n"
-          (print_reg rd) (print_reg rd);
-        OK ()
+          (print_reg rd) (print_reg rd)
       | Elang.Ecge ->
         Format.fprintf oc "slt %s, %s, %s\n"
           (print_reg rd) (print_reg rs1) (print_reg rs2);
         Format.fprintf oc "seqz %s, %s\n"
-          (print_reg rd) (print_reg rd);
-        OK ()
+          (print_reg rd) (print_reg rd)
       | Elang.Eceq ->
         Format.fprintf oc "sub %s, %s, %s\n"
           (print_reg rd) (print_reg rs1) (print_reg rs2);
         Format.fprintf oc "seqz %s, %s\n"
-          (print_reg rd) (print_reg rd);
-        OK ()
+          (print_reg rd) (print_reg rd)
       | Elang.Ecne ->
         Format.fprintf oc "sub %s, %s, %s\n"
           (print_reg rd) (print_reg rs1) (print_reg rs2);
         Format.fprintf oc "snez %s, %s\n"
-          (print_reg rd) (print_reg rd);
-        OK ()
+          (print_reg rd) (print_reg rd)
       | _ -> Format.fprintf oc "%s %s, %s, %s\n"
-               (print_binop b) (print_reg rd) (print_reg rs1) (print_reg rs2);
-        OK ()
+               (print_binop b) (print_reg rd) (print_reg rs1) (print_reg rs2)
     end
   | LUnop(u, rd, rs) ->
     Format.fprintf oc "%s %s, %s\n"
-          (print_unop u) (print_reg rd) (print_reg rs); OK ()
+          (print_unop u) (print_reg rd) (print_reg rs)
   | LStore(rt, i, rs, sz) ->
-    (instrsuffix_of_size sz) >>= fun sz ->
-    OK (Format.fprintf oc "s%c %s, %d(%s)\n"
-          sz (print_reg rs) i (print_reg rt))
+    let sz = instrsuffix_of_size sz in
+    Format.fprintf oc "s%c %s, %d(%s)\n"
+          sz (print_reg rs) i (print_reg rt)
   | LLoad(rd, rt, i, sz) ->
-    (instrsuffix_of_size sz) >>= fun sz ->
+    let sz = (instrsuffix_of_size sz) in
     Format.fprintf oc "l%c %s, %d(%s)\n"
-      sz (print_reg rd) i (print_reg rt); OK ()
+      sz (print_reg rd) i (print_reg rt)
   | LMov(rd, rs) ->
-    Format.fprintf oc "mv %s, %s\n" (print_reg rd) (print_reg rs);
-    OK ()
+    Format.fprintf oc "mv %s, %s\n" (print_reg rd) (print_reg rs)
   | LLabel l ->
-    Format.fprintf oc "%s:\n" l;
-    OK ()
-  | LJmp l -> Format.fprintf oc "j %s\n" l;
-    OK ()
-  | LJmpr r -> Format.fprintf oc "jr %s\n" (print_reg r);
-    OK ()
-  | LConst (rd, i) -> Format.fprintf oc "li %s, %d\n\n" (print_reg rd) i;
-    OK ()
-  | LComment l -> Format.fprintf oc "# %s\n" l;
-    OK ()
+    Format.fprintf oc "%s:\n" l
+  | LJmp l -> Format.fprintf oc "j %s\n" l
+  | LJmpr r -> Format.fprintf oc "jr %s\n" (print_reg r)
+  | LConst (rd, i) -> Format.fprintf oc "li %s, %d\n\n" (print_reg rd) i
+  | LComment l -> Format.fprintf oc "# %s\n" l
   | LBranch(cmp, rs1, rs2, s) ->
     Format.fprintf oc "%s %s, %s, %s\n"
-      (riscv_of_cmp cmp) (print_reg rs1) (print_reg rs2) s;
-    OK ()
+      (riscv_of_cmp cmp) (print_reg rs1) (print_reg rs2) s
   | LCall fname ->
-    Format.fprintf oc "jal ra, %s\n" fname;
-    OK ()
-  | LHalt -> Format.fprintf oc "halt\n";
-    OK ()
+    Format.fprintf oc "jal ra, %s\n" fname
+  | LHalt -> Format.fprintf oc "halt\n"
 
 let dump_riscv_fun oc (fname , lf) =
   Format.fprintf oc "%s:\n" fname;
-  list_iter_res (dump_riscv_instr oc) lf.ltlfunbody
-
-let riscv_load_args oc : unit res =
-  let nargs = [1;2;3;4;5;6;7;8] in
-  (* for each arg in [1..8]:
-       a0 <- arg
-       call load_int_arg
-       call atoi
-       sd a0, -8*arg(fp)
-  *)
-  let l1 = (nargs |>
-           List.map (fun i ->
-               [LConst(reg_a0, i);
-                LCall("load_int_arg");
-                LBranch(Rceq, reg_a0, reg_zero, Printf.sprintf "riscv_load_arg_end");
-                LCall("atoi");
-                LStore(reg_fp, - !Archi.wordsize*i,
-                       reg_a0, !Archi.wordsize);
-               ]))
-           @
-      [[LLabel(Printf.sprintf "riscv_load_arg_end")]]
-  in
-  (* for each arg in [1..8]
-     ld a{arg-1}, -8*arg(fp)
-  *)
-  let l2 = nargs |>
-           List.map (fun i ->
-               [LLoad(starting_arg_register + i - 1, reg_fp,
-                      - !Archi.wordsize*i, !Archi.wordsize)]) in
-  (l1 @ l2) |> List.concat |> list_iter_res (fun i -> dump_riscv_instr oc i)
-
-
-let riscv_fun_load_arg oc () =
-  ("load_int_arg",{
-      ltlfunargs = 0;
-      (*
-
-         *( fp + a0 * wordsize + 8)
-
-         t0 <- Archi.wordsize (in this example 8)
-         mul a0, a0, t0
-         add t0, fp, a0
-         ld a0, 8(t0)
-         jmpr ra
-      *)
-      ltlfunbody = [LConst(reg_t0, !Archi.wordsize);
-                    LBinop(Emul, reg_ret, reg_ret, reg_t0);
-                    LBinop(Eadd, reg_t0, reg_fp, reg_ret);
-                    LLoad(reg_ret, reg_t0, !Archi.wordsize, !Archi.wordsize);
-                    LJmpr reg_ra
-                   ];
-      ltlfuninfo = [];
-      ltlregalloc = []
-    }) |> dump_riscv_fun oc
+  List.iter (dump_riscv_instr oc) lf.ltlfunbody
+
+let riscv_load_args target oc : unit =
+  (match target with
+   | Linux -> LLoad(reg_s1, reg_sp, 0, archi_mas ()) :: (* s1 <- argc *)
+              LAddi(reg_s2, reg_sp, (Archi.wordsize ())) :: []
+   | Xv6 -> LMov(reg_s1, reg_a0) ::
+            LMov(reg_s2, reg_a1) :: []) @
+  LConst(reg_s3, 1) ::
+  LSubi(reg_sp, reg_sp, 72) ::
+  LLabel "Lloop" ::
+  LBranch(Rceq, reg_s3, reg_s1, "Lendargs") ::
+  LMov(reg_a0, reg_t4) ::
+  LAddi(reg_s4, reg_s3, 0) ::
+  LConst(reg_t1, (Archi.wordsize ())) ::
+  LBinop(Emul, reg_s4, reg_s4, reg_t1) ::
+  LBinop(Eadd, reg_t3, reg_s4, reg_s2) ::
+  LLoad(reg_a0, reg_t3, 0, archi_mas ()) ::
+  LCall "atoi" ::
+  LBinop(Esub, reg_s4, reg_fp, reg_s4) ::
+  LStore(reg_s4, 0, reg_a0, archi_mas ()) ::
+  LAddi(reg_s3, reg_s3, 1) ::
+  LJmp "Lloop" ::
+  LLabel "Lendargs" ::
+  LLoad(reg_a0, reg_fp, -8, archi_mas ()) ::
+  LLoad(reg_a1, reg_fp, -16, archi_mas ()) ::
+  LLoad(reg_a2, reg_fp, -24, archi_mas ()) ::
+  LLoad(reg_a3, reg_fp, -32, archi_mas ()) ::
+  LLoad(reg_a4, reg_fp, -40, archi_mas ()) ::
+  LLoad(reg_a5, reg_fp, -48, archi_mas ()) ::
+  LLoad(reg_a6, reg_fp, -56, archi_mas ()) ::
+  LLoad(reg_a7, reg_fp, -64, archi_mas ()) ::
+  [] |>
+  List.iter (dump_riscv_instr oc)
 
 let rv_store () =
-  Format.sprintf "s%c" !Archi.instrsuffix
+  Format.sprintf "s%c" (Archi.instrsuffix ())
 let rv_load () =
-  Format.sprintf "l%c" !Archi.instrsuffix
+  Format.sprintf "l%c" (Archi.instrsuffix ())
 
-let riscv_prelude oc =
+let riscv_prelude target oc =
+  Format.fprintf oc ".include \"syscall_numbers.s\"\n";
   Format.fprintf oc ".globl _start\n";
   Format.fprintf oc "_start:\n";
   Format.fprintf oc "  lui gp, %%hi(_heap_start)\n";
@@ -212,22 +173,19 @@ let riscv_prelude oc =
   Format.fprintf oc "  addi t0, gp, 8\n";
   Format.fprintf oc "  %s t0, 0(gp)\n" (rv_store ());
   Format.fprintf oc "  mv s0, sp\n";
-  Format.fprintf oc "  add sp, sp, -72\n";
-  riscv_load_args oc >>= fun _ -> 
+  riscv_load_args target oc ;
   Format.fprintf oc "jal ra, main\n";
   Format.fprintf oc "mv s0, a0\n";
   Format.fprintf oc "jal ra, println\n";
   Format.fprintf oc "mv a0, s0\n";
   Format.fprintf oc "jal ra, print_int\n";
   Format.fprintf oc "jal ra, println\n";
-  Format.fprintf oc "addi a7, zero, 93\n";
-  Format.fprintf oc "ecall\n";
-  OK ()
+  Format.fprintf oc "addi a7, zero, SYSCALL_EXIT\n";
+  Format.fprintf oc "ecall\n"
 
-let dump_riscv_prog oc lp : unit res =
-  (if !nostart then OK () else riscv_prelude oc) >>= fun _ ->
+let dump_riscv_prog target oc lp : unit =
+  (if !nostart then () else riscv_prelude target oc);
   Format.fprintf oc ".global main\n";
-  list_iter_res (function
+  List.iter (function
         (fname, Gfun f) -> dump_riscv_fun oc (fname,f)
-    ) lp >>= fun _ ->
-  riscv_fun_load_arg oc ()
+    ) lp
diff --git a/src/rtl_gen.ml b/src/rtl_gen.ml
index e9b62e058e82d8483fd940ed88e0f01944d63142..ce1eb8f84ef214052bb074b76658d460ac7045df 100644
--- a/src/rtl_gen.ml
+++ b/src/rtl_gen.ml
@@ -4,6 +4,9 @@ open Cfg
 open Rtl
 open Prog
 open Utils
+open Report
+open Rtl_print
+open Options
 
 (* Une partie de la génération de RTL consiste à allouer les variables dans des
    pseudo-registres RTL.
@@ -89,3 +92,9 @@ let rtl_of_gdef funname = function
     Gfun f -> Gfun (rtl_instrs_of_cfg_fun funname f)
 
 let rtl_of_cfg cp = List.map (fun (s, gd) -> (s, rtl_of_gdef s gd)) cp
+
+let pass_rtl_gen cfg =
+  let rtl = rtl_of_cfg cfg in
+  dump !rtl_dump dump_rtl_prog rtl
+    (fun file () -> add_to_report "rtl" "RTL" (Code (file_contents file)));
+  OK rtl
diff --git a/src/test_lexer.ml b/src/test_lexer.ml
index fa64acc93c566c2c6e2ff5af64b251d973dc4d8c..6e3adc92fd7602379603b4289325afde92c331f8 100644
--- a/src/test_lexer.ml
+++ b/src/test_lexer.ml
@@ -8,6 +8,10 @@ let () =
   let regexp_list = [
     (keyword_regexp "while",    fun s -> Some (SYM_WHILE));
     (keyword_regexp "if",    fun s -> Some (SYM_IF));
+    (Cat(letter_regexp,
+         Star(identifier_material)),
+     fun s -> Some (SYM_IDENTIFIER s));
+
   ] in
   (* Décommentez la ligne suivante pour tester sur la vraie liste d'expressions
      régulières. *)
@@ -29,4 +33,82 @@ let () =
   dfa_to_dot oc dfa alphabet;
   close_out oc;
 
+  let n =
+    {
+      nfa_states = [1; 2; 3; 4] ;
+      nfa_initial = [1] ;
+      nfa_final = [(3, fun s -> None); (4, fun s -> None)];
+      nfa_step = fun q ->
+        match q with
+        | 1 -> [(Some (Set.singleton '0'), 2); (None, 3)]
+        | 2 -> [(Some (Set.singleton '1'), 2); (Some (Set.singleton '1'), 4)]
+        | 3 -> [(Some (Set.singleton '0'), 4); (None, 2)]
+        | 4 -> [(Some (Set.singleton '0'), 2)]
+        | _ -> []
+
+    } in
+
+  let expect_set str s_got s_exp =
+    if Set.equal s_got s_exp
+    then Printf.printf "[OK] %s\n" str
+    else Printf.printf "[KO] %s : got %s, expected %s\n" str (string_of_int_set s_got)
+        (string_of_int_set s_exp) in
+
+  let ec1 = epsilon_closure n 1 in
+  let ec2 = epsilon_closure n 2 in
+  let ec3 = epsilon_closure n 3 in
+  let ec4 = epsilon_closure n 4 in
+
+  expect_set "epsilon_closure 1" ec1 (Set.of_list [1;2;3]);
+  expect_set "epsilon_closure 2" ec2 (Set.of_list [2]);
+  expect_set "epsilon_closure 3" ec3 (Set.of_list [2;3]);
+  expect_set "epsilon_closure 4" ec4 (Set.of_list [4]);
+
+  expect_set "dfa_initial_state" (dfa_initial_state n) (Set.of_list [1;2;3]);
+
+  let string_of_opt_tok ot =
+    match ot with
+      None -> "None"
+    | Some t -> Printf.sprintf "Some (%s)" (string_of_symbol t)
+  in
+
+  let expect_token_option str to_got to_exp =
+    if to_got = to_exp
+    then Printf.printf "[OK] %s\n" str
+    else Printf.printf "[KO] %s : got %s, expected %s\n" str (string_of_opt_tok to_got)
+        (string_of_opt_tok to_exp)
+  in
+
+  expect_token_option "min_priority 1" (min_priority [SYM_EOF; SYM_IDENTIFIER "bla"; SYM_WHILE]) (Some SYM_WHILE);
+  expect_token_option "min_priority 2" (min_priority [SYM_EOF; SYM_IDENTIFIER "bla"]) (Some (SYM_IDENTIFIER "bla"));
+  expect_token_option "min_priority 3" (min_priority [SYM_EOF; SYM_WHILE]) (Some SYM_WHILE);
+
+  expect_token_option "min_priority 4" (min_priority []) None;
+
+  let set_incl s1 s2 =
+    Set.for_all (fun s -> Set.exists (Set.equal s) s2) s1
+  in
+
+  let set_eq s1 s2 = set_incl s1 s2 && set_incl s2 s1 in
+
+  let string_of_int_set_set s =
+    Set.map (fun s ->
+        Printf.sprintf "{%s}" (String.concat "," (Set.to_list (Set.map string_of_int s)))
+      ) s
+    |> Set.to_list
+    |> String.concat ", "
+    |> Printf.sprintf "{%s}"
+  in
+
+  let expect_set_set str (set_got : int set set) (set_exp : int set set) =
+    if set_eq set_got set_exp
+    then Printf.printf "[OK] %s\n" str
+    else Printf.printf "[KO] %s : got %s, expected %s\n" str
+        (string_of_int_set_set set_got)
+        (string_of_int_set_set set_exp)
+  in
+
+  let table = Hashtbl.create 10 in
+  build_dfa_table table n (dfa_initial_state n);
+  expect_set_set "dfa states" (Hashtbl.keys table |> Set.of_enum) (Set.of_list [Set.of_list [1;2;3]; Set.of_list [2;4]; Set.of_list [2]])
 
diff --git a/src/tokenize.ml b/src/tokenize.ml
new file mode 100644
index 0000000000000000000000000000000000000000..8a1443915ca061f670dd996f081513bcd1264270
--- /dev/null
+++ b/src/tokenize.ml
@@ -0,0 +1,23 @@
+open Batteries
+open Lexer_generator
+open Report
+open Utils
+open Options
+open Symbols
+
+let tokenize file =
+  Lexer_generator.tokenize_file file >>= fun tokens ->
+  OK (List.map (fun tok -> (tok, None)) tokens)
+
+
+let pass_tokenize file =
+  tokenize file >>* (fun msg ->
+      record_compile_result ~error:(Some msg) "Lexing";
+      Error msg
+    ) $ fun tokens ->
+      record_compile_result "Lexing";
+      dump !show_tokens (fun oc tokens ->
+          List.iter (fun (tok,_) ->
+              Format.fprintf oc "%s\n" (string_of_symbol tok)
+            ) tokens) tokens (fun f () -> add_to_report "lexer" "Lexer" (Code (file_contents f)));
+      OK tokens
diff --git a/src/utils.ml b/src/utils.ml
index a954803ef76c3a4cda29afb42341e73d93a058df..aec74d5ff09c3737afc1d35d4617625c553e9873 100644
--- a/src/utils.ml
+++ b/src/utils.ml
@@ -113,7 +113,7 @@ let read_mem_bytes_as_int mem addr n =
 
 
 let read_mem_int mem addr =
-  read_mem_bytes_as_int mem addr !Archi.wordsize
+  read_mem_bytes_as_int mem addr (Archi.wordsize ())
 
 let read_mem_char mem addr =
   read_mem_bytes mem addr 1 >>= fun bl ->
@@ -318,3 +318,33 @@ let dump file (dumpf : _ -> 'a -> unit) (p: 'a) (additional_command: string -> u
       dumpf oc p; close ();
       if file <> "-" then additional_command file ()
   end
+
+
+let process_output_to_list2 = fun command ->
+  let chan = Unix.open_process_in command in
+  let res = ref ([] : string list) in
+  let rec process_otl_aux () =
+    let e = input_line chan in
+    res := e::!res;
+    process_otl_aux() in
+  try process_otl_aux ()
+  with End_of_file ->
+    let stat = Unix.close_process_in chan in (List.rev !res,stat)
+
+let cmd_to_list command =
+  let (l,_) = process_output_to_list2 command in l
+
+let file_contents file =
+  match
+    let ic = open_in file in
+    let rec aux s () =
+      try
+        let line = input_line ic in  (* read line from in_channel and discard \n *)
+        aux (s ^ line ^ "\n") ()   (* close the input channel *)
+      with e ->                      (* some unexpected exception occurs *)
+        close_in_noerr ic;           (* emergency closing *)
+        s in
+    aux "" ()
+  with
+  | exception Sys_error _ -> failwith (Printf.sprintf "Could not open file %s\n" file)
+  | x -> x
diff --git a/tests/Makefile b/tests/Makefile
index d6b84292ea9b87d1a73d77bdf767a9afb263d2b0..78c3657f7a434bd91dd0b8d0d4c4a55edfd59f09 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,14 +1,20 @@
 # if make is launched with a DIR variable, pass it as the -f option to test.py
 # 'make DIR=basic/mul*.e' launches all the files starting with mul in the basic directory
 # otherwise, use basic/*.e as a default
-FILES := $(if $(DIR),-f $(DIR),-f basic/*.e)
+FILES := $(if $(DIR),$(DIR),basic/*.e)
 
 OPTS := $(if $(OPTS), $(OPTS),)
 
 .PHONY: all
 all: ../main.native
-	./test.py $(FILES) $(OPTS)
+	./test.py -f $(FILES) $(OPTS)
+
+expect: ../main.native
+	OCAMLRUNPARAM=b ./test.py --make-expect -f $(FILES) $(OPTS) --args 1 2 3
+	OCAMLRUNPARAM=b ./test.py --make-expect -f $(FILES) $(OPTS) --args 14 12 3 8 12
+	for f in $(FILES); do ../main.native -f $$f -show-tokens $$f.expect_lexer; done
+
 
 clean:
-	find . -name '*.ltl' -or -name '*.cfg' -or -name '*.exe' -or -name '*.s' -or -name '*.rtl' -or -name '*.ast' -or -name '*.cfg0' -or -name '*.cfg1' -or -name '*.cfg2' -or -name '*.cfg3' -or -name '*.riscv' -or -name '*.dump' -or	-name '*.linear1' -or -name '*.linear' -or -name '*.html' -or -name '*.svg'	-or -name '*.html' -or -name '*.lex' -or -name "*.json" | xargs -I{} rm {}
+	find . -name '*.rig' -or -name '*.ltl' -or -name '*.cfg' -or -name '*.exe' -or -name '*.s' -or -name '*.rtl' -or -name '*.ast' -or -name '*.cfg0' -or -name '*.cfg1' -or -name '*.cfg2' -or -name '*.cfg3' -or -name '*.riscv' -or -name '*.dump' -or	-name '*.linear1' -or -name '*.linear' -or -name '*.html' -or -name '*.svg'	-or -name '*.html' -or -name '*.lex' -or -name "*.json" | xargs -I{} rm {}
 	rm -rf __pycache__
diff --git a/tests/funcall/argswap.e.expect_lexer b/tests/funcall/argswap.e.expect_lexer
index 89b98c324fdb2b227f987c44d6cd1bba0c75859d..2c8a87dc1d273f5d6156be905b62504276797c7b 100644
--- a/tests/funcall/argswap.e.expect_lexer
+++ b/tests/funcall/argswap.e.expect_lexer
@@ -5,12 +5,12 @@ SYM_COMMA
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
 SYM_LBRACE
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
@@ -30,12 +30,12 @@ SYM_COMMA
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
 SYM_LBRACE
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
diff --git a/tests/funcall/print_and_fun.e.expect_lexer b/tests/funcall/print_and_fun.e.expect_lexer
index d8e49347bfd160352797416d6be13177edbc3ee4..834218f66d791aed054dec525bb4e0e33596260b 100644
--- a/tests/funcall/print_and_fun.e.expect_lexer
+++ b/tests/funcall/print_and_fun.e.expect_lexer
@@ -21,12 +21,12 @@ SYM_LPARENTHESIS
 SYM_INTEGER(8)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(a)
 SYM_RPARENTHESIS
 SYM_SEMICOLON
-SYM_PRINT
+SYM_IDENTIFIER(print)
 SYM_LPARENTHESIS
 SYM_IDENTIFIER(b)
 SYM_RPARENTHESIS
diff --git a/tests/globals/arrayptr.e b/tests/globals/arrayptr.e
new file mode 100644
index 0000000000000000000000000000000000000000..e5d1b0d96515e4114a4edb031df15643097ca15e
--- /dev/null
+++ b/tests/globals/arrayptr.e
@@ -0,0 +1,24 @@
+struct S {
+  int x;
+  int y;
+  int z;
+};
+
+struct S *p;
+
+struct S t[3];
+
+int main(){
+  (t[0]).x = 1;
+  (t[0]).y = 2;
+  (t[0]).z = 3;
+  (t[1]).x = 4;
+  (t[1]).y = 5;
+  (t[1]).z = 6;
+  (t[2]).x = 7;
+  (t[2]).y = 8;
+  (t[2]).z = 9;
+  p = &(t[2]);
+
+  return (*p).y;
+}
diff --git a/tests/globals/arrayptr.e.expect_14_12_3_8_12 b/tests/globals/arrayptr.e.expect_14_12_3_8_12
new file mode 100644
index 0000000000000000000000000000000000000000..61b83a85dd0aeeb0ff59aaeb795875114625cdf7
--- /dev/null
+++ b/tests/globals/arrayptr.e.expect_14_12_3_8_12
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": 8}
\ No newline at end of file
diff --git a/tests/globals/arrayptr.e.expect_1_2_3 b/tests/globals/arrayptr.e.expect_1_2_3
new file mode 100644
index 0000000000000000000000000000000000000000..61b83a85dd0aeeb0ff59aaeb795875114625cdf7
--- /dev/null
+++ b/tests/globals/arrayptr.e.expect_1_2_3
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": 8}
\ No newline at end of file
diff --git a/tests/globals/arrayptr.e.expect_lexer b/tests/globals/arrayptr.e.expect_lexer
new file mode 100644
index 0000000000000000000000000000000000000000..1c2e857c384ad3c3582f64a43a9a94110e617de6
--- /dev/null
+++ b/tests/globals/arrayptr.e.expect_lexer
@@ -0,0 +1,150 @@
+SYM_STRUCT
+SYM_IDENTIFIER(S)
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(x)
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(y)
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(z)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_SEMICOLON
+SYM_STRUCT
+SYM_IDENTIFIER(S)
+SYM_ASTERISK
+SYM_IDENTIFIER(p)
+SYM_SEMICOLON
+SYM_STRUCT
+SYM_IDENTIFIER(S)
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(3)
+SYM_RBRACKET
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(main)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(x)
+SYM_ASSIGN
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(y)
+SYM_ASSIGN
+SYM_INTEGER(2)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(z)
+SYM_ASSIGN
+SYM_INTEGER(3)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(1)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(x)
+SYM_ASSIGN
+SYM_INTEGER(4)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(1)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(y)
+SYM_ASSIGN
+SYM_INTEGER(5)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(1)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(z)
+SYM_ASSIGN
+SYM_INTEGER(6)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(2)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(x)
+SYM_ASSIGN
+SYM_INTEGER(7)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(2)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(y)
+SYM_ASSIGN
+SYM_INTEGER(8)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(2)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(z)
+SYM_ASSIGN
+SYM_INTEGER(9)
+SYM_SEMICOLON
+SYM_IDENTIFIER(p)
+SYM_ASSIGN
+SYM_AMPERSAND
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(2)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RETURN
+SYM_LPARENTHESIS
+SYM_ASTERISK
+SYM_IDENTIFIER(p)
+SYM_RPARENTHESIS
+SYM_POINT
+SYM_IDENTIFIER(y)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_EOF
diff --git a/tests/globals/globtab2.e b/tests/globals/globtab2.e
new file mode 100644
index 0000000000000000000000000000000000000000..c60b2cb694fca94bf9f89bcc26daebd145f92fd1
--- /dev/null
+++ b/tests/globals/globtab2.e
@@ -0,0 +1,43 @@
+int IMG[64];
+int NBCOL = 8;
+int NBROW = 8;
+
+void draw(int color, int x, int y){
+  int pos = (y * NBCOL + x);
+  if (pos < NBCOL * NBROW){
+	  *(IMG + pos) = color;
+  }
+}
+
+int get(int x, int y){
+  int pos = (y * NBCOL + x);
+  if (pos < NBCOL * NBROW){
+    return *(IMG + pos);
+  }
+  return -1;
+}
+
+void draw_world(){
+  int i = 0;
+  int j = 0;
+  while (j < NBROW) {
+    i = 0;
+    while (i < NBCOL) {
+      if(get(i, j) != 0){
+        print_char('#');
+      } else {
+        print_char(' ');
+      }
+      i = i + 1;
+    }
+    print_char('\n');
+    j = j + 1;
+  }
+}
+
+int main(){
+  draw(0xff0000, 1, 1);
+  print(get(1,1));
+  draw_world();
+  return 0;
+}
diff --git a/tests/globals/globtab2.e.expect_14_12_3_8_12 b/tests/globals/globtab2.e.expect_14_12_3_8_12
new file mode 100644
index 0000000000000000000000000000000000000000..b09bb6fba8ce6c934aecda5bb182415bced685ed
--- /dev/null
+++ b/tests/globals/globtab2.e.expect_14_12_3_8_12
@@ -0,0 +1 @@
+{"output": "16711680\n        \n #      \n        \n        \n        \n        \n        \n        \n", "error": null, "retval": 0}
\ No newline at end of file
diff --git a/tests/globals/globtab2.e.expect_1_2_3 b/tests/globals/globtab2.e.expect_1_2_3
new file mode 100644
index 0000000000000000000000000000000000000000..b09bb6fba8ce6c934aecda5bb182415bced685ed
--- /dev/null
+++ b/tests/globals/globtab2.e.expect_1_2_3
@@ -0,0 +1 @@
+{"output": "16711680\n        \n #      \n        \n        \n        \n        \n        \n        \n", "error": null, "retval": 0}
\ No newline at end of file
diff --git a/tests/globals/globtab2.e.expect_lexer b/tests/globals/globtab2.e.expect_lexer
new file mode 100644
index 0000000000000000000000000000000000000000..c92540d9f191142eb924c6a1c74e1f898cb2098d
--- /dev/null
+++ b/tests/globals/globtab2.e.expect_lexer
@@ -0,0 +1,217 @@
+SYM_INT
+SYM_IDENTIFIER(IMG)
+SYM_LBRACKET
+SYM_INTEGER(64)
+SYM_RBRACKET
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(NBCOL)
+SYM_ASSIGN
+SYM_INTEGER(8)
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(NBROW)
+SYM_ASSIGN
+SYM_INTEGER(8)
+SYM_SEMICOLON
+SYM_VOID
+SYM_IDENTIFIER(draw)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_IDENTIFIER(color)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(x)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(y)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(pos)
+SYM_ASSIGN
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(y)
+SYM_ASTERISK
+SYM_IDENTIFIER(NBCOL)
+SYM_PLUS
+SYM_IDENTIFIER(x)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_IF
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(pos)
+SYM_LT
+SYM_IDENTIFIER(NBCOL)
+SYM_ASTERISK
+SYM_IDENTIFIER(NBROW)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_ASTERISK
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(IMG)
+SYM_PLUS
+SYM_IDENTIFIER(pos)
+SYM_RPARENTHESIS
+SYM_ASSIGN
+SYM_IDENTIFIER(color)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_RBRACE
+SYM_INT
+SYM_IDENTIFIER(get)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_IDENTIFIER(x)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(y)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(pos)
+SYM_ASSIGN
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(y)
+SYM_ASTERISK
+SYM_IDENTIFIER(NBCOL)
+SYM_PLUS
+SYM_IDENTIFIER(x)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_IF
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(pos)
+SYM_LT
+SYM_IDENTIFIER(NBCOL)
+SYM_ASTERISK
+SYM_IDENTIFIER(NBROW)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_RETURN
+SYM_ASTERISK
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(IMG)
+SYM_PLUS
+SYM_IDENTIFIER(pos)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_RETURN
+SYM_MINUS
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_VOID
+SYM_IDENTIFIER(draw_world)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(i)
+SYM_ASSIGN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(j)
+SYM_ASSIGN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_WHILE
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(j)
+SYM_LT
+SYM_IDENTIFIER(NBROW)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_IDENTIFIER(i)
+SYM_ASSIGN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_WHILE
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(i)
+SYM_LT
+SYM_IDENTIFIER(NBCOL)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_IF
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(get)
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(i)
+SYM_COMMA
+SYM_IDENTIFIER(j)
+SYM_RPARENTHESIS
+SYM_NOTEQ
+SYM_INTEGER(0)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_IDENTIFIER(print_char)
+SYM_LPARENTHESIS
+SYM_CHARACTER(#)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_ELSE
+SYM_LBRACE
+SYM_IDENTIFIER(print_char)
+SYM_LPARENTHESIS
+SYM_CHARACTER( )
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_IDENTIFIER(i)
+SYM_ASSIGN
+SYM_IDENTIFIER(i)
+SYM_PLUS
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_IDENTIFIER(print_char)
+SYM_LPARENTHESIS
+SYM_CHARACTER(
+)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_IDENTIFIER(j)
+SYM_ASSIGN
+SYM_IDENTIFIER(j)
+SYM_PLUS
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_RBRACE
+SYM_INT
+SYM_IDENTIFIER(main)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_IDENTIFIER(draw)
+SYM_LPARENTHESIS
+SYM_INTEGER(16711680)
+SYM_COMMA
+SYM_INTEGER(1)
+SYM_COMMA
+SYM_INTEGER(1)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_IDENTIFIER(print)
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(get)
+SYM_LPARENTHESIS
+SYM_INTEGER(1)
+SYM_COMMA
+SYM_INTEGER(1)
+SYM_RPARENTHESIS
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_IDENTIFIER(draw_world)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RETURN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_EOF
diff --git a/tests/invader/constants.s b/tests/invader/constants.S
similarity index 100%
rename from tests/invader/constants.s
rename to tests/invader/constants.S
diff --git a/tests/invader/crt.S b/tests/invader/crt.S
new file mode 100644
index 0000000000000000000000000000000000000000..e5a63ba69a39f0939d4bce115d795025726fdad1
--- /dev/null
+++ b/tests/invader/crt.S
@@ -0,0 +1 @@
+.include "crtm.S"
diff --git a/tests/invader/crt.s b/tests/invader/crt.s
deleted file mode 100644
index dcdf1e15619b966fe805452be4aeaf56892fb577..0000000000000000000000000000000000000000
--- a/tests/invader/crt.s
+++ /dev/null
@@ -1 +0,0 @@
-.include "crtm.s"
diff --git a/tests/invader/crtm.s b/tests/invader/crtm.S
similarity index 96%
rename from tests/invader/crtm.s
rename to tests/invader/crtm.S
index 158b3ce37b6d63155898f5f40916b043408ac200..e68162cf377d3687d3ce2c9d33bea465ac1c03b0 100644
--- a/tests/invader/crtm.s
+++ b/tests/invader/crtm.S
@@ -1,7 +1,7 @@
 # See LICENSE for license details.
 
-.include "macros.s"
-.include "constants.s"
+.include "macros.S"
+.include "constants.S"
 
 #
 # start of trap handler
diff --git a/tests/invader/include/font.h b/tests/invader/include/font.h
index f65d48d250503448fea06af0668b1b630b80bb0e..58f066b5e4c9e162f153431ce2dc366e094dedfe 100644
--- a/tests/invader/include/font.h
+++ b/tests/invader/include/font.h
@@ -23,6 +23,6 @@
 
 // Constant: font8x8_basic
 // Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin)
-char font8x8_basic[256][8];
+extern char font8x8_basic[256][8];
 
 #endif
diff --git a/tests/invader/macros.s b/tests/invader/macros.S
similarity index 100%
rename from tests/invader/macros.s
rename to tests/invader/macros.S
diff --git a/tests/ptr/weird-ptr.e b/tests/ptr/weird-ptr.e
new file mode 100644
index 0000000000000000000000000000000000000000..c6381bd7b5485fbbb7e542d43ed2fa850b532b23
--- /dev/null
+++ b/tests/ptr/weird-ptr.e
@@ -0,0 +1,11 @@
+int ignore(int * x){
+  return 0;
+}
+int main(){
+  int x = 0;
+  int y = 0;
+  ignore(&x); // force x on the stack
+  int* p = &y - 1;
+  *p = 3;
+  return x;
+}
diff --git a/tests/ptr/weird-ptr.e.expect_14_12_3_8_12 b/tests/ptr/weird-ptr.e.expect_14_12_3_8_12
new file mode 100644
index 0000000000000000000000000000000000000000..ff173ecdb8373e909da3d38e30940db4a55a4f2d
--- /dev/null
+++ b/tests/ptr/weird-ptr.e.expect_14_12_3_8_12
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": 3}
\ No newline at end of file
diff --git a/tests/ptr/weird-ptr.e.expect_1_2_3 b/tests/ptr/weird-ptr.e.expect_1_2_3
new file mode 100644
index 0000000000000000000000000000000000000000..ff173ecdb8373e909da3d38e30940db4a55a4f2d
--- /dev/null
+++ b/tests/ptr/weird-ptr.e.expect_1_2_3
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": 3}
\ No newline at end of file
diff --git a/tests/ptr/weird-ptr.e.expect_lexer b/tests/ptr/weird-ptr.e.expect_lexer
new file mode 100644
index 0000000000000000000000000000000000000000..4862f4dd9c13bc662077b45b4963c847399f9d90
--- /dev/null
+++ b/tests/ptr/weird-ptr.e.expect_lexer
@@ -0,0 +1,52 @@
+SYM_INT
+SYM_IDENTIFIER(ignore)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_ASTERISK
+SYM_IDENTIFIER(x)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_RETURN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_INT
+SYM_IDENTIFIER(main)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(x)
+SYM_ASSIGN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(y)
+SYM_ASSIGN
+SYM_INTEGER(0)
+SYM_SEMICOLON
+SYM_IDENTIFIER(ignore)
+SYM_LPARENTHESIS
+SYM_AMPERSAND
+SYM_IDENTIFIER(x)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_INT
+SYM_ASTERISK
+SYM_IDENTIFIER(p)
+SYM_ASSIGN
+SYM_AMPERSAND
+SYM_IDENTIFIER(y)
+SYM_MINUS
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_ASTERISK
+SYM_IDENTIFIER(p)
+SYM_ASSIGN
+SYM_INTEGER(3)
+SYM_SEMICOLON
+SYM_RETURN
+SYM_IDENTIFIER(x)
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_EOF
diff --git a/tests/real_args/show_args.e b/tests/real_args/show_args.e
deleted file mode 100644
index 31100a71533456cd92acc6064864a47f98630b3c..0000000000000000000000000000000000000000
--- a/tests/real_args/show_args.e
+++ /dev/null
@@ -1,15 +0,0 @@
-int main(int argc, char* argv[]){
-  print_string("Program launched with ");
-  print_int(argc);
-  print_string(" arguments\n");
-  int i = 0;
-  while(i < argc){
-    print_string("argv[");
-    print_int(i);
-    print_string("] = ");
-    print_string(argv[i]);
-    print_string("\n");
-    i = i + 1;
-  }
-  return argc;
-}
diff --git a/tests/strings/rot13.e b/tests/strings/rot13.e
deleted file mode 100644
index 5b72b2ffbaffde899e3ffb556eeab1ecccd6faae..0000000000000000000000000000000000000000
--- a/tests/strings/rot13.e
+++ /dev/null
@@ -1,44 +0,0 @@
-int and(int a, int b){
-  if(a != 0){ return b; }
-  return 0;
-}
-
-int rot13c(char x){
-  if('A' <= x){
-    if (x <= 'Z'){
-      return 'A' + (x - 'A' + 13) % 26;
-    }
-  }
-  if('a' <= x){
-    if (x <= 'z'){
-      return 'a' + (x - 'a' + 13) % 26;
-    }
-  }
-  return x;
-}
-
-int rot13(char* c){
-  int i = 0;
-
-  while(c[i] != 0){
-    c[i] = rot13c(c[i]);
-    i = i + 1;
-  }
-  return 0;
-}
-int main(int argc,char* argv[]){
-  int a = atoi(argv[1]);
-  int b = atoi(argv[2]);
-  char c[10];
-  c[0] = 'C';
-  c[1] = 'o';
-  c[2] = 'u';
-  c[3] = 'c';
-  c[4] = 'o';
-  c[5] = 'u';
-  c[6] = 0;
-
-  rot13(c);
-  print_string(c);
-  return 0;
-}
diff --git a/tests/strings/string.e b/tests/strings/string.e
deleted file mode 100644
index 05def8af5f92f07573e108f0b80b5235604ce28c..0000000000000000000000000000000000000000
--- a/tests/strings/string.e
+++ /dev/null
@@ -1,13 +0,0 @@
-int main(int argc,char* argv[]){
-  char b[10];
-  b[0] = 'H';
-  b[1] = 'e';
-  b[2] = 'l';
-  b[3] = 'l';
-  b[4] = 'o';
-  b[5] = '!';
-  b[6] = 0;
-
-  print_string(b);
-  return 0;
-}
diff --git a/tests/strings/stringlit.e b/tests/strings/stringlit.e
deleted file mode 100644
index 4e84976016821f26ea4685e7868a3d6eaa39ed40..0000000000000000000000000000000000000000
--- a/tests/strings/stringlit.e
+++ /dev/null
@@ -1,5 +0,0 @@
-int main(int argc,char* argv[]){
-  char* c = "I am a string literal! Yay!\n";
-  print_string(c);
-  return 0;
-}
diff --git a/tests/strings/stringlit2.e b/tests/strings/stringlit2.e
deleted file mode 100644
index 643aeba161389002cad711fc6afc92c463af99c4..0000000000000000000000000000000000000000
--- a/tests/strings/stringlit2.e
+++ /dev/null
@@ -1,4 +0,0 @@
-int main(int argc,char* argv[]){
-  print_string("I am a string literal! Yay!\n");
-  return 0;
-}
diff --git a/tests/strings/stringlit3.e b/tests/strings/stringlit3.e
deleted file mode 100644
index b0d76cf208a453d3b6e7418efe6170f910e87650..0000000000000000000000000000000000000000
--- a/tests/strings/stringlit3.e
+++ /dev/null
@@ -1,6 +0,0 @@
-int main(int argc,char* argv[]){
-  char *c = "I am a string literal! Yay!\n";
-  c[5] = 'A';
-  print_string(c);
-  return 0;
-}
diff --git a/tests/strings/stringtab.e b/tests/strings/stringtab.e
deleted file mode 100644
index 6afea99590336e3e2c71e31f72b47f4d4be7e07e..0000000000000000000000000000000000000000
--- a/tests/strings/stringtab.e
+++ /dev/null
@@ -1,10 +0,0 @@
-int main(int argc,char* argv[]){
-  char* c = "Coucou\n";
-  char* d = "Hello!\n";
-  char* e[2];
-  e[0] = c;
-  e[1] = d;
-  print_string(e[0]);
-  print_string(e[1]);
-  return 0;
-}
diff --git a/tests/structs/structtab.e b/tests/structs/structtab.e
index 5fd4eac981a9242d3e4920220b1a1abdea43c16e..f28c3d354c19b88c5063634ef470148f7bf18852 100644
--- a/tests/structs/structtab.e
+++ b/tests/structs/structtab.e
@@ -2,7 +2,7 @@ struct S {
   int t[4];
 };
 
-int main(int argc, char* argv[]){
+int main(){
   struct S s;
   (s.t)[0] = 1;
   print_int((s.t)[0]);
diff --git a/tests/structs/structtab.e.expect_14_12_3_8_12 b/tests/structs/structtab.e.expect_14_12_3_8_12
new file mode 100644
index 0000000000000000000000000000000000000000..8858d4cccf47c58c61f15b14873ea04ff1793568
--- /dev/null
+++ b/tests/structs/structtab.e.expect_14_12_3_8_12
@@ -0,0 +1 @@
+{"output": "1", "error": null, "retval": 1}
\ No newline at end of file
diff --git a/tests/structs/structtab.e.expect_1_2_3 b/tests/structs/structtab.e.expect_1_2_3
new file mode 100644
index 0000000000000000000000000000000000000000..8858d4cccf47c58c61f15b14873ea04ff1793568
--- /dev/null
+++ b/tests/structs/structtab.e.expect_1_2_3
@@ -0,0 +1 @@
+{"output": "1", "error": null, "retval": 1}
\ No newline at end of file
diff --git a/tests/structs/structtab.e.expect_lexer b/tests/structs/structtab.e.expect_lexer
new file mode 100644
index 0000000000000000000000000000000000000000..1566d173fdc41a967b051fd8f02525da716c01e2
--- /dev/null
+++ b/tests/structs/structtab.e.expect_lexer
@@ -0,0 +1,55 @@
+SYM_STRUCT
+SYM_IDENTIFIER(S)
+SYM_LBRACE
+SYM_INT
+SYM_IDENTIFIER(t)
+SYM_LBRACKET
+SYM_INTEGER(4)
+SYM_RBRACKET
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_SEMICOLON
+SYM_INT
+SYM_IDENTIFIER(main)
+SYM_LPARENTHESIS
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_STRUCT
+SYM_IDENTIFIER(S)
+SYM_IDENTIFIER(s)
+SYM_SEMICOLON
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(s)
+SYM_POINT
+SYM_IDENTIFIER(t)
+SYM_RPARENTHESIS
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_ASSIGN
+SYM_INTEGER(1)
+SYM_SEMICOLON
+SYM_IDENTIFIER(print_int)
+SYM_LPARENTHESIS
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(s)
+SYM_POINT
+SYM_IDENTIFIER(t)
+SYM_RPARENTHESIS
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RETURN
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(s)
+SYM_POINT
+SYM_IDENTIFIER(t)
+SYM_RPARENTHESIS
+SYM_LBRACKET
+SYM_INTEGER(0)
+SYM_RBRACKET
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_EOF
diff --git a/tests/test.py b/tests/test.py
index a0b25898501d4840b9155f3a9a3e9fe6b6cff7fb..fd9e2979ec1ec236c7ec16762d5ccd0c29452dfe 100755
--- a/tests/test.py
+++ b/tests/test.py
@@ -21,7 +21,6 @@ parser.add_argument("-p", "--passes",
                     nargs='+',
                     default=["e-run",
                              "cfg-run",
-                             "cfg-run-after-loop",
                              "cfg-run-after-cp",
                              "cfg-run-after-dae",
                              "cfg-run-after-ne",
@@ -144,13 +143,18 @@ class CommandExecutor(Thread):
         self.stderr = process['stderr'].decode('utf8')
         json_file_name = self.f + ".json"
         j = []
-        with open(json_file_name, 'r') as jsonfile:
-            try:
-                j = json.load(jsonfile)
-            except:
-                j.append({'retval':-1,
-                          'output': display_verbatim(self.stdout),
-                          'error': display_verbatim(self.stderr)})
+        try:
+            with open(json_file_name, 'r') as jsonfile:
+                try:
+                    j = json.load(jsonfile)
+                except:
+                    j.append({'retval':-1,
+                              'output': display_verbatim(self.stdout),
+                              'error': display_verbatim(self.stderr)})
+        except:
+            j.append({'retval':-1,
+                      'output': display_verbatim(self.stdout),
+                      'error': "No file {} generated...".format(json_file_name)})
         old_ret = None
         old_out = None
         old_err = None
@@ -185,7 +189,7 @@ class CommandExecutor(Thread):
                     self.lastcorrectstep = curcol
                 self.s += make_td(["Ret = {}.<br>Output = <pre>'{}'</pre>{}<br>Time: {:.2f} seconds.<br>".
                                    format(r['retval'], r['output'],
-                                          "Error: "+r['error'] if r['error'] != None else "",
+                                          "Error: <pre>"+r['error']+"</pre>" if r['error'] != None else "",
                                           r['time']),
                                    "class=\"{}\"".format(cls)])
                 curcol+=1
diff --git a/tests/type_funcall/argswap-simple.e b/tests/type_funcall/argswap-simple.e
new file mode 100644
index 0000000000000000000000000000000000000000..7af7b6a7fbca5a4ee0ce29b45204babd5711ae29
--- /dev/null
+++ b/tests/type_funcall/argswap-simple.e
@@ -0,0 +1,9 @@
+int g(int a,int b){
+  return (b - a);
+}
+int f(int a, int b){
+  return g(b, a);
+}
+int main(int x, int y){
+  return f(x, y);
+}
diff --git a/tests/type_funcall/argswap-simple.e.expect_14_12_3_8_12 b/tests/type_funcall/argswap-simple.e.expect_14_12_3_8_12
new file mode 100644
index 0000000000000000000000000000000000000000..df1c5a5ba4e1647c7e3409ee9539a3583afa9bdf
--- /dev/null
+++ b/tests/type_funcall/argswap-simple.e.expect_14_12_3_8_12
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": 2}
\ No newline at end of file
diff --git a/tests/type_funcall/argswap-simple.e.expect_1_2_3 b/tests/type_funcall/argswap-simple.e.expect_1_2_3
new file mode 100644
index 0000000000000000000000000000000000000000..f8d80dd35ec68fe40bb34baeb5311e940a3ebfa9
--- /dev/null
+++ b/tests/type_funcall/argswap-simple.e.expect_1_2_3
@@ -0,0 +1 @@
+{"output": "", "error": null, "retval": -1}
\ No newline at end of file
diff --git a/tests/type_funcall/argswap-simple.e.expect_lexer b/tests/type_funcall/argswap-simple.e.expect_lexer
new file mode 100644
index 0000000000000000000000000000000000000000..034f6bd4babb9793eafad6000d158efd3ff168dc
--- /dev/null
+++ b/tests/type_funcall/argswap-simple.e.expect_lexer
@@ -0,0 +1,57 @@
+SYM_INT
+SYM_IDENTIFIER(g)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_IDENTIFIER(a)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(b)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_RETURN
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(b)
+SYM_MINUS
+SYM_IDENTIFIER(a)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_INT
+SYM_IDENTIFIER(f)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_IDENTIFIER(a)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(b)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_RETURN
+SYM_IDENTIFIER(g)
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(b)
+SYM_COMMA
+SYM_IDENTIFIER(a)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_INT
+SYM_IDENTIFIER(main)
+SYM_LPARENTHESIS
+SYM_INT
+SYM_IDENTIFIER(x)
+SYM_COMMA
+SYM_INT
+SYM_IDENTIFIER(y)
+SYM_RPARENTHESIS
+SYM_LBRACE
+SYM_RETURN
+SYM_IDENTIFIER(f)
+SYM_LPARENTHESIS
+SYM_IDENTIFIER(x)
+SYM_COMMA
+SYM_IDENTIFIER(y)
+SYM_RPARENTHESIS
+SYM_SEMICOLON
+SYM_RBRACE
+SYM_EOF