main.ml 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. open Lexing
  2. open Printf
  3. open Ast
  4. (* Compile infile to assembly code
  5. * in_channel -> int -> repr *)
  6. let compile infile verbose =
  7. let rec run_phases ir = function
  8. | [] -> ir
  9. | h::t -> run_phases (h ir) t
  10. in
  11. run_phases (Inputfile (infile, verbose)) [
  12. Parse.phase;
  13. Print.phase;
  14. Desug.phase;
  15. Print.phase;
  16. (*
  17. Context_analysis.phase;
  18. Print.phase;
  19. Typecheck.phase;
  20. Extern_vars.phase;
  21. Dim_reduce.phase;
  22. Bool_op.phase;
  23. Assemble.phase;
  24. Peephole.phase;
  25. Print.phase;
  26. *)
  27. ]
  28. let print_fancy_error msg loc verbose =
  29. let (fname, ystart, yend, xstart, xend) = loc in
  30. let line_s = if yend != ystart
  31. then sprintf "lines %d-%d" ystart yend
  32. else sprintf "line %d" ystart
  33. in
  34. let char_s = if xend != xstart || yend != ystart
  35. then sprintf "characters %d-%d" xstart xend
  36. else sprintf "character %d" xstart
  37. in
  38. eprintf "File \"%s\", %s, %s:\n" fname line_s char_s;
  39. eprintf "Error: %s\n" msg;
  40. if verbose >= 2 then (
  41. let file = open_in fname in
  42. (* skip lines until the first matched line *)
  43. for i = 1 to ystart - 1 do input_line file done;
  44. (* for each line in `loc`, print the source line with an underline *)
  45. for l = ystart to yend do
  46. let line = input_line file in
  47. let linewidth = String.length line in
  48. let left = if l = ystart then xstart else 1 in
  49. let right = if l = yend then xend else linewidth in
  50. if linewidth > 0 then (
  51. prerr_endline line;
  52. for i = 1 to left - 1 do prerr_char ' ' done;
  53. for i = left to right do prerr_char '^' done;
  54. prerr_endline ""
  55. )
  56. done
  57. )
  58. (* Main function, returns exit status
  59. * () -> int *)
  60. let main () =
  61. let filename = ref None in
  62. let verbose = ref 2 in
  63. let args = [
  64. ("-v", Arg.Int (fun i -> verbose := i), "Set verbosity")
  65. ] in
  66. let usage = "Usage: " ^ Sys.argv.(0) ^ " [ -v VERBOSITY ] FILE" in
  67. try
  68. Arg.parse args (fun s -> filename := Some s) usage;
  69. let _ = compile !filename !verbose in
  70. 0
  71. with
  72. | CompileError msg ->
  73. prerr_endline ("Error: " ^ msg);
  74. 1
  75. | NodeError (node, msg) ->
  76. print_fancy_error msg (Util.locof node) !verbose;
  77. 1
  78. | LocError (loc, msg) ->
  79. print_fancy_error msg loc !verbose;
  80. 1
  81. let _ = exit (main ())