main.ml 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. infile = None;
  65. outfile = None;
  66. verbose = 2;
  67. cpp = true;
  68. } in
  69. let args_spec = [
  70. ("-o", Arg.String (fun s -> args.outfile <- Some s),
  71. "Output file (defaults to foo.s for foo.cvc)");
  72. ("-v", Arg.Int (fun i -> args.verbose <- i),
  73. "Set verbosity (0|1|2)");
  74. ("-nocpp", Arg.Unit (fun i -> args.cpp <- false),
  75. "Disable C preprocessor");
  76. ] in
  77. let usage = "Usage: " ^ Sys.argv.(0) ^ " [-o <file>] [-nocpp] [-v <verbosity>] [<file>]" in
  78. try
  79. try
  80. Arg.parse args_spec (fun s -> args.infile <- Some s) usage;
  81. compile args;
  82. 0
  83. with
  84. | InvalidNode ->
  85. raise (CompileError "invalid node")
  86. | InvalidInput name ->
  87. raise (CompileError ("invalid input for phase \"" ^ name ^ "\""))
  88. | NodeError (node, msg) ->
  89. raise (LocError (Util.locof node, msg))
  90. with
  91. | CompileError msg ->
  92. eprintf "Error: %s\n" msg;
  93. 1
  94. | LocError (loc, msg) ->
  95. print_fancy_error msg loc args.verbose;
  96. 1
  97. let _ = exit (main ())