text: /*!
   * parser.js
   *
   * Builds an abstract syntax tree from a token
   * stream generated by the scanner
   */
  
  var Assert = require('assert');
  var Lisp = require('./lisp');
  var TokenStream = require('./tokenstream');
  var Scanner = require('./scanner');
  
  var parse = exports.parse = function parse(input, pair) {
  
    var stream = TokenStream.createStream(Scanner.tokenize(input));
  
    function buildAST(depth) {
      var token = stream.next(),
          skip = false,
          parsed;
  
      switch (token.type) {
      case 'L_PAREN':
        parsed = buildAST(depth + 1);
        break;
  
      case 'R_PAREN':
        depth -= 1;
        parsed = Lisp.nil();
        skip = true;
        break;
  
      case 'DOT':
        parsed = buildAST(depth - 1);
        depth -= 1;
        break;
  
      case 'NUMBER':
        parsed = Lisp.number(token.token);
        break;
  
      case 'STRING':
        parsed = Lisp.string(token.token);
        break;
  
      case 'SYMBOL':
        parsed = Lisp.symbol(token.token);
        break;
  
      case 'QUOTE':
        parsed = Lisp.quote(buildAST(0));
        break;
  
      default:
        parsed = Lisp.nil();
      }
  
      if (depth === 0 || skip) {
        return parsed;
      }
  
      return Lisp.cons(parsed, buildAST(depth));
    }
  
    return buildAST(0);
  };
  