• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 PANDA_ASSEMBLER_UTILS_NUMBERS_UTILS_H
17 #define PANDA_ASSEMBLER_UTILS_NUMBERS_UTILS_H
18 
19 namespace ark::pandasm {
20 
21 constexpr size_t HEX_BASE = 16;
22 
23 constexpr size_t DEC_BASE = 10;
24 
25 constexpr size_t OCT_BASE = 8;
26 
27 constexpr size_t BIN_BASE = 2;
28 
29 constexpr size_t MAX_DWORD = 65536;
30 
ValidateXToken(std::string_view token,size_t shift)31 inline bool ValidateXToken(std::string_view token, size_t shift)
32 {
33     token.remove_prefix(shift);
34 
35     for (auto i : token) {
36         if (!((i >= '0' && i <= '9') || (i >= 'A' && i <= 'F') || (i >= 'a' && i <= 'f'))) {
37             return false;
38         }
39     }
40 
41     return true;
42 }
43 
ValidateBToken(std::string_view token,size_t shift)44 inline bool ValidateBToken(std::string_view token, size_t shift)
45 {
46     token.remove_prefix(shift);
47     if (token.empty()) {
48         return false;
49     }
50     for (auto i : token) {
51         if (!(i == '0' || i == '1')) {
52             return false;
53         }
54     }
55 
56     return true;
57 }
58 
ValidateZeroToTenToken(std::string_view token)59 inline bool ValidateZeroToTenToken(std::string_view token)
60 {
61     token.remove_prefix(1);
62 
63     for (auto i : token) {
64         if (!(i >= '0' && i <= '7')) {
65             return false;
66         }
67     }
68 
69     return true;
70 }
71 
ValidateInteger(std::string_view p)72 inline bool ValidateInteger(std::string_view p)
73 {
74     constexpr size_t GENERAL_SHIFT = 2;
75 
76     std::string_view token = p;
77 
78     if (token.back() == '-' || token.back() == '+' || token.back() == 'x' || token == ".") {
79         return false;
80     }
81 
82     if (token[0] == '-' || token[0] == '+') {
83         token.remove_prefix(1);
84     }
85 
86     if (token[0] == '0' && token.size() > 1 && token.find('.') == std::string::npos) {
87         if (token[1] == 'x') {
88             return ValidateXToken(token, GENERAL_SHIFT);
89         }
90 
91         if (token[1] == 'b') {
92             return ValidateBToken(token, GENERAL_SHIFT);
93         }
94 
95         if (token[1] >= '0' && token[1] <= '9' && token.find('e') == std::string::npos) {
96             return ValidateZeroToTenToken(token);
97         }
98     }
99 
100     for (auto i : token) {
101         if (!(i >= '0' && i <= '9')) {
102             return false;
103         }
104     }
105 
106     return true;
107 }
108 
IntegerNumber(std::string_view p)109 inline int64_t IntegerNumber(std::string_view p)
110 {
111     constexpr size_t GENERAL_SHIFT = 2;
112 
113     // expects a valid number
114     if (p.size() == 1) {
115         return p[0] - '0';
116     }
117 
118     size_t minusShift = 0;
119     if (p[0] == '-') {
120         minusShift++;
121     }
122 
123     if (p.size() == GENERAL_SHIFT && minusShift != 0) {
124         return -1 * (p[1] - '0');
125     }
126 
127     if (p[minusShift + 1] == 'b') {
128         p.remove_prefix(GENERAL_SHIFT + minusShift);
129         return std::strtoull(p.data(), nullptr, BIN_BASE) * (minusShift == 0 ? 1 : -1);
130     }
131 
132     if (p[minusShift + 1] == 'x') {
133         return std::strtoull(p.data(), nullptr, HEX_BASE);
134     }
135 
136     if (p[minusShift] == '0') {
137         return std::strtoull(p.data(), nullptr, OCT_BASE);
138     }
139 
140     return std::strtoull(p.data(), nullptr, DEC_BASE);
141 }
142 
ValidateFloat(std::string_view p)143 inline bool ValidateFloat(std::string_view p)
144 {
145     std::string_view token = p;
146 
147     if (ValidateInteger(token)) {
148         return true;
149     }
150 
151     if (token[0] == '-' || token[0] == '+') {
152         token.remove_prefix(1);
153     }
154 
155     bool dot = false;
156     bool exp = false;
157     bool nowexp = false;
158 
159     for (auto i : token) {
160         if (nowexp && (i == '-' || i == '+')) {
161             nowexp = false;
162             continue;
163         }
164 
165         if (nowexp) {
166             nowexp = false;
167         }
168 
169         if (i == '.' && !exp && !dot) {
170             dot = true;
171         } else if (!exp && i == 'e') {
172             nowexp = true;
173             exp = true;
174         } else if (!(i >= '0' && i <= '9')) {
175             return false;
176         }
177     }
178 
179     return !nowexp;
180 }
181 
FloatNumber(std::string_view p,bool is64bit)182 inline double FloatNumber(std::string_view p, bool is64bit)
183 {
184     constexpr size_t GENERAL_SHIFT = 2;
185     // expects a valid number
186     if (p.size() > GENERAL_SHIFT && p.substr(0, GENERAL_SHIFT) == "0x") {  // hex literal
187         char *end = nullptr;
188         if (is64bit) {
189             return bit_cast<double>(strtoull(p.data(), &end, 0));
190         }
191         return bit_cast<float>(static_cast<uint32_t>(strtoull(p.data(), &end, 0)));
192     }
193     return std::strtold(std::string(p.data(), p.length()).c_str(), nullptr);
194 }
195 
ToNumber(std::string_view p)196 inline size_t ToNumber(std::string_view p)
197 {
198     size_t sum = 0;
199 
200     for (char i : p) {
201         if (isdigit(i) != 0) {
202             sum = sum * DEC_BASE + static_cast<size_t>(i - '0');
203         } else {
204             return MAX_DWORD;
205         }
206     }
207 
208     return sum;
209 }
210 
211 }  // namespace ark::pandasm
212 
213 #endif  // PANDA_ASSEMBLER_UTILS_NUMBERS_UTILS_H
214