function scan()

in jones-test/lib/DocsTest.js [58:152]


function scan(text) { 
  var i = 0;                  // the index of the current character 
  var c = text.charAt(i);     // the current character
  var list = [];              // functions found in the file
  var constructor = 0;        // constructor function found in file
  var tok;                    // the current token

  function isUpper(c)   { return (c >= 'A' && c <= 'Z'); }
  function isLower(c)   { return (c >= 'a' && c <= 'z'); }
  function isAlpha(c)   { return (isUpper(c) || isLower(c)); }
  function isNumeric(c) { return (c >= '0' && c <= '9'); }
  function isJsFunctionName(c) { 
    return( isAlpha(c) || isNumeric(c) || (c == '_'));
  }
  
  function peek() {
    return text.charAt(i + 1);
  }

  function advance(n) {       // Advance to next character
    var amt = n || 1;
    if(i + amt >= text.length) {
      i = text.length;
      c = '';
    }
    else { 
      i += amt;
      c = text.charAt(i);
    }
  }

  function Token() {
    this.str = c;
    advance();
  }
    
  Token.prototype.consume = function() {
    this.str += c;
    advance();
  };
    
  Token.prototype.commit = function() {
    var docFunction;
    if(isUpper(this.str.charAt(0))) { 
      constructor = this.str;
    } else {
      docFunction = new DocumentedFunction(constructor, this.str);
      list.push(docFunction);
    }
  };

  // Start scanning
  while(c) {
  
    while(c != '' && c <= ' ') { advance(); }          // whitespace
     
    if(c == '/' && peek() == '/') {                    // comment to EOL  
      advance(2);
      while(c !== '\n' && c !== '\r' && c !== '') {
        advance();
      }
    }
    
    else if (c === '/' && peek() === '*') {            // comment to */
      advance(2); 
      while(! (c == '*' && peek() == '/')) {
        advance();
      }
      if(c === '') { throw new Error("Unterminated comment"); }
      advance(2);
    }
 
    else if(isAlpha(c)) {                              // candidate functions
      tok = new Token();
      while(isJsFunctionName(c)) {
        tok.consume();
      }
      if(c == '(') {  // IT WAS A FUNCTION
        tok.commit();
        advance();   
        /* Now, there may be more functions (callbacks) defined as arguments,
           so we skip to the next semicolon */
        while(c && c !== ';') {
          advance();
        }
      }
      // delete tok;
    }
    
    else {
      advance();
    }
  }
  return list;
}