mpri-funcprog-project/src/Main.ml

125 lines
3.3 KiB
OCaml
Raw Normal View History

2017-12-13 14:04:28 +01:00
(* -------------------------------------------------------------------------- *)
(* Parse the command line. *)
let debug =
ref false
2018-02-15 22:19:14 +01:00
let light_debug =
ref false
2018-02-16 20:53:43 +01:00
let no_varvarbind = ref false
let no_const_propagation = ref false
2017-12-13 14:04:28 +01:00
let filenames =
ref []
let record filename =
filenames := filename :: !filenames
let options =
Arg.align [
"--debug", Arg.Set debug, " Enable debugging output";
2018-02-15 22:19:14 +01:00
"--light-debug", Arg.Set light_debug, " Enable debugging output";
2018-02-16 20:53:43 +01:00
"--no-var-var-bind", Arg.Set no_varvarbind,
"Disable var/var bind suppression";
"--no-const-propagation", Arg.Set no_const_propagation,
"Disable constants propagation";
2017-12-13 14:04:28 +01:00
]
let usage =
Printf.sprintf "Usage: %s <options> <filename>" Sys.argv.(0)
let () =
Arg.parse options record usage
let debug =
!debug
2018-02-15 22:19:14 +01:00
let light_debug =
!light_debug
2017-12-13 14:04:28 +01:00
2018-02-16 20:53:43 +01:00
let no_varvarbind = !no_varvarbind
let no_const_propagation = !no_const_propagation
2017-12-13 14:04:28 +01:00
let filenames =
List.rev !filenames
(* -------------------------------------------------------------------------- *)
(* Printing a syntax tree in an intermediate language (for debugging). *)
let print_delimiter () =
Printf.eprintf "----------------------------------------";
Printf.eprintf "----------------------------------------\n"
2018-02-15 22:19:14 +01:00
let dump (phase : string) (show : 'term -> string) (light: bool) (t : 'term) =
if debug || (light_debug && light) then begin
2017-12-13 14:04:28 +01:00
print_delimiter();
Printf.eprintf "%s:\n\n%s\n\n%!" phase (show t)
end;
t
(* -------------------------------------------------------------------------- *)
(* Reading and parsing a file. *)
let read filename : RawLambda.term =
try
let contents = Utils.file_get_contents filename in
let lexbuf = Lexing.from_string contents in
Error.set_filename lexbuf filename;
try
Parser.entry Lexer.entry lexbuf
with
| Parser.Error ->
Error.error (Error.place lexbuf) "Syntax error."
with
| Sys_error msg ->
prerr_endline msg;
exit 1
(* -------------------------------------------------------------------------- *)
(* Printing the final C program on the standard output channel. *)
let output (p : C.program) : unit =
Printf.printf "#include<stdlib.h>\n";
Printf.printf "#include<stdio.h>\n";
Printf.printf "#include \"prologue.h\"\n\n";
let print_program = PrintCommon.print_program PrintC.p_decl_or_function in
let buf = Buffer.create 1024 in
PrintCommon.printf_of_pprint_pretty print_program buf p;
print_endline (Buffer.contents buf)
(* -------------------------------------------------------------------------- *)
(* The complete processing pipeline. Beautiful, isn't it? *)
2018-02-16 20:53:43 +01:00
let skip x = x
2017-12-13 14:04:28 +01:00
let process filename =
filename
|> read
2018-02-15 22:19:14 +01:00
|> dump "RawLambda" RawLambda.show_term false
2017-12-13 14:04:28 +01:00
|> Cook.cook_term
2018-02-15 22:19:14 +01:00
|> dump "Lambda" Lambda.show_term false
2017-12-13 14:04:28 +01:00
|> CPS.cps_term
2018-02-15 22:19:14 +01:00
|> dump "Tail" Tail.show_term false
|> dump "PrettyTail" PrettyTail.show true
2017-12-13 14:04:28 +01:00
|> Defun.defun_term
2018-02-16 20:53:43 +01:00
|> (if no_varvarbind then skip else VarVarBind.clean_var_var_bind)
|> (if no_const_propagation then skip else
ConstantPropag.constant_propagation)
2018-02-15 22:19:14 +01:00
|> dump "Top" Top.show_program false
|> dump "PrettyTop" PrettyTop.show true
2017-12-13 14:04:28 +01:00
|> Finish.finish_program
2018-02-15 22:19:14 +01:00
|> dump "C" C.show_program false
2017-12-13 14:04:28 +01:00
|> output
(* -------------------------------------------------------------------------- *)
(* The main program. *)
let () =
List.iter process filenames