 #  object will have a field 'where' that signifies which stage of processing
 #  it failed.
 #
-PalCompiler = (inputText, options={}) ->
+PalCompiler.compile = (inputText, options=defaultOptions) ->
+  # Figure out which compilation stages should be enabled.
+  stages = prepareStages options
+  # Then do them, returning their final result.
+  executeStages inputText, stages
+
+
+# Returns a list of all stages need for compilation.
+prepareStages = (opts) ->
+  # Every compilation involves the parsing stage:
+  stages = [compilationStage.parse]
+  (->
+    # Return right away if we only need to check syntax.
+    return if opts.syntaxOnly
+
+    stages.push compilationStage.analyze
+    # Return again if we just want semantic analysis
+    return if opts.analysisOnly
+
+    # Add the code generation stage!
+    stages.push compilationStage.generateJS
+
+    stages.push compilationStage.eval if opts.shouldEval
+  )()
+
+  stages
+
+
+executeStages = (initialValue, stages) ->
+  # Set some default fields in the result object.
   result =
     ast: null
     src: null
     fn: null
     error: null
-
-  stages = [
-    ['ast', PalCompiler.parse],
-    ['src', PalCompiler.generateJS]
-    ['fn',  PalCompiler.createFn]
-  ]
 
   # Set up the initial state of the weird continuation loop thing.
   stageNo = 0

        result

  # Start the continuation loop and return its result.
  doNext(null, inputText)


PalCompiler.parse = (inputText, cb) ->
  try
    ast = PalParser.parse inputText, 'program'
  catch err
    return cb err

  cb null, ast

PalCompiler.generateJS = (ast, cb) ->
  codeGenerator = new JSCodeGenerator
  src = codeGenerator.compile ast


# This is the main entry point for the Pal compiler.

PalParser = require './parser'

# The export is just the object with all of the helper methods.  The export
# also doubles as a shortcut to the compile() static method.
module.exports = PalCompiler = ->
  PalCompiler.compile.apply(PalCompiler,  arguments)

defaultOptions =
  shouldEval:   no
  syntaxOnly:   no
  analysisOnly: no

# Call the compiler with a string and if all goes well, get back a result
# object with:
#
#  * 'ast' -- The abstract syntax tree, fresh from parsing.
