1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef ASSEMBLER_UTILS_NUMBER_UTILS_H 17#define ASSEMBLER_UTILS_NUMBER_UTILS_H 18 19namespace panda::pandasm { 20 21constexpr size_t HEX_BASE = 16; 22 23constexpr size_t DEC_BASE = 10; 24 25constexpr size_t OCT_BASE = 8; 26 27constexpr size_t BIN_BASE = 2; 28 29constexpr size_t MAX_DWORD = 65536; 30 31inline bool IsHexNumber(const std::string_view &token) 32{ 33 for (auto i : token) { 34 if (!((i >= '0' && i <= '9') || (i >= 'A' && i <= 'F') || (i >= 'a' && i <= 'f'))) { 35 return false; 36 } 37 } 38 return true; 39} 40 41inline bool IsBinaryNumber(const std::string_view &token) 42{ 43 for (auto i : token) { 44 if (!(i == '0' || i == '1')) { 45 return false; 46 } 47 } 48 return true; 49} 50 51inline bool IsOctalNumber(const std::string_view &token) 52{ 53 for (auto i : token) { 54 if (!(i >= '0' && i <= '7')) { 55 return false; 56 } 57 } 58 return true; 59} 60 61inline bool ValidateInteger(const std::string_view &p) 62{ 63 constexpr size_t GENERAL_SHIFT = 2; 64 65 std::string_view token = p; 66 67 if (token.back() == '-' || token.back() == '+' || token.back() == 'x' || token == ".") { 68 return false; 69 } 70 71 if (token[0] == '-' || token[0] == '+') { 72 token.remove_prefix(1); 73 } 74 75 if (token[0] == '0' && token.size() > 1 && token.find('.') == std::string::npos) { 76 if (token[1] == 'x') { 77 token.remove_prefix(GENERAL_SHIFT); 78 return IsHexNumber(token); 79 } 80 81 if (token[1] == 'b') { 82 token.remove_prefix(GENERAL_SHIFT); 83 return (!token.empty() && IsBinaryNumber(token)); 84 } 85 86 if (token[1] >= '0' && token[1] <= '9' && token.find('e') == std::string::npos) { 87 token.remove_prefix(1); 88 return IsOctalNumber(token); 89 } 90 } 91 92 for (auto i : token) { 93 if (!(i >= '0' && i <= '9')) { 94 return false; 95 } 96 } 97 98 return true; 99} 100 101inline int64_t IntegerNumber(std::string_view p) 102{ 103 constexpr size_t GENERAL_SHIFT = 2; 104 105 // expects a valid number 106 if (p.size() == 1) { 107 return p[0] - '0'; 108 } 109 110 size_t minus_shift = 0; 111 if (p[0] == '-') { 112 minus_shift++; 113 } 114 115 if (p[minus_shift + 1] == 'b') { 116 p.remove_prefix(GENERAL_SHIFT + minus_shift); 117 return std::strtoull(p.data(), nullptr, BIN_BASE) * (minus_shift == 0 ? 1 : -1); 118 } 119 120 if (p[minus_shift + 1] == 'x') { 121 return std::strtoull(p.data(), nullptr, HEX_BASE); 122 } 123 124 if (p[minus_shift] == '0') { 125 return std::strtoull(p.data(), nullptr, OCT_BASE); 126 } 127 128 return std::strtoull(p.data(), nullptr, DEC_BASE); 129} 130 131inline bool ValidateFloat(const std::string_view &p) 132{ 133 std::string_view token = p; 134 135 if (ValidateInteger(token)) { 136 return true; 137 } 138 139 if (token[0] == '-' || token[0] == '+') { 140 token.remove_prefix(1); 141 } 142 143 bool dot = false; 144 bool exp = false; 145 bool nowexp = false; 146 147 for (auto i : token) { 148 if (nowexp && (i == '-' || i == '+')) { 149 nowexp = false; 150 continue; 151 } 152 153 if (nowexp) { 154 nowexp = false; 155 } 156 157 if (i == '.' && !exp && !dot) { 158 dot = true; 159 } else if (!exp && i == 'e') { 160 nowexp = true; 161 exp = true; 162 } else if (!(i >= '0' && i <= '9')) { 163 return false; 164 } 165 } 166 167 return !nowexp; 168} 169 170inline double FloatNumber(std::string_view p, bool is_64bit) 171{ 172 constexpr size_t GENERAL_SHIFT = 2; 173 // expects a valid number 174 if (p.size() > GENERAL_SHIFT && p.substr(0, GENERAL_SHIFT) == "0x") { // hex literal 175 char *end = nullptr; 176 if (is_64bit) { 177 return bit_cast<double>(strtoull(p.data(), &end, 0)); 178 } else { 179 return bit_cast<float>(static_cast<uint32_t>(strtoull(p.data(), &end, 0))); 180 } 181 } 182 return std::strtold(std::string(p.data(), p.length()).c_str(), nullptr); 183} 184 185inline size_t ToNumber(std::string_view p) 186{ 187 size_t sum = 0; 188 189 for (char i : p) { 190 if (isdigit(i) != 0) { 191 sum = sum * DEC_BASE + static_cast<size_t>(i - '0'); 192 } else { 193 return MAX_DWORD; 194 } 195 } 196 197 return sum; 198} 199 200} // namespace panda::pandasm 201 202#endif // ASSEMBLER_UTILS_NUMBER_UTILS_H 203