Add `--debug-stop-after-step` flag.

This exposes the existing `stop_after_step` functionality that is used
in unit tests through the command line, which allows the IR to be
inspected/analyzed.
diff --git a/compiler/front_end/emboss_front_end.py b/compiler/front_end/emboss_front_end.py
index c62638d..63697d7 100644
--- a/compiler/front_end/emboss_front_end.py
+++ b/compiler/front_end/emboss_front_end.py
@@ -56,6 +56,12 @@
         "before symbol resolution.",
     )
     parser.add_argument(
+        "--debug-stop-before-step",
+        type=str,
+        nargs=1,
+        help="Stop processing before the specified step.",
+    )
+    parser.add_argument(
         "--debug-show-full-ir",
         action="store_true",
         help="Show the final IR of the main input file.",
@@ -146,7 +152,7 @@
     return _find_and_read
 
 
-def parse_and_log_errors(input_file, import_dirs, color_output):
+def parse_and_log_errors(input_file, import_dirs, color_output, stop_before_step=None):
     """Fully parses an .emb and logs any errors.
 
     Arguments:
@@ -158,7 +164,7 @@
       (ir, debug_info, errors)
     """
     ir, debug_info, errors = glue.parse_emboss_file(
-        input_file, _find_in_dirs_and_read(import_dirs)
+        input_file, _find_in_dirs_and_read(import_dirs), stop_before_step=stop_before_step
     )
     if errors:
         _show_errors(errors, ir, color_output)
@@ -168,7 +174,7 @@
 
 def main(flags):
     ir, debug_info, errors = parse_and_log_errors(
-        flags.input_file[0], flags.import_dirs, flags.color_output
+        flags.input_file[0], flags.import_dirs, flags.color_output, stop_before_step=flags.debug_stop_before_step[0],
     )
     if errors:
         return 1
diff --git a/compiler/front_end/glue.py b/compiler/front_end/glue.py
index 2744086..d59f45e 100644
--- a/compiler/front_end/glue.py
+++ b/compiler/front_end/glue.py
@@ -19,6 +19,7 @@
 """
 
 import collections
+import sys
 
 from compiler.front_end import attribute_checker
 from compiler.front_end import constraints
@@ -323,9 +324,8 @@
         constraints.check_constraints,
         write_inference.set_write_methods,
     )
-    assert stop_before_step in [None] + [
-        f.__name__ for f in passes
-    ], "Bad value for stop_before_step."
+    valid_step_names = [f.__name__ for f in passes]
+    assert stop_before_step in [None] + valid_step_names, f"Bad value '{stop_before_step}' for stop_before_step.  Valid values: " + " ".join(valid_step_names)
     # Some parts of the IR are synthesized from "natural" parts of the IR, before
     # the natural parts have been fully error checked.  Because of this, the
     # synthesized parts can have errors; in a couple of cases, they can have
@@ -371,7 +371,9 @@
     deferred_errors = []
     for function in passes:
         if stop_before_step == function.__name__:
+            print("Stopping before", stop_before_step, file=sys.stderr)
             return (ir, [])
+        print("Running", function.__name__, file=sys.stderr)
         errors, hidden_errors = error.split_errors(function(ir))
         if errors:
             return (None, errors)