let main () =
  let ast = ref [] in
  try
    let inchan = if Sys.argv.(1) = "stdin" then stdin else open_in (Sys.argv.(1)) in
    let lexbuf = Lexing.from_channel inchan in
    let _ = (print_string (String.concat "" ["\nBeginning parse of file: ";(Sys.argv.(1));"\n"])); flush stdout; in
    let _ = ast := Bmdparse.program Bmdlex.bmd_lang lexbuf in
    let _ = print_string "Compiling state machines...\n"; flush stdout; in
    let _ = ast := Bmdfsmc.compile_fsm !ast in
      
      (** Output the compiled fsm code. We do *not* re-parse, this is just for debugging. **)

    let src_to_src_file = open_out "temp.bmd" in
    let _ = output_string src_to_src_file (Ast.string_of_ast !ast) in  
    let _ = Bmdtc.reset_link_buffer in
    let _  = print_string "Type checking...\n"; flush stdout in
    let is_typed = Bmdtc.is_typed !ast in
      if is_typed then
        let _ = print_string "Compiling...\n"; flush stdout; in
        let ir_buf = Bmdirc.compile_ir !ast in
        let final_buf = Bmdfc.compile_buffer ir_buf in
        let do_file_output = ((Array.length Sys.argv) >= 3) in
        let outfile = if do_file_output then open_out Sys.argv.(2) else stdout in
        let _ = output_string outfile (Bmdtc.get_link_buffer()) in
        let _ = Bmdfc.print_buffer outfile final_buf in
        let _ = print_string "Done.\n"; flush stdout in
          ()
      else
        let _ = print_string "Typecheck failure.\n"; flush stdout; in
          ()
  with
      Parsing.Parse_error -> 
        begin 
          print_string "Syntax error on line ";
          print_string (string_of_int !Bmdlex.line_count);
          print_string ".\n";
          flush stdout; 
        end
    | Failure s ->
        begin
          print_string "Failure: ";
          print_string s;
          print_string "\n";
          flush stdout;
        end
    | Sys_error s ->
        begin
          print_string "Could not open input file ";
          print_string s;
          print_string "\n";
          flush stdout;
        end 
    | Bmdfsmc.Fsm_error s ->
        begin
          print_string s;
          print_string "\n";
          flush stdout;
        end 
    | _ ->
        begin
          print_string "Compilation failed.\n";
        end