13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#ifndef ES2PANDA_LEXER_TOKEN_NUMBER_H
173af6ab5fSopenharmony_ci#define ES2PANDA_LEXER_TOKEN_NUMBER_H
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ci#include "macros.h"
203af6ab5fSopenharmony_ci#include "util/ustring.h"
213af6ab5fSopenharmony_ci#include "util/enumbitops.h"
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ci#include <cstdint>
243af6ab5fSopenharmony_ci#include <type_traits>
253af6ab5fSopenharmony_ci#include <utility>
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_cinamespace ark::es2panda::lexer {
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_ciusing ENUMBITOPS_OPERATORS;
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_cienum class NumberFlags : uint32_t {
323af6ab5fSopenharmony_ci    NONE,
333af6ab5fSopenharmony_ci    BIGINT = 1U << 0U,
343af6ab5fSopenharmony_ci    DECIMAL_POINT = 1U << 1U,
353af6ab5fSopenharmony_ci    EXPONENT = 1U << 2U,
363af6ab5fSopenharmony_ci    ERROR = 1U << 3U,
373af6ab5fSopenharmony_ci};
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_ci}  // namespace ark::es2panda::lexer
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_citemplate <>
423af6ab5fSopenharmony_cistruct enumbitops::IsAllowedType<ark::es2panda::lexer::NumberFlags> : std::true_type {
433af6ab5fSopenharmony_ci};
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_cinamespace ark::es2panda::lexer {
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ci// NOLINTBEGIN(readability-identifier-naming)
483af6ab5fSopenharmony_ci// NOLINTBEGIN(fuchsia-multiple-inheritance)
493af6ab5fSopenharmony_citemplate <class... Ts>
503af6ab5fSopenharmony_cistruct overloaded : Ts... {
513af6ab5fSopenharmony_ci    using Ts::operator()...;
523af6ab5fSopenharmony_ci};
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_citemplate <class... Ts>
553af6ab5fSopenharmony_cioverloaded(Ts...) -> overloaded<Ts...>;
563af6ab5fSopenharmony_ci// NOLINTEND(fuchsia-multiple-inheritance)
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_citemplate <typename>
593af6ab5fSopenharmony_ciinline constexpr bool dependent_false_v = false;
603af6ab5fSopenharmony_ci// NOLINTEND(readability-identifier-naming)
613af6ab5fSopenharmony_ci
623af6ab5fSopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
633af6ab5fSopenharmony_ciclass Number {
643af6ab5fSopenharmony_cipublic:
653af6ab5fSopenharmony_ci    // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
663af6ab5fSopenharmony_ci    explicit Number() noexcept : num_(static_cast<int32_t>(0)) {};
673af6ab5fSopenharmony_ci    explicit Number(util::StringView str) noexcept : str_(str) {}
683af6ab5fSopenharmony_ci    // NOLINTNEXTLINE(bugprone-exception-escape)
693af6ab5fSopenharmony_ci    explicit Number(util::StringView str, const std::string &utf8, NumberFlags flags) noexcept;
703af6ab5fSopenharmony_ci    explicit Number(util::StringView str, double num) noexcept : str_(str), num_(num) {}
713af6ab5fSopenharmony_ci    explicit Number(uint32_t num) noexcept : Number(static_cast<int32_t>(num)) {}
723af6ab5fSopenharmony_ci    explicit Number(int32_t num) noexcept : num_(num) {}
733af6ab5fSopenharmony_ci    explicit Number(uint64_t num) noexcept : Number(static_cast<int64_t>(num)) {}
743af6ab5fSopenharmony_ci    explicit Number(int64_t num) noexcept : num_(num) {}
753af6ab5fSopenharmony_ci    explicit Number(float num) noexcept : num_(num) {}
763af6ab5fSopenharmony_ci    explicit Number(double num) noexcept : num_(num) {}
773af6ab5fSopenharmony_ci    DEFAULT_COPY_SEMANTIC(Number);
783af6ab5fSopenharmony_ci    DEFAULT_MOVE_SEMANTIC(Number);
793af6ab5fSopenharmony_ci    ~Number() = default;
803af6ab5fSopenharmony_ci    // NOLINTEND(cppcoreguidelines-pro-type-member-init)
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ci    bool IsInt() const noexcept
833af6ab5fSopenharmony_ci    {
843af6ab5fSopenharmony_ci        return std::holds_alternative<int32_t>(num_);
853af6ab5fSopenharmony_ci    }
863af6ab5fSopenharmony_ci
873af6ab5fSopenharmony_ci    bool IsLong() const noexcept
883af6ab5fSopenharmony_ci    {
893af6ab5fSopenharmony_ci        return std::holds_alternative<int64_t>(num_);
903af6ab5fSopenharmony_ci    }
913af6ab5fSopenharmony_ci
923af6ab5fSopenharmony_ci    bool IsInteger() const noexcept
933af6ab5fSopenharmony_ci    {
943af6ab5fSopenharmony_ci        return IsInt() || IsLong();
953af6ab5fSopenharmony_ci    }
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci    bool IsFloat() const noexcept
983af6ab5fSopenharmony_ci    {
993af6ab5fSopenharmony_ci        return std::holds_alternative<float>(num_);
1003af6ab5fSopenharmony_ci    }
1013af6ab5fSopenharmony_ci
1023af6ab5fSopenharmony_ci    bool IsDouble() const noexcept
1033af6ab5fSopenharmony_ci    {
1043af6ab5fSopenharmony_ci        return std::holds_alternative<double>(num_);
1053af6ab5fSopenharmony_ci    }
1063af6ab5fSopenharmony_ci
1073af6ab5fSopenharmony_ci    bool IsReal() const noexcept
1083af6ab5fSopenharmony_ci    {
1093af6ab5fSopenharmony_ci        return IsFloat() || IsDouble();
1103af6ab5fSopenharmony_ci    }
1113af6ab5fSopenharmony_ci
1123af6ab5fSopenharmony_ci    bool ConversionError() const
1133af6ab5fSopenharmony_ci    {
1143af6ab5fSopenharmony_ci        return (flags_ & NumberFlags::ERROR) != 0;
1153af6ab5fSopenharmony_ci    }
1163af6ab5fSopenharmony_ci
1173af6ab5fSopenharmony_ci    int32_t GetInt() const
1183af6ab5fSopenharmony_ci    {
1193af6ab5fSopenharmony_ci        ASSERT(IsInt());
1203af6ab5fSopenharmony_ci        return std::get<int32_t>(num_);
1213af6ab5fSopenharmony_ci    }
1223af6ab5fSopenharmony_ci
1233af6ab5fSopenharmony_ci    int64_t GetLong() const
1243af6ab5fSopenharmony_ci    {
1253af6ab5fSopenharmony_ci        return std::visit(overloaded {[](int64_t value) { return value; },
1263af6ab5fSopenharmony_ci                                      [](int32_t value) { return static_cast<int64_t>(value); },
1273af6ab5fSopenharmony_ci                                      []([[maybe_unused]] auto value) {
1283af6ab5fSopenharmony_ci                                          ASSERT(false);
1293af6ab5fSopenharmony_ci                                          return static_cast<int64_t>(0);
1303af6ab5fSopenharmony_ci                                      }},
1313af6ab5fSopenharmony_ci                          num_);
1323af6ab5fSopenharmony_ci    }
1333af6ab5fSopenharmony_ci
1343af6ab5fSopenharmony_ci    float GetFloat() const
1353af6ab5fSopenharmony_ci    {
1363af6ab5fSopenharmony_ci        ASSERT(IsFloat());
1373af6ab5fSopenharmony_ci        return std::get<float>(num_);
1383af6ab5fSopenharmony_ci    }
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_ci    double GetDouble() const
1413af6ab5fSopenharmony_ci    {
1423af6ab5fSopenharmony_ci        return std::visit(
1433af6ab5fSopenharmony_ci            overloaded {[](double value) { return value; }, [](auto value) { return static_cast<double>(value); }},
1443af6ab5fSopenharmony_ci            num_);
1453af6ab5fSopenharmony_ci    }
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci    const util::StringView &Str() const
1483af6ab5fSopenharmony_ci    {
1493af6ab5fSopenharmony_ci        return str_;
1503af6ab5fSopenharmony_ci    }
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_ci    void Negate()
1533af6ab5fSopenharmony_ci    {
1543af6ab5fSopenharmony_ci        std::visit(overloaded {[](auto &value) { value = -value; }}, num_);
1553af6ab5fSopenharmony_ci        if (std::holds_alternative<int64_t>(num_)) {
1563af6ab5fSopenharmony_ci            int64_t num = std::get<int64_t>(num_);
1573af6ab5fSopenharmony_ci            if (num == INT32_MIN) {
1583af6ab5fSopenharmony_ci                SetValue<int32_t>(num);
1593af6ab5fSopenharmony_ci            }
1603af6ab5fSopenharmony_ci        }
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    template <typename RT>
1643af6ab5fSopenharmony_ci    bool CanGetValue() const noexcept
1653af6ab5fSopenharmony_ci    {
1663af6ab5fSopenharmony_ci        using T = typename std::remove_cv_t<typename std::remove_reference_t<RT>>;
1673af6ab5fSopenharmony_ci
1683af6ab5fSopenharmony_ci        if constexpr (std::is_same_v<T, int64_t>) {
1693af6ab5fSopenharmony_ci            return IsInteger();
1703af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, int32_t>) {
1713af6ab5fSopenharmony_ci            return IsInt();
1723af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, double>) {
1733af6ab5fSopenharmony_ci            return true;
1743af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, float>) {
1753af6ab5fSopenharmony_ci            return IsFloat();
1763af6ab5fSopenharmony_ci        } else {
1773af6ab5fSopenharmony_ci            return false;
1783af6ab5fSopenharmony_ci        }
1793af6ab5fSopenharmony_ci    }
1803af6ab5fSopenharmony_ci
1813af6ab5fSopenharmony_ci    template <typename RT>
1823af6ab5fSopenharmony_ci    auto GetValue() const
1833af6ab5fSopenharmony_ci    {
1843af6ab5fSopenharmony_ci        using T = typename std::remove_cv_t<typename std::remove_reference_t<RT>>;
1853af6ab5fSopenharmony_ci
1863af6ab5fSopenharmony_ci        if constexpr (std::is_same_v<T, int64_t>) {
1873af6ab5fSopenharmony_ci            return GetLong();
1883af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, int32_t>) {
1893af6ab5fSopenharmony_ci            return GetInt();
1903af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, double>) {
1913af6ab5fSopenharmony_ci            return GetDouble();
1923af6ab5fSopenharmony_ci        } else if constexpr (std::is_same_v<T, float>) {
1933af6ab5fSopenharmony_ci            return GetFloat();
1943af6ab5fSopenharmony_ci        } else {
1953af6ab5fSopenharmony_ci            static_assert(dependent_false_v<T>, "Invalid value type was requested for Number.");
1963af6ab5fSopenharmony_ci        }
1973af6ab5fSopenharmony_ci    }
1983af6ab5fSopenharmony_ci
1993af6ab5fSopenharmony_ci    template <typename RT>
2003af6ab5fSopenharmony_ci    void SetValue(RT &&value)
2013af6ab5fSopenharmony_ci    {
2023af6ab5fSopenharmony_ci        using T = typename std::remove_cv_t<typename std::remove_reference_t<RT>>;
2033af6ab5fSopenharmony_ci
2043af6ab5fSopenharmony_ci        if constexpr (std::is_same_v<T, int64_t> || std::is_same_v<T, int32_t> || std::is_same_v<T, double> ||
2053af6ab5fSopenharmony_ci                      std::is_same_v<T, float>) {
2063af6ab5fSopenharmony_ci            num_ = std::forward<RT>(value);
2073af6ab5fSopenharmony_ci        } else {
2083af6ab5fSopenharmony_ci            static_assert(dependent_false_v<T>, "Invalid value type was requested for Number.");
2093af6ab5fSopenharmony_ci        }
2103af6ab5fSopenharmony_ci    }
2113af6ab5fSopenharmony_ci
2123af6ab5fSopenharmony_ciprivate:
2133af6ab5fSopenharmony_ci    util::StringView str_ {};
2143af6ab5fSopenharmony_ci    std::variant<int32_t, int64_t, float, double> num_;
2153af6ab5fSopenharmony_ci    NumberFlags flags_ {NumberFlags::NONE};
2163af6ab5fSopenharmony_ci};
2173af6ab5fSopenharmony_ci}  // namespace ark::es2panda::lexer
2183af6ab5fSopenharmony_ci
2193af6ab5fSopenharmony_ci#endif
220