// Copyright 2011 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_STRINGS_CHAR_PREDICATES_INL_H_
#define V8_STRINGS_CHAR_PREDICATES_INL_H_

#include "src/strings/char-predicates.h"

namespace v8 {
namespace internal {

// If c is in 'A'-'Z' or 'a'-'z', return its lower-case.
// Else, return something outside of 'A'-'Z' and 'a'-'z'.
// Note: it ignores LOCALE.
inline constexpr int AsciiAlphaToLower(uc32 c) { return c | 0x20; }

inline constexpr bool IsCarriageReturn(uc32 c) { return c == 0x000D; }

inline constexpr bool IsLineFeed(uc32 c) { return c == 0x000A; }

inline constexpr bool IsAsciiIdentifier(uc32 c) {
  return IsAlphaNumeric(c) || c == '$' || c == '_';
}

inline constexpr bool IsAlphaNumeric(uc32 c) {
  return IsInRange(AsciiAlphaToLower(c), 'a', 'z') || IsDecimalDigit(c);
}

inline constexpr bool IsDecimalDigit(uc32 c) {
  // ECMA-262, 3rd, 7.8.3 (p 16)
  return IsInRange(c, '0', '9');
}

inline constexpr bool IsHexDigit(uc32 c) {
  // ECMA-262, 3rd, 7.6 (p 15)
  return IsDecimalDigit(c) || IsInRange(AsciiAlphaToLower(c), 'a', 'f');
}

inline constexpr bool IsOctalDigit(uc32 c) {
  // ECMA-262, 6th, 7.8.3
  return IsInRange(c, '0', '7');
}

inline constexpr bool IsNonOctalDecimalDigit(uc32 c) {
  return IsInRange(c, '8', '9');
}

inline constexpr bool IsBinaryDigit(uc32 c) {
  // ECMA-262, 6th, 7.8.3
  return c == '0' || c == '1';
}

inline constexpr bool IsAsciiLower(uc32 c) { return IsInRange(c, 'a', 'z'); }

inline constexpr bool IsAsciiUpper(uc32 c) { return IsInRange(c, 'A', 'Z'); }

inline constexpr uc32 ToAsciiUpper(uc32 c) {
  return c & ~(IsAsciiLower(c) << 5);
}

inline constexpr uc32 ToAsciiLower(uc32 c) {
  return c | (IsAsciiUpper(c) << 5);
}

inline constexpr bool IsRegExpWord(uc16 c) {
  return IsInRange(AsciiAlphaToLower(c), 'a', 'z') || IsDecimalDigit(c) ||
         (c == '_');
}

inline constexpr bool IsRegExpNewline(uc16 c) {
  //          CR             LF             LS             PS
  return c != 0x000A && c != 0x000D && c != 0x2028 && c != 0x2029;
}

// Constexpr cache table for character flags.
enum AsciiCharFlags {
  kIsIdentifierStart = 1 << 0,
  kIsIdentifierPart = 1 << 1,
  kIsWhiteSpace = 1 << 2,
  kIsWhiteSpaceOrLineTerminator = 1 << 3
};
constexpr uint8_t BuildAsciiCharFlags(uc32 c) {
  return ((IsAsciiIdentifier(c) || c == '\\')
              ? (kIsIdentifierPart |
                 (!IsDecimalDigit(c) ? kIsIdentifierStart : 0))
              : 0) |
         ((c == ' ' || c == '\t' || c == '\v' || c == '\f')
              ? kIsWhiteSpace | kIsWhiteSpaceOrLineTerminator
              : 0) |
         ((c == '\r' || c == '\n') ? kIsWhiteSpaceOrLineTerminator : 0);
}
const constexpr uint8_t kAsciiCharFlags[128] = {
#define BUILD_CHAR_FLAGS(N) BuildAsciiCharFlags(N),
    INT_0_TO_127_LIST(BUILD_CHAR_FLAGS)
#undef BUILD_CHAR_FLAGS
};

bool IsIdentifierStart(uc32 c) {
  if (!IsInRange(c, 0, 127)) return IsIdentifierStartSlow(c);
  DCHECK_EQ(IsIdentifierStartSlow(c),
            static_cast<bool>(kAsciiCharFlags[c] & kIsIdentifierStart));
  return kAsciiCharFlags[c] & kIsIdentifierStart;
}

bool IsIdentifierPart(uc32 c) {
  if (!IsInRange(c, 0, 127)) return IsIdentifierPartSlow(c);
  DCHECK_EQ(IsIdentifierPartSlow(c),
            static_cast<bool>(kAsciiCharFlags[c] & kIsIdentifierPart));
  return kAsciiCharFlags[c] & kIsIdentifierPart;
}

bool IsWhiteSpace(uc32 c) {
  if (!IsInRange(c, 0, 127)) return IsWhiteSpaceSlow(c);
  DCHECK_EQ(IsWhiteSpaceSlow(c),
            static_cast<bool>(kAsciiCharFlags[c] & kIsWhiteSpace));
  return kAsciiCharFlags[c] & kIsWhiteSpace;
}

bool IsWhiteSpaceOrLineTerminator(uc32 c) {
  if (!IsInRange(c, 0, 127)) return IsWhiteSpaceOrLineTerminatorSlow(c);
  DCHECK_EQ(
      IsWhiteSpaceOrLineTerminatorSlow(c),
      static_cast<bool>(kAsciiCharFlags[c] & kIsWhiteSpaceOrLineTerminator));
  return kAsciiCharFlags[c] & kIsWhiteSpaceOrLineTerminator;
}

bool IsLineTerminatorSequence(uc32 c, uc32 next) {
  if (!unibrow::IsLineTerminator(c)) return false;
  if (c == 0x000d && next == 0x000a) return false;  // CR with following LF.
  return true;
}

}  // namespace internal
}  // namespace v8

#endif  // V8_STRINGS_CHAR_PREDICATES_INL_H_
