1 /*
2 * Copyright (c) 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 #include <cstddef>
17 #include <cstdlib>
18 #include <string_view>
19 #include "number-utils.h"
20
21 namespace ark::pandasm {
22
IntegerNumber(std::string_view p)23 int64_t IntegerNumber(std::string_view p)
24 {
25 constexpr size_t GENERAL_SHIFT = 2;
26
27 // expects a valid number
28 if (p.size() == 1) {
29 return p[0] - '0';
30 }
31
32 size_t minusShift = 0;
33 if (p[0] == '-') {
34 minusShift++;
35 }
36
37 if (p.size() == GENERAL_SHIFT && minusShift != 0) {
38 return -1 * (p[1] - '0');
39 }
40
41 if (p[minusShift + 1] == 'b') {
42 p.remove_prefix(GENERAL_SHIFT + minusShift);
43 return std::strtoull(p.data(), nullptr, BIN_BASE) * (minusShift == 0 ? 1 : -1);
44 }
45
46 if (p[minusShift + 1] == 'x') {
47 return std::strtoull(p.data(), nullptr, HEX_BASE);
48 }
49
50 if (p[minusShift] == '0') {
51 return std::strtoull(p.data(), nullptr, OCT_BASE);
52 }
53
54 return std::strtoull(p.data(), nullptr, DEC_BASE);
55 }
56
ValidateInteger(std::string_view p)57 bool ValidateInteger(std::string_view p)
58 {
59 constexpr size_t GENERAL_SHIFT = 2;
60
61 std::string_view token = p;
62
63 if (token.back() == '-' || token.back() == '+' || token.back() == 'x' || token == ".") {
64 return false;
65 }
66
67 if (token[0] == '-' || token[0] == '+') {
68 token.remove_prefix(1);
69 }
70
71 if (token[0] == '0' && token.size() > 1 && token.find('.') == std::string::npos) {
72 if (token[1] == 'x') {
73 return ValidateXToken(token, GENERAL_SHIFT);
74 }
75
76 if (token[1] == 'b') {
77 return ValidateBToken(token, GENERAL_SHIFT);
78 }
79
80 if (token[1] >= '0' && token[1] <= '9' && token.find('e') == std::string::npos) {
81 return ValidateZeroToTenToken(token);
82 }
83 }
84
85 for (auto i : token) {
86 if (!(i >= '0' && i <= '9')) {
87 return false;
88 }
89 }
90
91 return true;
92 }
93
ValidateFloat(std::string_view p)94 bool ValidateFloat(std::string_view p)
95 {
96 std::string_view token = p;
97
98 if (ValidateInteger(token)) {
99 return true;
100 }
101
102 if (token[0] == '-' || token[0] == '+') {
103 token.remove_prefix(1);
104 }
105
106 bool dot = false;
107 bool exp = false;
108 bool nowexp = false;
109
110 for (auto i : token) {
111 if (nowexp && (i == '-' || i == '+')) {
112 nowexp = false;
113 continue;
114 }
115
116 if (nowexp) {
117 nowexp = false;
118 }
119
120 if (i == '.' && !exp && !dot) {
121 dot = true;
122 } else if (!exp && i == 'e') {
123 nowexp = true;
124 exp = true;
125 } else if (!(i >= '0' && i <= '9')) {
126 return false;
127 }
128 }
129
130 return !nowexp;
131 }
132
133 } // namespace ark::pandasm
134