• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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