main.ml 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. | [] -> input
  9. | h::t -> run_phases (h input) t
  10. in
  11. run_phases (Args args) [
  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 args = {
  62. filename = None;
  63. verbose = 2
  64. } in
  65. let args_spec = [
  66. ("-v", Arg.Int (fun i -> args.verbose <- i), "Set verbosity")
  67. ] in
  68. let usage = "Usage: " ^ Sys.argv.(0) ^ " [ -v VERBOSITY ] FILE" in
  69. try
  70. try
  71. Arg.parse args_spec (fun s -> args.filename <- Some s) usage;
  72. compile args;
  73. 0
  74. with
  75. | InvalidNode ->
  76. raise (CompileError "invalid node")
  77. | InvalidInput name ->
  78. raise (CompileError ("invalid input for phase \"" ^ name ^ "\""))
  79. | NodeError (node, msg) ->
  80. raise (LocError (Util.locof node, msg))
  81. with
  82. | CompileError msg ->
  83. eprintf "Error: %s\n" msg;
  84. 1
  85. | LocError (loc, msg) ->
  86. print_fancy_error msg loc args.verbose;
  87. 1
  88. let _ = exit (main ())