Skip to content
Snippets Groups Projects
main.ml 8.55 KiB
Newer Older
Erwan Jahier's avatar
Erwan Jahier committed
(** Time-stamp: <modified the 28/08/2008 (at 10:28) by Erwan Jahier> *)
(** Here follows a description of the different modules used by this lus2lic compiler.
(1) First of all, the Lustre files are parsed,

Erwan Jahier's avatar
Erwan Jahier committed
   lexer.mll  
   parser.mly
   parserUtils.ml
   lxm.mli/ml
which results into a parse tree containing raw source expressions.

   syntaxTree.ml  -> should rather be called rawSyntaxTab.ml ?
(2) Then, we perform reference checking at module level + model expansion.

      symbolTab.mli/ml (type/const/node)
syntaxTab is a kind of layer above syntaxTree to make things easier afterwards.


Erwan Jahier's avatar
Erwan Jahier committed
(3) Finally, the compilation (type checking+const/type evaluation) is performed.
   compile.ml
      lazyCompiler.mli/ml
        evalConst.mli/ml
        evalType.mli/ml
   compiledData.ml
    

Some misc (eponymous) modules are used along the way.
   errors.ml 
Erwan Jahier's avatar
Erwan Jahier committed
   verbose.mli/ml
Erwan Jahier's avatar
Erwan Jahier committed

open Verbose
open SyntaxTree
Erwan Jahier's avatar
Erwan Jahier committed
open SyntaxTreeCore
Erwan Jahier's avatar
Erwan Jahier committed
open Lxm
open Errors
open Parsing
open Format


(*---------------------------------------------------------
Les args sont des variables GLOBALES
---------------------------------------------------------*)
Erwan Jahier's avatar
Erwan Jahier committed

let print_version = function (x: unit) -> (
  print_string (Version.str ^ "\n")
)

let usage_msg =  
  "usage: "^(Version.tool)^" [options] <lustre files> | "^(Version.tool)^" -help" 
   
let rec arg_list = [
  ( "--version", Arg.Unit(fun x -> print_version () ; exit 0),
    "\tPrint the current version then exit"
  );
  ( "--output-file", Arg.String(fun x -> Global.outfile := x), "<file>"
  );
  ( "-o", Arg.String(fun x -> Global.outfile := x),
    "<file>\tSet the output file name"
  );
  ( "--node", Arg.String(fun x -> Global.main_node := x),
    "<node>"
  );
  ( "-n", Arg.String(fun x -> Global.main_node := x),
    "<node>\tSet the main node (all items are compiled if unset)"
  );
  ( "--compile-all-items", Arg.Unit
      (function x -> Global.compile_all_items := true),
    "\t"
  );
  ( "-all", Arg.Unit
      (function x -> Global.compile_all_items := true),
    "\t\tCompile all items of the program"
  );
  ( "-unit", Arg.Unit (fun x -> Global.run_unit_test := true),
    "\tRun some (internal) unit tests"
  );
  ( "--verbose", Arg.Unit (fun vl -> Verbose.set_level 1 ),
    ""
  );
  ( "-v", Arg.Unit (fun vl -> Verbose.set_level 1 ),
    "\t\tSet verbose mode on (i.e., verbose level = 1)"
  );
  ( "--verbose-level", Arg.Int(fun vl -> Verbose.set_level vl ), "<int>"
  );
  ( "-vl", Arg.Int(fun vl -> Verbose.set_level vl ),
    "<int>\tSet verbose level"
  );

  ( "--keep-nested-calls", Arg.Unit (fun _ -> Global.one_op_per_equation := false),
    "\tKeep nested calls"
  );


  ("-h", Arg.Unit (fun _ -> (Arg.usage arg_list usage_msg; exit 0)), "" );
  ("-help", Arg.Unit (fun _ -> (Arg.usage arg_list usage_msg; exit 0)),"" );
  ("--help", Arg.Unit (fun _ -> (Arg.usage arg_list usage_msg; exit 0)),
   "\tDisplay this list of options" )
]
and
    parse_args () = (
      Arg.parse arg_list  (* liste des options *)
Erwan Jahier's avatar
Erwan Jahier committed
        Global.add_infile (* arg par defaut = fichier d'entree *)
        usage_msg         (* message d'erreur *)
Erwan Jahier's avatar
Erwan Jahier committed

let test_lex ( lexbuf ) = (
  let tk = ref (Lexer.lexer lexbuf) in (
      while !tk <> Parser.TK_EOF do
Erwan Jahier's avatar
Erwan Jahier committed
        match (Lexer.token_code !tk) with 
            ( co , lxm ) ->
              printf "%s : %15s = \"%s\"\n"
                (Lxm.position lxm) co (Lxm.str lxm) ;
              tk := (Lexer.lexer lexbuf)
Erwan Jahier's avatar
Erwan Jahier committed
      done
Erwan Jahier's avatar
Erwan Jahier committed
    )   
Erwan Jahier's avatar
Erwan Jahier committed
)

(* Retourne un parse_tree *)
Erwan Jahier's avatar
Erwan Jahier committed
let lus_load lexbuf = (
  SolveIdent.recognize_predef_op 
    (Parser.sxLusFile Lexer.lexer lexbuf)
Erwan Jahier's avatar
Erwan Jahier committed
) 

(* Dump d'un packbody *)
let dump_body (pkg: SyntaxTree.packbody) = (
  let os = Format.formatter_of_out_channel stdout in
Erwan Jahier's avatar
Erwan Jahier committed
    SyntaxTreeDump.packbody os pkg      
Erwan Jahier's avatar
Erwan Jahier committed
)

(* Dump d'un name-space, pack ou modele ...  *)
let dump_ns (ns: SyntaxTree.pack_or_model) = (
  let os = Format.formatter_of_out_channel stdout in
    match ns with
Erwan Jahier's avatar
Erwan Jahier committed
        NSPack pf -> (
          (* Verbose.printf (lazy ("DUMP PACKDEF\n")); *)
          SyntaxTreeDump.packinfo os pf
        ) 
      | NSModel mf -> (
Erwan Jahier's avatar
Erwan Jahier committed
          (* Verbose.printf (lazy ("DUMP MODDEF\n")); *)
          SyntaxTreeDump.modelinfo os mf
        ) 
Erwan Jahier's avatar
Erwan Jahier committed
)

Erwan Jahier's avatar
Erwan Jahier committed
  (*
Erwan Jahier's avatar
Erwan Jahier committed
    Lance le parser et renvoie la liste name-spaces d'entre.   
Erwan Jahier's avatar
Erwan Jahier committed
    Dans le cas d'un fichier sans package, on lui donne
    comme nom le basename de infile.
  *)
type maybe_packed = 
  | Packed of SyntaxTree.pack_or_model list
  | Unpacked of SyntaxTree.pack_or_model

let (get_source_list : string list -> SyntaxTree.pack_or_model list) =
  fun infile_list -> 
Erwan Jahier's avatar
Erwan Jahier committed
    let (get_one_source : string -> string list * maybe_packed) = 
Erwan Jahier's avatar
Erwan Jahier committed
        let lexbuf = Global.lexbuf_of_file_name infile in
          match (lus_load lexbuf) with
            | PRPackBody(incl_files, pbdy) ->
                let nme = 
                  try Filename.chop_extension (Filename.basename infile) 
                  with _ -> print_string ("*** '"^infile^"': bad file name.\n"); exit 1
                in
                let pi = 
                  SyntaxTree.give_pack_this_name (Ident.pack_name_of_string nme) pbdy 
                in
                  incl_files, Unpacked (NSPack (Lxm.flagit pi (Lxm.dummy nme)))
            | PRPack_or_models(incl_files, nsl) -> incl_files, Packed nsl
Erwan Jahier's avatar
Erwan Jahier committed
    let rec (get_remaining_source_list : maybe_packed * string list * string list -> 
Erwan Jahier's avatar
Erwan Jahier committed
           maybe_packed * string list * string list) =
Erwan Jahier's avatar
Erwan Jahier committed
      fun (maybe_pack, compiled, to_be_compiled) -> 
Erwan Jahier's avatar
Erwan Jahier committed
        match to_be_compiled with
          | [] -> (maybe_pack, compiled, [])
          | infile::tail ->
              if List.mem infile compiled then
                get_remaining_source_list (maybe_pack, compiled, tail)
              else
                let included_files, pack = get_one_source infile in
                let new_maybe_pack =
                  match maybe_pack, pack with
                    | Unpacked _, _ 
                    | _, Unpacked _ -> 
                        print_string ("old-style (un-packaged) lustre files can " ^
                                        " not be mixed with packages, nor be " ^
                                        " defined in more than 1 file.");
                        exit 1
                    | Packed l1, Packed l2 -> Packed (l1@l2)
                in
                  get_remaining_source_list(
                    new_maybe_pack, 
                    infile::compiled, 
                    tail@included_files)
Erwan Jahier's avatar
Erwan Jahier committed
    let first_file = assert (infile_list <> []); List.hd infile_list in
    let included_files, first_pack = get_one_source first_file in
    let (pack_list,_,_) = get_remaining_source_list 
      (first_pack, [first_file], (List.tl infile_list) @ included_files)
Erwan Jahier's avatar
Erwan Jahier committed
        | Packed l -> l
        | Unpacked pack -> [pack]
Erwan Jahier's avatar
Erwan Jahier committed

  if Sys.file_exists !Global.outfile then Sys.remove !Global.outfile;
Erwan Jahier's avatar
Erwan Jahier committed
let main = (
  (* Compile.init_appli () ; *)
Erwan Jahier's avatar
Erwan Jahier committed
    Arg.usage arg_list usage_msg ;
    exit 1
Erwan Jahier's avatar
Erwan Jahier committed
  try (
    let nsl = get_source_list !Global.infiles in
      if !Global.main_node = "" then None else 
Erwan Jahier's avatar
Erwan Jahier committed
        Some (Ident.idref_of_string !Global.main_node)
      if !Global.outfile <> "" then Global.oc := open_out !Global.outfile;
      LicDump.dump_type_alias !Global.oc;
      LicDump.dump_node_alias !Global.oc;
Erwan Jahier's avatar
Erwan Jahier committed
  ) with
      Sys_error(s) ->
Erwan Jahier's avatar
Erwan Jahier committed
        prerr_string (s^"\n");
        my_exit 1
Erwan Jahier's avatar
Erwan Jahier committed
    | Global_error s ->
Erwan Jahier's avatar
Erwan Jahier committed
        print_global_error s ;
        my_exit 1
Erwan Jahier's avatar
Erwan Jahier committed
    | Parse_error ->
Erwan Jahier's avatar
Erwan Jahier committed
        print_compile_error (Lxm.last_made ()) "syntax error";
        my_exit 1
Erwan Jahier's avatar
Erwan Jahier committed
    | Compile_error(lxm,msg) -> 
Erwan Jahier's avatar
Erwan Jahier committed
        print_compile_error lxm msg ;
        my_exit 1
Erwan Jahier's avatar
Erwan Jahier committed
    | Assert_failure (file, line, col)  -> 
Erwan Jahier's avatar
Erwan Jahier committed
        prerr_string (
          "\n*** oops: an internal error occurred in file "^ file ^ ", line " ^ 
            (string_of_int line) ^ ", column " ^
            (string_of_int col) ^ "\n*** when compiling lustre program" ^
            (if List.length !Global.infiles > 1 then "s " else " ") ^
            (String.concat ", " !Global.infiles) ^ "\n") ;
        my_exit 2

        (* | Compile_node_error(nkey,lxm,msg) -> ( *)
        (* print_compile_node_error nkey lxm msg ; *)
        (* exit 1 *)
        (* ) *)
        (* | Global_node_error(nkey,msg) -> ( *)
        (* print_global_node_error nkey msg ; *)
        (* exit 1 *)
        (* ) *)
Erwan Jahier's avatar
Erwan Jahier committed

Erwan Jahier's avatar
Erwan Jahier committed
)