main.ml 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. open Printf
  2. open Lexing
  3. open Types
  4. open Util
  5. let always _ = true
  6. let when_optimize _ = args.optimize
  7. let phases = [
  8. ("load", Load.phase, always,
  9. "Load input file");
  10. ("parse", Parse.phase, always,
  11. "Parse input");
  12. ("desug", Desug.phase, always,
  13. "Desugaring");
  14. ("context", Context_analysis.phase, always,
  15. "Context analysis");
  16. ("typecheck", Typecheck.phase, always,
  17. "Type checking");
  18. ("expand", Expand_dims.phase, always,
  19. "Expand array dimensions");
  20. ("boolop", Bool_op.phase, always,
  21. "Convert bool operations");
  22. ("dimreduce", Dim_reduce.phase, always,
  23. "Array dimension reduction");
  24. ("extern", Extern_vars.phase, always,
  25. "Create getters and setters for extern variables");
  26. ("constant", Constant_propagation.phase, when_optimize,
  27. "Constant propagation");
  28. ("index", Index_analysis.phase, always,
  29. "Index analysis");
  30. ("assemble", Assemble.phase, always,
  31. "Assembly");
  32. ("peephole", Peephole.phase, when_optimize,
  33. "Peephole optimization");
  34. ("output", Output.phase, always,
  35. "Output assembly");
  36. ]
  37. (* Compile CVC file to assembly code
  38. * in_channel -> int -> repr *)
  39. let compile () =
  40. let rec run_phases input = function
  41. | [] -> ()
  42. | (id, phase, cond, msg) :: tl ->
  43. let output = if cond () then (
  44. log_plain_line 1 (expand 13 ("- " ^ id ^ ":") ^ msg);
  45. let output = phase input in
  46. if id = args.endphase || args.verbose = 2 then (
  47. let _ = Print.phase output in ()
  48. );
  49. output
  50. ) else input in
  51. if id = args.endphase then () else run_phases output tl
  52. in
  53. run_phases Empty phases
  54. (* Main function, returns exit status
  55. * Command-line arguments are stored in Util.args
  56. * () -> int *)
  57. let main () =
  58. let rec upto_usage = function
  59. | [] -> ""
  60. | (id, _, _, msg) :: tl ->
  61. "\n" ^ repeat " " 12 ^ expand 10 id ^ ": " ^ msg ^ (upto_usage tl)
  62. in
  63. let args_spec = [
  64. ("<file>", Arg.Rest (fun s -> ()),
  65. " Optional input file (default is to read from stdin)");
  66. ("-o", Arg.String (fun s -> args.outfile <- Some s),
  67. "<file> Output file (defaults to foo.s for foo.cvc)");
  68. ("-v", Arg.Int (fun i -> args.verbose <- i),
  69. "<num> Set verbosity (0: nothing, 1: phase titles, 2: intermediate, 3: debug)");
  70. ("-nocpp", Arg.Unit (fun _ -> args.cpp <- false),
  71. " Disable C preprocessor");
  72. ("-cpp", Arg.Unit (fun _ -> args.cpp <- true),
  73. " Enable C preprocessor (overwrite earlier -nocpp)");
  74. ("-noopt", Arg.Unit (fun _ -> args.optimize <- false),
  75. " Disable optimization");
  76. ("-opt", Arg.Unit (fun _ -> args.optimize <- true),
  77. " Enable optimization (overwrite earlier -nocpp)");
  78. ("-upto", Arg.String (fun s -> args.endphase <- s),
  79. "<phase> Stop after the specified phase, and print the intermediate " ^
  80. "representation to stderr.\n " ^
  81. " Possible options are (in order of execution):" ^ upto_usage phases);
  82. ] in
  83. let usage =
  84. "Usage: " ^ Sys.argv.(0) ^ " [-o <file>] [-nocpp] [-noopt] " ^
  85. " [-v <verbosity>] [-upto <phase>] [<file>]"
  86. in
  87. try
  88. try
  89. Arg.parse args_spec (fun s -> args.infile <- Some s) usage;
  90. compile ();
  91. 0
  92. with
  93. (*| InvalidNode ->
  94. raise (CompileError "invalid node")*)
  95. | InvalidInput name ->
  96. raise (CompileError ("invalid input for phase \"" ^ name ^ "\""))
  97. | NodeError (node, msg) ->
  98. (* If no location is given, just stringify the node to at least give
  99. * some information *)
  100. let msg = if locof node = noloc then
  101. msg ^ "\nnode: " ^ Stringify.node2str node
  102. else msg in
  103. raise (LocError (locof node, msg))
  104. with
  105. | CompileError msg ->
  106. eprintf "Error: %s\n" msg;
  107. 1
  108. | LocError (loc, msg) ->
  109. prerr_loc_msg loc ("Error: " ^ msg);
  110. 1
  111. | EmptyError ->
  112. 1
  113. let _ = exit (main ())