function scanIdentifierOrKeyword(beginIndex, code) {
  // Keep track of any unicode escape sequences.
  let escapedCharCodes;
  if (code === 92) {  // \
    code = readUnicodeEscapeSequence();
    escapedCharCodes = [code];
  }

  if (!isIdentifierStart(code)) {
    reportError(
        `Character code '${code}' is not a valid identifier start char`,
        beginIndex);
    return createToken(ERROR, beginIndex);
  }

  for (;;) {
    code = currentCharCode;
    if (isIdentifierPart(code)) {
      next();
    } else if (code === 92) {  // \
      next();
      code = readUnicodeEscapeSequence();
      if (!escapedCharCodes)
        escapedCharCodes = [];
      escapedCharCodes.push(code);
      if (!isIdentifierPart(code))
        return createToken(ERROR, beginIndex);
    } else {
      break;
    }
  }

  let value = input.slice(beginIndex, index);
  let keywordType = getKeywordType(value);
  if (keywordType)
    return new KeywordToken(value, keywordType, getTokenRange(beginIndex));

  if (escapedCharCodes) {
    let i = 0;
    value = value.replace(/\\u..../g, function(s) {
      return String.fromCharCode(escapedCharCodes[i++]);
    });
  }

  return new IdentifierToken(getTokenRange(beginIndex), value);
}
@param {number} beginIndex
@param {number} code
@return {Token}