whole_func_string: function () {
          var input = this.source;
          this.blockComments = [];
          for (;;) {
              var ch = input[this.cursor++];
              var next = input[this.cursor];
              // handle \r, \r\n and (always preferable) \n
              if (ch === '\r') {
                  // if the next character is \n, we don't care about this at all
                  if (next === '\n') continue;
  
                  // otherwise, we want to consider this as a newline
                  ch = '\n';
              }
  
              if (ch === '\n' && !this.scanNewlines) {
                  this.lineno++;
              } else if (ch === '/' && next === '*') {
                  var commentStart = ++this.cursor;
                  for (;;) {
                      ch = input[this.cursor++];
                      if (ch === undefined)
                          throw this.newSyntaxError("Unterminated comment");
  
                      if (ch === '*') {
                          next = input[this.cursor];
                          if (next === '/') {
                              var commentEnd = this.cursor - 1;
                              this.cursor++;
                              break;
                          }
                      } else if (ch === '\n') {
                          this.lineno++;
                      }
                  }
                  this.blockComments.push(input.substring(commentStart, commentEnd));
              } else if ((ch === '/' && next === '/') ||
                         (this.allowHTMLComments && ch === '<' && next === '!' &&
                          input[this.cursor + 1] === '-' && input[this.cursor + 2] === '-' &&
                          (this.cursor += 2))) {
                  this.cursor++;
                  for (;;) {
                      ch = input[this.cursor++];
                      next = input[this.cursor];
                      if (ch === undefined)
                          return;
  
                      if (ch === '\r') {
                          // check for \r\n
                          if (next !== '\n') ch = '\n';
                      }
  
                      if (ch === '\n') {
                          if (this.scanNewlines) {
                              this.cursor--;
                          } else {
                              this.lineno++;
                          }
                          break;
                      }
                  }
              } else if (!(ch in definitions.whitespace)) {
                  this.cursor--;
                  return;
              }
          }
      }
func_code_string: function () {
          var input = this.source;
          this.blockComments = [];
          for (;;) {
              var ch = input[this.cursor++];
              var next = input[this.cursor];
              // handle \r, \r\n and (always preferable) \n
              if (ch === '\r') {
                  // if the next character is \n, we don't care about this at all
                  if (next === '\n') continue;
  
                  // otherwise, we want to consider this as a newline
                  ch = '\n';
              }
  
              if (ch === '\n' && !this.scanNewlines) {
                  this.lineno++;
              } else if (ch === '/' && next === '*') {
                  var commentStart = ++this.cursor;
                  for (;;) {
                      ch = input[this.cursor++];
                      if (ch === undefined)
                          throw this.newSyntaxError("Unterminated comment");
  
                      if (ch === '*') {
                          next = input[this.cursor];
                          if (next === '/') {
                              var commentEnd = this.cursor - 1;
                              this.cursor++;
                              break;
                          }
                      } else if (ch === '\n') {
                          this.lineno++;
                      }
                  }
                  this.blockComments.push(input.substring(commentStart, commentEnd));
              } else if ((ch === '/' && next === '/') ||
                         (this.allowHTMLComments && ch === '<' && next === '!' &&
                          input[this.cursor + 1] === '-' && input[this.cursor + 2] === '-' &&
                          (this.cursor += 2))) {
                  this.cursor++;
                  for (;;) {
                      ch = input[this.cursor++];
                      next = input[this.cursor];
                      if (ch === undefined)
                          return;
  
                      if (ch === '\r') {
                          // check for \r\n
                          if (next !== '\n') ch = '\n';
                      }
  
                      if (ch === '\n') {
                          if (this.scanNewlines) {
                              this.cursor--;
                          } else {
                              this.lineno++;
                          }
                          break;
                      }
                  }
              } else if (!(ch in definitions.whitespace)) {
                  this.cursor--;
                  return;
              }
          }
      }
func_documentation_string: Eat comments and whitespace.