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 #include "assembly-parser.h"
17 #include "utils/number-utils.h"
18
19 namespace panda::pandasm {
20
Make(const std::vector<panda::pandasm::Token> & t)21 void Context::Make(const std::vector<panda::pandasm::Token> &t)
22 {
23 err = {};
24
25 ins_number = 0;
26
27 tokens = t;
28
29 number = 1;
30
31 end = false;
32
33 token = std::string_view(&*(tokens[number - 1].whole_line.begin() + tokens[number - 1].bound_left),
34 tokens[number - 1].bound_right - tokens[number - 1].bound_left);
35
36 id = this->tokens[number - 1].type;
37 }
38
Len() const39 size_t Context::Len() const
40 {
41 return token.size();
42 }
43
ValidateRegisterName(char c,size_t n) const44 bool Context::ValidateRegisterName(char c, size_t n) const
45 {
46 if (token[0] == c) {
47 std::string_view p = token;
48
49 p.remove_prefix(1);
50
51 if (p.empty() || (p.size() > 1 && p[0] == '0')) {
52 return false;
53 }
54
55 if (c != 'a') {
56 for (const auto &ch : p) {
57 if (std::isdigit(ch) == 0) {
58 return false;
59 }
60 }
61 } else {
62 if (ToNumber(p) > n) {
63 return false;
64 }
65 }
66
67 return true;
68 }
69
70 return false;
71 }
72
ValidateParameterName(size_t number_of_params_already_is) const73 bool Context::ValidateParameterName(size_t number_of_params_already_is) const
74 {
75 if (number_of_params_already_is >= MAX_DWORD) {
76 return false;
77 }
78
79 if (token[0] == 'a') {
80 std::string_view p = token;
81
82 p.remove_prefix(1);
83
84 if (ToNumber(p) == number_of_params_already_is) {
85 return true;
86 }
87 }
88
89 return false;
90 }
91
GiveToken()92 std::string_view Context::GiveToken()
93 {
94 return token;
95 }
96
Next()97 Token::Type Context::Next()
98 {
99 if (this->tokens.size() > number) {
100 return this->tokens[number].type;
101 }
102
103 return this->tokens[number - 1].type;
104 }
105
UpSignOperation()106 void Context::UpSignOperation()
107 {
108 signop = id;
109 }
110
WaitFor()111 Token::Type Context::WaitFor()
112 {
113 return signop;
114 }
115
Mask()116 bool Context::Mask()
117 {
118 return end;
119 }
120
NextMask()121 bool Context::NextMask()
122 {
123 if (end) {
124 return true;
125 }
126
127 return this->tokens.size() < number + 1;
128 }
129
130 // NOLINTNEXTLINE(cert-dcl21-cpp)
operator ++(int)131 Token::Type Context::operator++(int)
132 {
133 Token::Type last_id = id;
134
135 if (this->tokens.size() > number) {
136 ++number;
137
138 id = this->tokens[number - 1].type;
139
140 token = std::string_view(&*(tokens[number - 1].whole_line.begin() + tokens[number - 1].bound_left),
141 tokens[number - 1].bound_right - tokens[number - 1].bound_left);
142 } else {
143 end = true;
144 }
145
146 return last_id;
147 }
148
operator ++()149 Token::Type Context::operator++()
150 {
151 if (this->tokens.size() > number) {
152 ++number;
153
154 id = this->tokens[number - 1].type;
155
156 token = std::string_view(&*(tokens[number - 1].whole_line.begin() + tokens[number - 1].bound_left),
157 tokens[number - 1].bound_right - tokens[number - 1].bound_left);
158 } else {
159 end = true;
160 }
161
162 return id;
163 }
164
165 // NOLINTNEXTLINE(cert-dcl21-cpp)
operator --(int)166 Token::Type Context::operator--(int)
167 {
168 Token::Type last_id = id;
169
170 if (1 < number) {
171 end = false;
172
173 --number;
174
175 id = this->tokens[number - 1].type;
176
177 token = std::string_view(&*(tokens[number - 1].whole_line.begin() + tokens[number - 1].bound_left),
178 tokens[number - 1].bound_right - tokens[number - 1].bound_left);
179 } else {
180 end = false;
181 }
182
183 return last_id;
184 }
185
operator --()186 Token::Type Context::operator--()
187 {
188 if (1 < number) {
189 end = false;
190
191 --number;
192
193 id = this->tokens[number - 1].type;
194
195 token = std::string_view(&*(tokens[number - 1].whole_line.begin() + tokens[number - 1].bound_left),
196 tokens[number - 1].bound_right - tokens[number - 1].bound_left);
197 } else {
198 end = false;
199 }
200
201 return id;
202 }
203
operator *()204 Token::Type Context::operator*()
205 {
206 return id;
207 }
208
209 } // namespace panda::pandasm
210