var utils = require(“./utils”);

module.exports = {

/*
 * Compiler passes.
 *
 * Each pass is a function that is passed the AST. It can perform checks on it
 * or modify it as needed. If the pass encounters a semantic error, it throws
 * |PEG.GrammarError|.
 */
passes: {
  check: {
    reportMissingRules:  require("./compiler/passes/report-missing-rules"),
    reportLeftRecursion: require("./compiler/passes/report-left-recursion")
  },
  transform: {
    removeProxyRules:    require("./compiler/passes/remove-proxy-rules")
  },
  generate: {
    generateBytecode:    require("./compiler/passes/generate-bytecode"),
    generateJavascript:  require("./compiler/passes/generate-javascript")
  }
},

/*
 * Generates a parser from a specified grammar AST. Throws |PEG.GrammarError|
 * if the AST contains a semantic error. Note that not all errors are detected
 * during the generation and some may protrude to the generated parser and
 * cause its malfunction.
 */
compile: function(ast, passes) {
  var options = arguments.length > 2 ? utils.clone(arguments[2]) : {},
      stage;

  /*
   * Extracted into a function just to silence JSHint complaining about
   * creating functions in a loop.
   */
  function runPass(pass) {
    pass(ast, options);
  }

  utils.defaults(options, {
    allowedStartRules:  [ast.rules[0].name],
    cache:              false,
    optimize:           "speed",
    output:             "parser"
  });

  for (stage in passes) {
    if (passes.hasOwnProperty(stage)) {
      utils.each(passes[stage], runPass);
    }
  }

  switch (options.output) {
    case "parser": return eval(ast.code);
    case "source": return ast.code;
  }
}

};