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