main.ml 2.8 KB

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