diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..034be96b32572067d6baed606b1e7268c43944f3
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "tests"]
+	path = tests
+	url = https://cavale.enseeiht.fr/git/lustrec-tests
diff --git a/dune b/dune
new file mode 100644
index 0000000000000000000000000000000000000000..1db7dae38d926d9d73ae1aad2ac37608155ac75e
--- /dev/null
+++ b/dune
@@ -0,0 +1,41 @@
+; too bad dune does not support glob in install stanza
+; (see https://discuss.ocaml.org/t/installing-many-files-with-dune/4143)
+; TODO: open an issue?
+
+(install
+ (section (site (lustrec include_)))
+ (files
+   include/conv.c
+   include/mpfr_lustre.c
+   include/simulink_math_fcn.c
+   include/arrow.c
+   include/arrow.h
+   include/arrow.cpp
+   include/arrow.hpp
+   include/io_frontend.c
+   include/io_frontend.h
+   include/io_frontend.hpp
+   include/lustrec_math.smt2
+   include/mpfr_lustre.lusi
+   include/mpfr_lustre.lusic
+   include/simulink_math_fcn.lusi
+   include/simulink_math_fcn.lusic
+   include/conv.lusi
+   include/conv.lusic
+   include/lustrec_math.lusi
+   include/lustrec_math.lusic
+   include/StdIn.java))
+
+(install
+ (section (site (lustrec testgen)))
+ (files
+   share/FindLustre.cmake
+   share/helpful_functions.cmake))
+
+(rule
+ (alias runtest)
+ (deps (source_tree tests/regression_tests))
+ (action (chdir tests/regression_tests
+          (progn
+           (run cmake "-DSUBPROJ=\"unstable\"" "-DLUSTRE_INCLUDE_DIR=%{project_root}/include" .)
+           (run ctest -D Experimental -R "COMPIL_LUS|MAKE|BIN|DIFF" -E LUSTRET --progress)))))
diff --git a/dune-project b/dune-project
index 1202daa8308efc80449439e8bb2829e7cd92c7e9..6b6ecc3cae7abc895b18746d0ca5aa2753a021a6 100644
--- a/dune-project
+++ b/dune-project
@@ -18,7 +18,9 @@
  (name lustrec)
  (sites
   (lib plugins)
-  (lib verifiers))
+  (lib verifiers)
+  (lib include_)
+  (share testgen))
  (synopsis "A Lustre compiler toolset")
  (description
    "lustrec is structured around the modular compilation scheme proposed by \
diff --git a/include/dune b/include/dune
new file mode 100644
index 0000000000000000000000000000000000000000..3bdc5731ccbb651edb8c49320e0600d0d0f6b1f0
--- /dev/null
+++ b/include/dune
@@ -0,0 +1,23 @@
+; too bad we have to repeat the same rule three times...
+; The make-like behavior if still unsupported by dune
+; (see https://discuss.ocaml.org/t/dune-copy-multiple-dependencies-to-build-directory-in-rule-stanza/4144/5)
+
+(rule
+ (target conv.lusic)
+ (action (run lustrec -verbose 0 -I . -d . %{dep:conv.lusi}))
+ (alias install))
+
+(rule
+ (target simulink_math_fcn.lusic)
+ (action (run lustrec -verbose 0 -I . -d . %{dep:simulink_math_fcn.lusi}))
+ (alias install))
+
+(rule
+ (target lustrec_math.lusic)
+ (action (run lustrec -verbose 0 -I . -d . %{dep:lustrec_math.lusi}))
+ (alias install))
+
+(rule
+ (target mpfr_lustre.lusic)
+ (action (run lustrec -verbose 0 -mpfr 1 -d . %{dep:mpfr_lustre.lusi}))
+ (alias install))
diff --git a/share/FindLustre.cmake.in b/share/FindLustre.cmake
similarity index 99%
rename from share/FindLustre.cmake.in
rename to share/FindLustre.cmake
index 9503e317ff790930e86c8dae6c4777bfe0983662..7b8ae85b19455220a6b9b8dac8bab922f32fc26a 100644
--- a/share/FindLustre.cmake.in
+++ b/share/FindLustre.cmake
@@ -26,7 +26,7 @@
 # The VERBOSE level is a numeric value passed directly to the -verbose
 # command line option of the lustre compiler
 #
-include("@prefix@/share/helpful_functions.cmake")
+include("helpful_functions.cmake")
 
 if(LUSTRE_PATH_HINT)
   message(STATUS "FindLustre: using PATH HINT: ${LUSTRE_PATH_HINT}")
diff --git a/src/automata.ml b/src/automata.ml
index e5388d9f305f64dc06a77098d3f3e48b91863b7e..37f9b92947a335caa52b01dcd2f5f11f8adf8523 100644
--- a/src/automata.ml
+++ b/src/automata.ml
@@ -263,7 +263,7 @@ let expand_node_stmt nused used owner node (top_types, top_nodes, locals, eqs) s
     (top_typedef :: top_types, top_decls'@top_nodes, locals'@locals, eqs'@eqs)
 
 let expand_node_stmts nused used loc owner node =
-  let (top_types', top_nodes', locals', eqs') =
+  let top_types', top_nodes', locals', eqs' =
     List.fold_left (expand_node_stmt nused used owner node) ([], [], [], []) node.node_stmts in
   let node' = 
     { node with node_locals = locals'@node.node_locals; node_stmts = eqs' } in
@@ -277,18 +277,18 @@ let rec expand_decls_rec nused top_decls =
     match top_decl.top_decl_desc with
     | Node nd ->
       let used name =
-	   List.exists (fun v -> v.var_id = name) nd.node_inputs
-	|| List.exists (fun v -> v.var_id = name) nd.node_outputs
-	|| List.exists (fun v -> v.var_id = name) nd.node_locals in
-      let (top_types', top_decl', top_nodes') = expand_node_stmts nused used top_decl.top_decl_loc top_decl.top_decl_owner nd in
+        List.exists (fun v -> v.var_id = name) nd.node_inputs
+        || List.exists (fun v -> v.var_id = name) nd.node_outputs
+        || List.exists (fun v -> v.var_id = name) nd.node_locals in
+      let top_types', top_decl', top_nodes' = expand_node_stmts nused used top_decl.top_decl_loc top_decl.top_decl_owner nd in
       top_types' @ (top_decl' :: expand_decls_rec nused (top_nodes'@q))
     | _       -> top_decl :: expand_decls_rec nused q
 
 let expand_decls top_decls =
   let top_names = List.fold_left (fun names t -> match t.top_decl_desc with
-    | Node nd         -> ISet.add nd.node_id names
-    | ImportedNode nd -> ISet.add nd.nodei_id names
-    | _               -> names) ISet.empty top_decls in
+      | Node nd         -> ISet.add nd.node_id names
+      | ImportedNode nd -> ISet.add nd.nodei_id names
+      | _               -> names) ISet.empty top_decls in
   let nused name = ISet.mem name top_names in
   expand_decls_rec nused top_decls
 
diff --git a/src/backends/C/c_backend_header.ml b/src/backends/C/c_backend_header.ml
index 1c0afa99ab4b9d39c37bef09b8960f325f612154..b853f5e7d807c8bb91809a625144c50d8e2f6f69 100644
--- a/src/backends/C/c_backend_header.ml
+++ b/src/backends/C/c_backend_header.ml
@@ -280,11 +280,11 @@ let print_type_definitions fmt filename =
 		| _        -> ()) type_table
 
 let reset_type_definitions, print_type_definition_from_header =
-  let cpt_type =ref 0 in
-  ((fun () -> cpt_type := 0),
-   (fun fmt typ filename ->
-    fprintf fmt "typedef %a;@.@."
-	(pp_c_type_decl filename cpt_type typ.tydef_id) typ.tydef_desc))
+  let cpt_type = ref 0 in
+  (fun () -> cpt_type := 0),
+  (fun fmt typ filename ->
+     fprintf fmt "typedef %a;@.@."
+	     (pp_c_type_decl filename cpt_type typ.tydef_id) typ.tydef_desc)
 
 (********************************************************************************************)
 (*                         MAIN Header Printing functions                                   *)
diff --git a/src/backends/C/c_backend_makefile.ml b/src/backends/C/c_backend_makefile.ml
index 6dd4678a7a86a6fab2c67faf7202312d48e7d399..1b4471649f63ccf2feb6c4ee99a619508c164ff9 100644
--- a/src/backends/C/c_backend_makefile.ml
+++ b/src/backends/C/c_backend_makefile.ml
@@ -98,7 +98,7 @@ To be solved (later) with
     fprintf fmt "GCC=gcc -O0@.";
     fprintf fmt "LUSTREC=%s@." Sys.executable_name;
     fprintf fmt "LUSTREC_BASE=%s@." (Filename.dirname (Filename.dirname Sys.executable_name));
-    fprintf fmt "INC=${LUSTREC_BASE}/include/lustrec@.";
+    fprintf fmt "INC=%s@." Version.include_path (*"${LUSTREC_BASE}/include/lustrec"*);
     fprintf fmt "@.";
 
     (* Main binary *)
diff --git a/src/compiler_stages.ml b/src/compiler_stages.ml
index 31f341234d437efcef3d49d6c16a6c9e5807a599..4a51a4f6cad09b4077e77acf2cc84a892574273a 100644
--- a/src/compiler_stages.ml
+++ b/src/compiler_stages.ml
@@ -17,41 +17,39 @@ let compile_source_to_header prog computed_types_env computed_clocks_env dirname
   let destname = !Options.dest_dir ^ "/" ^ basename in
   let lusic_ext = ".lusic" in
   let header_name = destname ^ lusic_ext in
+  let from_lusi = extension = ".lusi" in
   begin
     if (* Generating the lusic file *)
-      extension = ".lusi" (* because input is a lusi *)
-      || (extension = ".lus" &&
-            not (Sys.file_exists header_name))
-           (* or because it is a lus but not lusic exists *)
+      (* because input is a lusi *)
+      from_lusi
+      (* or because it is a lus but no lusic exists *)
+      || (extension = ".lus" && not (Sys.file_exists header_name))
+      (* or the lusic exists but is not generated from a lusi, hence it
+         has te be regenerated *)
       || (let lusic = Lusic.read_lusic destname lusic_ext in
           not lusic.Lusic.from_lusi)
-         (* or the lusic exists but is not generated from a lusi, hence it
-            has te be regenerated *)
     then
       begin
-	Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
-	Lusic.write_lusic
-          (extension = ".lusi") (* is it a lusi file ? *)
-          (if extension = ".lusi" then prog else Lusic.extract_header dirname basename prog)
+        Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
+        Lusic.write_lusic
+          from_lusi (* is it a lusi file ? *)
+          (if from_lusi then prog else Lusic.extract_header dirname basename prog)
           destname
           lusic_ext;
-        let _ =
-          match !Options.output with
-          | "C" -> C_backend_lusic.print_lusic_to_h destname lusic_ext
-          | _ -> ()
-        in
-        ()
+        match !Options.output with
+        | "C" -> C_backend_lusic.print_lusic_to_h destname lusic_ext
+        | _ -> ()
       end
     else (* Lusic exists and is usable. Checking compatibility *)
       begin
-	Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name);
+        Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name);
         let lusic = Lusic.read_lusic destname lusic_ext in
         Lusic.check_obsolete lusic destname;
-	let header = lusic.Lusic.contents in
-	let (declared_types_env, declared_clocks_env) = Modules.get_envs_from_top_decls header in
-	check_compatibility
-	  (prog, computed_types_env, computed_clocks_env)
-	  (header, declared_types_env, declared_clocks_env)
+        let header = lusic.Lusic.contents in
+        let (declared_types_env, declared_clocks_env) = Modules.get_envs_from_top_decls header in
+        check_compatibility
+          (prog, computed_types_env, computed_clocks_env)
+          (header, declared_types_env, declared_clocks_env)
       end
   end
 
diff --git a/src/dune b/src/dune
index 27cd125af017cebef40a022a8c4eb33e54d5da12..5eb91bb8f83527c26c6a6b91525011da71d273f0 100644
--- a/src/dune
+++ b/src/dune
@@ -50,7 +50,7 @@
    clock_calculus
  )
  (wrapped false)
- (libraries ocamlgraph zarith unix str))
+ (libraries sites ocamlgraph zarith unix str))
 
 (library
  (name plugin_register)
@@ -61,7 +61,10 @@
 
 (generate_sites_module
  (module sites)
- (plugins (lustrec plugins) (lustrec verifiers)))
+ ; (sites lustrec)
+ (plugins
+  (lustrec plugins)
+  (lustrec verifiers)))
 
 (library
  (name sites)
@@ -157,6 +160,8 @@
    memo)
  (libraries tools_lib))
 
+
+
 ; (executable
 ;  (name main_parse_json_file)
 ;  (public_name json-parser)
diff --git a/src/lusic.ml b/src/lusic.ml
index d8cf1676521c59d29f69a236565920bfea227f69..1cd5dd8a1f48606e1567350039edc89f87f293e2 100644
--- a/src/lusic.ml
+++ b/src/lusic.ml
@@ -32,14 +32,16 @@ let extract_header dirname basename prog =
   let owner = dirname ^ "/" ^ basename in
   List.fold_right
     (fun decl header ->
-      (*Format.eprintf "Lusic.extract_header: header = %B, owner = %s, decl_owner = %s@." decl.top_decl_itf owner decl.top_decl_owner;*)
-      if decl.top_decl_itf || decl.top_decl_owner <> owner then header else
-	match decl.top_decl_desc with
-	| Node nd        -> { decl with top_decl_desc = ImportedNode (Corelang.get_node_interface nd) } :: header 
-	| ImportedNode _ -> header
-	| Const _
-	| TypeDef _
-	| Include _ | Open _         -> decl :: header)
+       (* Format.eprintf "Lusic.extract_header: header = %B, owner = %s, decl_owner = %s@."
+        *   decl.top_decl_itf owner decl.top_decl_owner; *)
+       if decl.top_decl_itf || decl.top_decl_owner <> owner then header
+       else match decl.top_decl_desc with
+         | Node nd ->
+           { decl with top_decl_desc =
+                         ImportedNode (Corelang.get_node_interface nd) }
+           :: header
+         | ImportedNode _ -> header
+         | Const _ | TypeDef _ | Include _ | Open _  -> decl :: header)
     prog []
 
 let check_obsolete lusic basename =
diff --git a/src/main_lustre_testgen.ml b/src/main_lustre_testgen.ml
index 2c4f73a423346a25ce05406415652456ed40abc2..5c8820d1d6f7465989042d1b9f294f4582b0e46d 100644
--- a/src/main_lustre_testgen.ml
+++ b/src/main_lustre_testgen.ml
@@ -152,8 +152,8 @@ let testgen_source dirname basename extension =
   let cmake_file = open_out cmakelists in
   let cmake_fmt = formatter_of_out_channel cmake_file in
   Format.fprintf cmake_fmt "cmake_minimum_required(VERSION 3.5)@.";
-  Format.fprintf cmake_fmt "include(\"%s/share/helpful_functions.cmake\")@." Version.prefix;
-  Format.fprintf cmake_fmt "include(\"%s/share/FindLustre.cmake\")@." Version.prefix;
+  Format.fprintf cmake_fmt "include(\"%s/helpful_functions.cmake\")@." Version.testgen_path;
+  Format.fprintf cmake_fmt "include(\"%s/FindLustre.cmake\")@." Version.testgen_path;
   Format.fprintf cmake_fmt "LUSTREFILES(LFILES ${CMAKE_CURRENT_SOURCE_DIR} )@.";
   Format.fprintf cmake_fmt "@[<v 2>FOREACH(lus_file ${LFILES})@ ";
   Format.fprintf cmake_fmt "get_lustre_name_ext(${lus_file} L E)@ ";
diff --git a/src/options_management.ml b/src/options_management.ml
index ac48093bebbb83caa69c1ae8ef0d9756938ae1ca..e12b2afb8167a2c990adbb9f1dde0b6bab86bf8d 100644
--- a/src/options_management.ml
+++ b/src/options_management.ml
@@ -11,7 +11,7 @@
 open Options
 
 let print_version () =
-  Format.printf "Lustrec compiler, version %s (%s)@." version codename;
+  Format.printf "Lustrec compiler, version %s (%s)@." version (codename ());
   Format.printf "Standard lib: %s@." Version.include_path;
   Format.printf "User provided include directory: @[<h>%a@]@."
     (Utils.fprintf_list ~sep:"@ " Format.pp_print_string) !include_dirs
diff --git a/src/parsers/parse.ml b/src/parsers/parse.ml
index c33319cf38ea56f3eac866734edb2687aaee7bc4..2835e16253d3193bdb8e8cfbf03142f47534e394 100644
--- a/src/parsers/parse.ml
+++ b/src/parsers/parse.ml
@@ -24,44 +24,47 @@ type error =
 
 exception Error of (Location.t * error)
 
-
 let pp_error fmt err =
   match err with
-  | Unexpected_eof          -> fprintf fmt "unexpected end of file"
-  | Undefined_token tok   -> fprintf fmt "undefined token '%s'" tok
-  | Unfinished_string        -> fprintf fmt "unfinished string"
-  | Unfinished_comment  -> fprintf fmt "unfinished comment"
-  | Syntax_error               -> fprintf fmt "syntax error"
-  | String_Syntax_error s              -> fprintf fmt "syntax error in %s" s
-  | Unfinished_annot        -> fprintf fmt "unfinished annotation"
-  | Unfinished_node_spec -> fprintf fmt "unfinished node specification"
-  | Annot_error s              -> fprintf fmt "impossible to parse the following annotation:@.%s@.@?" s
-  | Node_spec_error s       -> fprintf fmt "Impossible to parse the following node specification:@.%s@.@?" s
+  | Unexpected_eof ->
+    fprintf fmt "unexpected end of file"
+  | Undefined_token tok ->
+    fprintf fmt "undefined token '%s'" tok
+  | Unfinished_string ->
+    fprintf fmt "unfinished string"
+  | Unfinished_comment ->
+    fprintf fmt "unfinished comment"
+  | Syntax_error ->
+    fprintf fmt "syntax error"
+  | String_Syntax_error s ->
+    fprintf fmt "syntax error in %s" s
+  | Unfinished_annot ->
+    fprintf fmt "unfinished annotation"
+  | Unfinished_node_spec ->
+    fprintf fmt "unfinished node specification"
+  | Annot_error s ->
+    fprintf fmt "impossible to parse the following annotation:@.%s@.@?" s
+  | Node_spec_error s ->
+    fprintf fmt "Impossible to parse the following node specification:@.%s@.@?" s
 
 let report_error (loc, err) =
-  eprintf "Syntax error: %a@.%a@."
-    pp_error err
+  eprintf "Syntax error: %a@."
+    (* pp_error err *)
     Location.pp_loc loc
 
 let header parsing_fun token_fun lexbuf =
-  try
-    let ast = parsing_fun token_fun lexbuf in
-    Parsing.clear_parser ();
-    ast
-  with
-  | Parsing.Parse_error ->
+  try parsing_fun token_fun lexbuf with _ ->
     let loc = Location.curr lexbuf in
-    raise (Error (loc, Syntax_error))
+    let e = loc, Syntax_error in
+    report_error e;
+    raise (Error e)
 
 let prog parsing_fun token_fun lexbuf =
-  try
-    let ast = parsing_fun token_fun lexbuf in
-    Parsing.clear_parser ();
-    ast
-  with
-  | Parsing.Parse_error ->
+  try parsing_fun token_fun lexbuf with err ->
     let loc = Location.curr lexbuf in
-    raise (Error (loc, Syntax_error))
+    let e = loc, Syntax_error in
+    report_error e;
+    raise (Error e)
 
 (* Local Variables: *)
 (* compile-command:"make -C .." *)
diff --git a/src/parsers/parser_lustre.mly b/src/parsers/parser_lustre.mly
index 95854fd72e1cdffce415113112d41effc125486c..aad0a712d2171f5cfee5e6c16eeebf373e908923 100644
--- a/src/parsers/parser_lustre.mly
+++ b/src/parsers/parser_lustre.mly
@@ -19,26 +19,26 @@ open Dimension
 let get_loc () = Location.symbol_rloc ()
 
 let mkident x = x, get_loc ()
-let mktyp = mktyp (get_loc ())
+let mktyp x = mktyp (get_loc ()) x
 let mkotyp x = match x with Some t -> Some (mktyp t) | None -> None
-let mkclock = mkclock (get_loc ())
+let mkclock x = mkclock (get_loc ()) x
 let mkvar_decl x loc = mkvar_decl loc ~orig:true x
-let mkexpr = mkexpr (get_loc ())
-let mkeexpr = mkeexpr (get_loc ())
-let mkeq = mkeq (get_loc ())
-let mkassert = mkassert (get_loc ())
-let mktop_decl = mktop_decl (get_loc ()) (Location.get_module ())
-let mkpredef_call = mkpredef_call (get_loc ())
+let mkexpr x = mkexpr (get_loc ()) x
+let mkeexpr x = mkeexpr (get_loc ()) x
+let mkeq x = mkeq (get_loc ()) x
+let mkassert x = mkassert (get_loc ()) x
+let mktop_decl x = mktop_decl (get_loc ()) (Location.get_module ()) x
+let mkpredef_call x = mkpredef_call (get_loc ()) x
 let mkpredef_call_b f x1 x2 = mkpredef_call f [x1; x2]
 let mkpredef_call_u f x = mkpredef_call f [x]
 
-let mkdim_int = mkdim_int (get_loc ())
+let mkdim_int x = mkdim_int (get_loc ()) x
 (* let mkdim_bool b = mkdim_bool (get_loc ()) b *)
-let mkdim_ident = mkdim_ident (get_loc ())
-let mkdim_appl = mkdim_appl (get_loc ())
+let mkdim_ident x = mkdim_ident (get_loc ()) x
+let mkdim_appl x = mkdim_appl (get_loc ()) x
 let mkdim_appl_b f x1 x2 = mkdim_appl f [x1; x2]
 let mkdim_appl_u f x = mkdim_appl f [x]
-let mkdim_ite = mkdim_ite (get_loc ())
+let mkdim_ite x = mkdim_ite (get_loc ()) x
 
 let mkarraytype = List.fold_left (fun t d -> Tydec_array (d, t))
 
@@ -96,8 +96,8 @@ let rec fby expr n init =
 %token EOF
 
 %nonassoc p_string
-%nonassoc p_vdecl
-%left SCOL
+(* %nonassoc p_vdecl *)
+(* %left SCOL *)
 %nonassoc EVERY
 %nonassoc ELSE
 %right ARROW FBY
@@ -189,8 +189,8 @@ top_decl_header:
 | CONST ds=cdecl+ SCOL
   { List.map ((|>) true) ds }
 | nodei_spec=nodespecs nodei_stateless=state_annot nodei_id=node_ident_decl
-  LPAR nodei_inputs=vdecl_list SCOL? RPAR
-  RETURNS LPAR nodei_outputs=vdecl_list SCOL? RPAR
+  LPAR nodei_inputs=var_decl_list(vdecl) RPAR
+  RETURNS LPAR nodei_outputs=var_decl_list(vdecl) RPAR
   nodei_prototype=preceded(PROTOTYPE, node_ident)?
   nodei_in_lib=preceded(LIB, module_ident)* SCOL
   { let nd = mktop_decl true (ImportedNode {
@@ -215,8 +215,8 @@ top_decl:
 | CONST ds=cdecl+ SCOL
   { List.map ((|>) false) ds }
 | node_dec_stateless=state_annot node_id=node_ident_decl
-  LPAR node_inputs=vdecl_list SCOL? RPAR
-  RETURNS LPAR node_outputs=vdecl_list SCOL? RPAR SCOL?
+  LPAR node_inputs=var_decl_list(vdecl) RPAR
+  RETURNS LPAR node_outputs=var_decl_list(vdecl) RPAR SCOL?
   node_spec=nodespecs
   node_locals=locals LET content=stmt_list TEL
   { let node_stmts, node_asserts, node_annot = content in
@@ -351,8 +351,8 @@ lustre_spec:
 
 top_contract:
 | CONTRACT node_id=node_ident_decl
-  LPAR node_inputs=vdecl_list SCOL? RPAR
-  RETURNS LPAR node_outputs=vdecl_list SCOL? RPAR SCOL?
+  LPAR node_inputs=var_decl_list(vdecl) RPAR
+  RETURNS LPAR node_outputs=var_decl_list(vdecl) RPAR SCOL?
   LET cc=contract_content TEL
   { let nd = mktop_decl true (Node {
                                   node_id;
@@ -566,12 +566,11 @@ dim:
 | IF d=dim THEN t=dim ELSE f=dim { mkdim_ite d t f }
 
 %inline locals:
-| xs=loption(preceded(VAR, flatten(separated_nonempty_list(SCOL, local_vdecl))))
-  { xs }
+| xs=loption(preceded(VAR, var_decl_list(local_vdecl))) { xs }
 
-vdecl_list:
-| d=vdecl %prec p_vdecl { d }
-| d=vdecl SCOL ds=vdecl_list { d @ ds }
+var_decl_list(X):
+| d=X ioption(SCOL)            { d }
+| d=X SCOL ds=var_decl_list(X) { d @ ds }
 
 vdecl:
 | xs=ident_list COL t=typeconst c=clock?
diff --git a/src/utils/location.ml b/src/utils/location.ml
index 8c32603cd213c36b9c557af12535c8b1e8c17d46..87dba997b1b9a1dcc8e59bedae15f0ac567571b6 100644
--- a/src/utils/location.ml
+++ b/src/utils/location.ml
@@ -90,7 +90,8 @@ let pp_loc fmt loc =
   let (start_char, end_char) =
     if start_char < 0 then (0,1) else (start_char, end_char)
   in
-  Format.fprintf fmt "File \"%s\", line %i, characters %i-%i:" filename line start_char end_char;
+  Format.fprintf fmt "File \"%s\", line %i, characters %i-%i"
+    filename line start_char end_char;
   (* Format.fprintf fmt "@.loc1=(%i,%i,%i) loc2=(%i,%i,%i)@."
    *   loc.loc_start.Lexing.pos_lnum
    *   loc.loc_start.Lexing.pos_bol
diff --git a/src/version.ml b/src/version.ml
index 30f5044e61a39a20b1ee975effe2a234e0a78162..1b434bc8c4e91ef892931e4fcfe86e5c14fe9634 100644
--- a/src/version.ml
+++ b/src/version.ml
@@ -1,7 +1,9 @@
-let number = "@PACKAGE_VERSION@-@GITBRANCH@"
+let number = "%%VERSION%%"
 
-let codename ="@VERSION_CODENAME@"
+let codename () =
+  match "%%VERSION_NUM%%" with
+  | "1.7" -> "Xia/Huai-dev"
+  | _ -> "dev"
 
-let prefix = "@prefix@"
-
-let include_path = prefix ^ "/include/lustrec"
+let include_path = Sites.Sites.include_ |> List.hd
+let testgen_path = Sites.Sites.testgen |> List.hd
diff --git a/tests b/tests
new file mode 160000
index 0000000000000000000000000000000000000000..0ac53ee0fbfc6ba8261ad8ab15173bd58c4d043c
--- /dev/null
+++ b/tests
@@ -0,0 +1 @@
+Subproject commit 0ac53ee0fbfc6ba8261ad8ab15173bd58c4d043c