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 "ins_emit.h"
17 #include "opcode_parsing.h"
18 #include "operand_types_print.h"
19 #include "utils/number-utils.h"
20
21 namespace panda::pandasm {
22
ParseRecordFields()23 bool Parser::ParseRecordFields()
24 {
25 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
26 curr_record_->body_location.begin = GetCurrentPosition(false);
27 open_ = true;
28
29 ++context_;
30 }
31
32 curr_record_->body_presence = true;
33
34 if (!open_) {
35 context_.err = GetError("Expected keyword.", Error::ErrorType::ERR_BAD_KEYWORD);
36 return false;
37 }
38
39 if (context_.Mask()) {
40 return true;
41 }
42
43 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
44 curr_record_->body_location.end = GetCurrentPosition(true);
45 ++context_;
46
47 open_ = false;
48
49 return true;
50 }
51
52 curr_record_->field_list.emplace_back(program_.lang);
53 curr_fld_ = &(curr_record_->field_list[curr_record_->field_list.size() - 1]);
54 curr_fld_->line_of_def = line_stric_;
55 context_.ins_number = curr_record_->field_list.size();
56
57 LOG(DEBUG, ASSEMBLER) << "parse line " << line_stric_ << " as field (.field name)";
58 if (!ParseRecordField()) {
59 if (context_.err.err != Error::ErrorType::ERR_NONE) {
60 return false;
61 }
62
63 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
64 curr_record_->body_location.end = GetCurrentPosition(true);
65 ++context_;
66 open_ = false;
67 } else {
68 context_.err = GetError("Expected a new field on the next line.", Error::ErrorType::ERR_BAD_KEYWORD);
69 return false;
70 }
71 }
72
73 return true;
74 }
75
ParseFieldName()76 bool Parser::ParseFieldName()
77 {
78 if (PrefixedValidName()) {
79 std::string field_name = std::string(context_.GiveToken().data(), context_.GiveToken().length());
80
81 auto match_names = [&field_name](const pandasm::Field &f) { return field_name == f.name; };
82 const auto iter = std::find_if(curr_record_->field_list.begin(), curr_record_->field_list.end(), match_names);
83 if (iter != curr_record_->field_list.end()) {
84 if (iter->is_defined) {
85 context_.err =
86 GetError("Repeating field names in the same record.", Error::ErrorType::ERR_REPEATING_FIELD_NAME);
87
88 return false;
89 }
90
91 curr_record_->field_list.erase(iter);
92 }
93
94 curr_fld_ = &(curr_record_->field_list[curr_record_->field_list.size() - 1]);
95
96 curr_fld_->name = field_name;
97
98 ++context_;
99
100 return true;
101 }
102
103 context_.err = GetError("Invalid name of field.", Error::ErrorType::ERR_BAD_OPERATION_NAME);
104
105 return false;
106 }
107
ParseType(Type * type)108 bool Parser::ParseType(Type *type)
109 {
110 ASSERT(TypeValidName());
111
112 std::string component_name(context_.GiveToken());
113 size_t rank = 0;
114
115 ++context_;
116
117 while (*context_ == Token::Type::DEL_SQUARE_BRACKET_L) {
118 ++context_;
119 if (*context_ != Token::Type::DEL_SQUARE_BRACKET_R) {
120 context_.err = GetError("Expected ']'.", Error::ErrorType::ERR_BAD_ARRAY_TYPE_BOUND);
121 return false;
122 }
123 ++context_;
124 ++rank;
125 }
126
127 *type = Type(component_name, rank);
128
129 if (type->IsArray()) {
130 program_.array_types.insert(*type);
131 }
132
133 return true;
134 }
135
ParseFieldType()136 bool Parser::ParseFieldType()
137 {
138 LOG(DEBUG, ASSEMBLER) << "started searching field type value (line " << line_stric_
139 << "): " << context_.tokens[context_.number - 1].whole_line;
140
141 if (!TypeValidName()) {
142 context_.err = GetError("Not a correct type.", Error::ErrorType::ERR_BAD_FIELD_VALUE_TYPE);
143 return false;
144 }
145
146 if (!ParseType(&curr_fld_->type)) {
147 return false;
148 }
149
150 curr_fld_->metadata->SetFieldType(curr_fld_->type);
151
152 LOG(DEBUG, ASSEMBLER) << "field type found (line " << line_stric_ << "): " << context_.GiveToken();
153
154 return true;
155 }
156
ParseRecordField()157 bool Parser::ParseRecordField()
158 {
159 if (!ParseFieldType()) {
160 return false;
161 }
162
163 if (context_.Mask()) {
164 context_.err = GetError("Expected field name.", Error::ErrorType::ERR_BAD_FIELD_MISSING_NAME, +1);
165 return false;
166 }
167
168 if (!ParseFieldName()) {
169 return false;
170 }
171
172 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
173 curr_record_->body_location.end = GetCurrentPosition(true);
174 ++context_;
175 open_ = false;
176 return true;
177 }
178
179 metadata_ = curr_fld_->metadata.get();
180 ParseMetaDef();
181
182 return context_.Mask();
183 }
184
IsConstArray()185 bool Parser::IsConstArray()
186 {
187 if ((curr_array_->literals_.size() >= INTRO_CONST_ARRAY_LITERALS_NUMBER) &&
188 (curr_array_->literals_[0].tag_ == panda_file::LiteralTag::TAGVALUE)) {
189 return true;
190 }
191 return false;
192 }
193
ArrayElementsValidNumber()194 bool Parser::ArrayElementsValidNumber()
195 {
196 if (!IsConstArray()) {
197 return true;
198 }
199
200 ASSERT(curr_array_->literals_.size() > 1);
201
202 auto init_size = std::get<uint32_t>(curr_array_->literals_[1].value_);
203 if (init_size < 1) {
204 return false;
205 }
206 if (curr_array_->literals_.size() != init_size + INTRO_CONST_ARRAY_LITERALS_NUMBER) {
207 return false;
208 }
209
210 return true;
211 }
212
ParseAsArray(const std::vector<Token> & tokens)213 void Parser::ParseAsArray(const std::vector<Token> &tokens)
214 {
215 LOG(DEBUG, ASSEMBLER) << "started parsing of array (line " << line_stric_ << "): " << tokens[0].whole_line;
216 func_def_ = false;
217 record_def_ = false;
218 array_def_ = true;
219
220 if (!open_) {
221 ++context_;
222 } else {
223 context_.err =
224 GetError("No one array can be defined inside another array.", Error::ErrorType::ERR_BAD_DEFINITION);
225 return;
226 }
227
228 if (ParseArrayFullSign()) {
229 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
230 ++context_;
231
232 LOG(DEBUG, ASSEMBLER) << "array body is open, line " << line_stric_ << ": " << tokens[0].whole_line;
233
234 open_ = true;
235 }
236
237 uint32_t iter_number = 1;
238 if (IsConstArray()) {
239 iter_number = std::get<uint32_t>(curr_array_->literals_[1].value_);
240 }
241
242 if (iter_number < 1) {
243 context_.err =
244 GetError("Сonstant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
245 return;
246 }
247
248 for (uint32_t i = 0; i < iter_number; i++) {
249 if (open_ && !context_.Mask() && *context_ != Token::Type::DEL_BRACE_R) {
250 ParseArrayElements();
251 } else {
252 break;
253 }
254 }
255
256 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
257 if (!ArrayElementsValidNumber()) {
258 context_.err =
259 GetError("Constant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
260 return;
261 }
262 LOG(DEBUG, ASSEMBLER) << "array body is closed, line " << line_stric_ << ": " << tokens[0].whole_line;
263
264 ++context_;
265
266 open_ = false;
267 }
268 }
269 }
270
ParseArrayElements()271 bool Parser::ParseArrayElements()
272 {
273 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
274 open_ = true;
275
276 ++context_;
277 }
278
279 if (!open_) {
280 context_.err = GetError("Expected keyword.", Error::ErrorType::ERR_BAD_KEYWORD);
281 return false;
282 }
283
284 if (context_.Mask()) {
285 return true;
286 }
287
288 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
289 if (!ArrayElementsValidNumber()) {
290 context_.err =
291 GetError("Constant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
292 return false;
293 }
294 ++context_;
295
296 open_ = false;
297
298 return true;
299 }
300
301 curr_array_->literals_.push_back(panda::pandasm::LiteralArray::Literal());
302 curr_array_elem_ = &(curr_array_->literals_[curr_array_->literals_.size() - 1]);
303
304 LOG(DEBUG, ASSEMBLER) << "parse line " << line_stric_ << " as array elem (.array_elem value)";
305 if (!ParseArrayElement()) {
306 if (context_.err.err != Error::ErrorType::ERR_NONE) {
307 return false;
308 }
309
310 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
311 ++context_;
312 open_ = false;
313
314 if (!ArrayElementsValidNumber()) {
315 context_.err =
316 GetError("Constant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
317 return false;
318 }
319 } else {
320 context_.err =
321 GetError("Expected a new array element on the next line.", Error::ErrorType::ERR_BAD_KEYWORD);
322 return false;
323 }
324 }
325
326 return true;
327 }
328
ParseArrayElement()329 bool Parser::ParseArrayElement()
330 {
331 if (IsConstArray()) {
332 curr_array_elem_->tag_ =
333 static_cast<panda_file::LiteralTag>(std::get<uint8_t>(curr_array_->literals_[0].value_));
334 } else {
335 if (!ParseArrayElementType()) {
336 return false;
337 }
338 }
339
340 if (context_.Mask()) {
341 context_.err =
342 GetError("Expected array element value.", Error::ErrorType::ERR_BAD_ARRAY_ELEMENT_MISSING_VALUE, +1);
343 return false;
344 }
345
346 if (!ParseArrayElementValue()) {
347 return false;
348 }
349
350 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
351 ++context_;
352 open_ = false;
353
354 if (!ArrayElementsValidNumber()) {
355 context_.err =
356 GetError("Constant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
357 return false;
358 }
359 return true;
360 }
361
362 return IsConstArray() ? true : context_.Mask();
363 }
364
ParseArrayElementType()365 bool Parser::ParseArrayElementType()
366 {
367 LOG(DEBUG, ASSEMBLER) << "started searching array element type value (line " << line_stric_
368 << "): " << context_.tokens[context_.number - 1].whole_line;
369
370 if (!TypeValidName()) {
371 context_.err = GetError("Not a correct type.", Error::ErrorType::ERR_BAD_ARRAY_ELEMENT_VALUE_TYPE);
372 return false;
373 }
374
375 Type type;
376 if (!ParseType(&type)) {
377 return false;
378 }
379
380 // workaround until #5776 is done
381 auto type_name = type.GetName();
382 std::replace(type_name.begin(), type_name.end(), '.', '/');
383 auto type_with_slash = Type(type_name, 0);
384
385 if (panda::pandasm::Type::IsPandaPrimitiveType(type.GetName())) {
386 curr_array_elem_->tag_ = panda::pandasm::LiteralArray::GetArrayTagFromComponentType(type.GetId());
387 if (program_.array_types.find(type) == program_.array_types.end()) {
388 program_.array_types.emplace(type, 1);
389 }
390 } else if (panda::pandasm::Type::IsStringType(type_with_slash.GetName(), program_.lang)) {
391 curr_array_elem_->tag_ = panda_file::LiteralTag::ARRAY_STRING;
392 if (program_.array_types.find(type_with_slash) == program_.array_types.end()) {
393 program_.array_types.emplace(type_with_slash, 1);
394 }
395 } else {
396 return false;
397 }
398
399 LOG(DEBUG, ASSEMBLER) << "array element type found (line " << line_stric_ << "): " << context_.GiveToken();
400
401 return true;
402 }
403
ParseArrayElementValueInteger()404 bool Parser::ParseArrayElementValueInteger()
405 {
406 int64_t n;
407 if (!ParseInteger(&n)) {
408 context_.err =
409 GetError("Invalid value of array integer element.", Error::ErrorType::ERR_BAD_ARRAY_ELEMENT_VALUE_INTEGER);
410 return false;
411 }
412 if (curr_array_elem_->IsBoolValue()) {
413 curr_array_elem_->value_ = static_cast<bool>(n);
414 }
415 if (curr_array_elem_->IsByteValue()) {
416 curr_array_elem_->value_ = static_cast<uint8_t>(n);
417 }
418 if (curr_array_elem_->IsShortValue()) {
419 curr_array_elem_->value_ = static_cast<uint16_t>(n);
420 }
421 if (curr_array_elem_->IsIntegerValue()) {
422 curr_array_elem_->value_ = static_cast<uint32_t>(n);
423 }
424 if (curr_array_elem_->IsLongValue()) {
425 curr_array_elem_->value_ = static_cast<uint64_t>(n);
426 }
427 return true;
428 }
429
ParseArrayElementValueFloat()430 bool Parser::ParseArrayElementValueFloat()
431 {
432 double n;
433 if (!ParseFloat(&n, !curr_array_elem_->IsFloatValue())) {
434 context_.err =
435 GetError("Invalid value of array float element.", Error::ErrorType::ERR_BAD_ARRAY_ELEMENT_VALUE_FLOAT);
436 return false;
437 }
438 if (curr_array_elem_->IsFloatValue()) {
439 curr_array_elem_->value_ = static_cast<float>(n);
440 } else {
441 curr_array_elem_->value_ = static_cast<double>(n);
442 }
443 return true;
444 }
445
ParseArrayElementValueString()446 bool Parser::ParseArrayElementValueString()
447 {
448 if (context_.err.err != Error::ErrorType::ERR_NONE) {
449 return false;
450 }
451
452 auto res = ParseStringLiteral();
453 if (!res) {
454 context_.err =
455 GetError("Invalid value of array string element.", Error::ErrorType::ERR_BAD_ARRAY_ELEMENT_VALUE_STRING);
456 return false;
457 }
458 curr_array_elem_->value_ = res.value();
459 return true;
460 }
461
ParseArrayElementValue()462 bool Parser::ParseArrayElementValue()
463 {
464 if (curr_array_elem_->IsBoolValue() || curr_array_elem_->IsByteValue() || curr_array_elem_->IsShortValue() ||
465 curr_array_elem_->IsIntegerValue() || curr_array_elem_->IsLongValue()) {
466 if (!ParseArrayElementValueInteger()) {
467 return false;
468 }
469 }
470 if (curr_array_elem_->IsFloatValue() || curr_array_elem_->IsDoubleValue()) {
471 if (!ParseArrayElementValueFloat()) {
472 return false;
473 }
474 }
475 if (curr_array_elem_->IsStringValue()) {
476 if (!ParseArrayElementValueString()) {
477 return false;
478 }
479 }
480
481 ++context_;
482
483 return true;
484 }
485
ParseFunctionCode()486 bool Parser::ParseFunctionCode()
487 {
488 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
489 open_ = true;
490 curr_func_->body_location.begin = GetCurrentPosition(false);
491 ++context_;
492 }
493
494 curr_func_->body_presence = true;
495
496 if (!open_) {
497 context_.err = GetError("Expected keyword.", Error::ErrorType::ERR_BAD_KEYWORD);
498 return false;
499 }
500
501 if (context_.Mask()) {
502 return true;
503 }
504
505 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
506 curr_func_->body_location.end = GetCurrentPosition(true);
507 ++context_;
508 open_ = false;
509 return true;
510 }
511
512 opcode_ = panda::pandasm::Opcode::INVALID;
513 ids_.clear();
514 imms_.clear();
515 regs_.clear();
516 set_label_ = false;
517 label_.clear();
518
519 LOG(DEBUG, ASSEMBLER) << "parse line " << line_stric_
520 << " as instruction ([label:] operation [operand,] [# comment])";
521
522 ParseFunctionInstruction();
523
524 SetError();
525 if (err_.err == Error::ErrorType::ERR_NONE) {
526 if (set_label_) {
527 curr_func_->ins.emplace_back(new panda::pandasm::LabelIns(label_));
528 } else {
529 curr_func_->ins.emplace_back(panda::pandasm::Ins::CreateIns(opcode_, regs_, imms_, ids_));
530 }
531 curr_func_->ins.back()->ins_debug = curr_debug_;
532 }
533
534 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
535 curr_func_->body_location.end = GetCurrentPosition(true);
536 ++context_;
537 open_ = false;
538 }
539
540 return true;
541 }
542
ParseAsRecord(const std::vector<Token> & tokens)543 void Parser::ParseAsRecord(const std::vector<Token> &tokens)
544 {
545 LOG(DEBUG, ASSEMBLER) << "started parsing of record (line " << line_stric_ << "): " << tokens[0].whole_line;
546 func_def_ = false;
547 record_def_ = true;
548 array_def_ = false;
549
550 if (!open_) {
551 ++context_;
552 } else {
553 context_.err =
554 GetError("No one record can be defined inside another record.", Error::ErrorType::ERR_BAD_DEFINITION);
555 return;
556 }
557
558 if (ParseRecordFullSign()) {
559 metadata_ = curr_record_->metadata.get();
560 if (ParseMetaDef()) {
561 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
562 curr_record_->body_location.begin = GetCurrentPosition(false);
563 ++context_;
564
565 LOG(DEBUG, ASSEMBLER) << "record body is open, line " << line_stric_ << ": " << tokens[0].whole_line;
566
567 open_ = true;
568 }
569
570 if (open_ && !context_.Mask() && *context_ != Token::Type::DEL_BRACE_R) {
571 ParseRecordFields();
572 } else if (open_) {
573 curr_record_->body_presence = true;
574 }
575
576 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
577 LOG(DEBUG, ASSEMBLER) << "record body is closed, line " << line_stric_ << ": " << tokens[0].whole_line;
578
579 curr_record_->body_location.end = GetCurrentPosition(true);
580 ++context_;
581
582 open_ = false;
583 }
584 }
585 }
586 }
587
ParseAsFunction(const std::vector<Token> & tokens)588 void Parser::ParseAsFunction(const std::vector<Token> &tokens)
589 {
590 LOG(DEBUG, ASSEMBLER) << "started parsing of function (line " << line_stric_ << "): " << tokens[0].whole_line;
591 record_def_ = false;
592 func_def_ = true;
593 array_def_ = false;
594
595 if (!open_) {
596 ++context_;
597 } else {
598 context_.err =
599 GetError("No one function can be defined inside another function.", Error::ErrorType::ERR_BAD_DEFINITION);
600 return;
601 }
602
603 if (ParseFunctionFullSign()) {
604 metadata_ = curr_func_->metadata.get();
605 if (ParseMetaDef()) {
606 if (!open_ && *context_ == Token::Type::DEL_BRACE_L) {
607 curr_func_->body_location.begin = GetCurrentPosition(false);
608 ++context_;
609
610 LOG(DEBUG, ASSEMBLER) << "function body is open, line " << line_stric_ << ": " << tokens[0].whole_line;
611
612 open_ = true;
613 }
614
615 if (open_ && !context_.Mask() && *context_ != Token::Type::DEL_BRACE_R) {
616 ParseFunctionCode();
617 } else if (open_) {
618 curr_func_->body_presence = true;
619 }
620
621 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
622 LOG(DEBUG, ASSEMBLER) << "function body is closed, line " << line_stric_ << ": "
623 << tokens[0].whole_line;
624
625 curr_func_->body_location.end = GetCurrentPosition(true);
626 ++context_;
627 open_ = false;
628 }
629 }
630 }
631 }
632
ParseAsBraceRight(const std::vector<Token> & tokens)633 void Parser::ParseAsBraceRight(const std::vector<Token> &tokens)
634 {
635 if (!open_) {
636 context_.err =
637 GetError("Delimiter '}' for the code area is outside a function.", Error::ErrorType::ERR_BAD_BOUND);
638 return;
639 }
640
641 LOG(DEBUG, ASSEMBLER) << "body is closed (line " << line_stric_ << "): " << tokens[0].whole_line;
642
643 open_ = false;
644 if (func_def_) {
645 curr_func_->body_location.end = GetCurrentPosition(true);
646 } else if (record_def_) {
647 curr_record_->body_location.end = GetCurrentPosition(true);
648 } else if (array_def_) {
649 if (!ArrayElementsValidNumber()) {
650 context_.err =
651 GetError("Constant array must contain at least one element.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
652 return;
653 }
654 } else {
655 LOG(FATAL, ASSEMBLER) << "Internal error: either function or record must be parsed here";
656 }
657 ++context_;
658 }
659
ParseResetFunctionLabelsAndParams()660 void Parser::ParseResetFunctionLabelsAndParams()
661 {
662 if (open_ || err_.err != Error::ErrorType::ERR_NONE) {
663 return;
664 }
665
666 for (const auto &f : program_.function_table) {
667 for (const auto &k : f.second.label_table) {
668 if (!k.second.file_location->is_defined) {
669 context_.err = Error("This label does not exist.", line_stric_, Error::ErrorType::ERR_BAD_LABEL_EXT, "",
670 k.second.file_location->bound_left, k.second.file_location->bound_right,
671 k.second.file_location->whole_line);
672 SetError();
673 }
674 }
675 }
676
677 for (const auto &t : context_.function_arguments_lists) {
678 curr_func_ = &(program_.function_table.at(t.first));
679 curr_func_->regs_num = static_cast<size_t>(curr_func_->value_of_first_param + 1);
680
681 for (const auto &v : t.second) {
682 if (!curr_func_->ins.empty() && curr_func_->ins.size() >= v.first &&
683 !curr_func_->ins[v.first - 1]->Regs().empty()) {
684 auto &ins = curr_func_->ins[v.first - 1];
685 auto reg = ins->Regs()[v.second];
686 reg += static_cast<uint16_t>(curr_func_->value_of_first_param + 1);
687 ins->SetReg(v.second, reg);
688 size_t max_reg_number = (1 << ins->MaxRegEncodingWidth());
689 if (reg >= max_reg_number) {
690 const auto &debug = ins->ins_debug;
691 context_.err =
692 Error("Register width mismatch.", debug.line_number, Error::ErrorType::ERR_BAD_NAME_REG, "",
693 0, 0, "");
694 SetError();
695 break;
696 }
697 }
698 }
699 }
700 }
701
ParseResetFunctionTable()702 void Parser::ParseResetFunctionTable()
703 {
704 for (auto &k : program_.function_table) {
705 if (!k.second.file_location->is_defined) {
706 context_.err = Error("This function does not exist.", k.second.file_location->line_number,
707 Error::ErrorType::ERR_BAD_ID_FUNCTION, "", k.second.file_location->bound_left,
708 k.second.file_location->bound_right, k.second.file_location->whole_line);
709 SetError();
710 } else {
711 for (auto insn_it = k.second.ins.begin(); insn_it != k.second.ins.end(); ++insn_it) {
712 if (!((*insn_it)->IsCall() || (*insn_it)->IsCallRange())) {
713 continue;
714 }
715
716 size_t diff = 1;
717 auto func_name = (*insn_it)->GetId(0);
718 if (!IsSignatureOrMangled(func_name)) {
719 const auto it_synonym = program_.function_synonyms.find(func_name);
720 if (it_synonym == program_.function_synonyms.end()) {
721 continue;
722 } else if (it_synonym->second.size() > 1) {
723 const auto &debug = (*insn_it)->ins_debug;
724 context_.err = Error("Unable to resolve ambiguous function call", debug.line_number,
725 Error::ErrorType::ERR_FUNCTION_MULTIPLE_ALTERNATIVES, "", 0, 0, "");
726 SetError();
727 break;
728 } else {
729 (*insn_it)->GetId(0) = program_.function_synonyms.at(func_name)[0];
730 }
731 }
732
733 if ((*insn_it)->OperandListLength() - diff >=
734 program_.function_table.at((*insn_it)->GetId(0)).GetParamsNum()) {
735 continue;
736 }
737 if ((*insn_it)->IsCallRange() &&
738 (static_cast<int>((*insn_it)->Regs().size()) - static_cast<int>(diff) >= 0)) {
739 continue;
740 }
741
742 const auto &debug = (*insn_it)->ins_debug;
743 context_.err = Error("Function argument mismatch.", debug.line_number,
744 Error::ErrorType::ERR_FUNCTION_ARGUMENT_MISMATCH, "", 0, 0, "");
745 SetError();
746 }
747 }
748 }
749 }
750
ParseResetRecordTable()751 void Parser::ParseResetRecordTable()
752 {
753 for (const auto &k : program_.record_table) {
754 if (!k.second.file_location->is_defined) {
755 context_.err = Error("This record does not exist.", k.second.file_location->line_number,
756 Error::ErrorType::ERR_BAD_ID_RECORD, "", k.second.file_location->bound_left,
757 k.second.file_location->bound_right, k.second.file_location->whole_line);
758 SetError();
759 } else if (k.second.HasImplementation() != k.second.body_presence) {
760 context_.err = Error("Inconsistency of the definition of the record and its metadata.",
761 k.second.file_location->line_number, Error::ErrorType::ERR_BAD_DEFINITION_RECORD, "",
762 k.second.file_location->bound_left, k.second.file_location->bound_right,
763 k.second.file_location->whole_line);
764 SetError();
765 } else {
766 for (const auto &fld : k.second.field_list) {
767 if (!fld.is_defined) {
768 context_.err =
769 Error("This field does not exist.", fld.line_of_def, Error::ErrorType::ERR_BAD_ID_FIELD, "",
770 fld.bound_left, fld.bound_right, fld.whole_line);
771 SetError();
772 }
773 }
774 }
775 }
776 }
ParseResetTables()777 void Parser::ParseResetTables()
778 {
779 if (err_.err != Error::ErrorType::ERR_NONE) {
780 return;
781 }
782
783 ParseResetFunctionTable();
784
785 if (err_.err != Error::ErrorType::ERR_NONE) {
786 return;
787 }
788
789 ParseResetRecordTable();
790 }
791
ParseAsLanguageDirective()792 void Parser::ParseAsLanguageDirective()
793 {
794 ++context_;
795
796 if (context_.Mask()) {
797 context_.err = GetError("Incorrect .language directive: Expected language",
798 Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
799 return;
800 }
801
802 auto lang = context_.GiveToken();
803 auto res = panda::panda_file::LanguageFromString(lang);
804 if (!res) {
805 context_.err =
806 GetError("Incorrect .language directive: Unknown language", Error::ErrorType::ERR_UNKNOWN_LANGUAGE);
807 return;
808 }
809
810 ++context_;
811
812 if (!context_.Mask()) {
813 context_.err = GetError("Incorrect .language directive: Unexpected token",
814 Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
815 }
816
817 program_.lang = res.value();
818 }
819
PrepareCatchBlock(bool is_catchall,size_t size,size_t catchall_tokens_num,size_t catch_tokens_num)820 Function::CatchBlock Parser::PrepareCatchBlock(bool is_catchall, size_t size, size_t catchall_tokens_num,
821 size_t catch_tokens_num)
822 {
823 constexpr size_t TRY_BEGIN = 0;
824 constexpr size_t TRY_END = 1;
825 constexpr size_t CATCH_BEGIN = 2;
826 constexpr size_t CATCH_END = 3;
827
828 Function::CatchBlock catch_block;
829 catch_block.whole_line = context_.tokens[0].whole_line;
830 std::vector<std::string> label_names {"try block begin", "try block end", "catch block begin"};
831 std::vector<std::string> labels;
832 bool full_catch_block = (is_catchall && size == catchall_tokens_num) || (!is_catchall && size == catch_tokens_num);
833 if (full_catch_block) {
834 label_names.emplace_back("catch block end");
835 }
836 if (!is_catchall) {
837 catch_block.exception_record = context_.GiveToken();
838 ++context_;
839 }
840
841 bool skip_comma = is_catchall;
842 for (auto label_name : label_names) {
843 if (!skip_comma) {
844 if (*context_ != Token::Type::DEL_COMMA) {
845 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
846 return catch_block;
847 }
848 ++context_;
849 }
850 skip_comma = false;
851 if (!LabelValidName()) {
852 context_.err =
853 GetError(std::string("Invalid name of the ") + label_name + " label.", Error::ErrorType::ERR_BAD_LABEL);
854 return catch_block;
855 }
856 labels.emplace_back(context_.GiveToken());
857 AddObjectInTable(false, *label_table_);
858 ++context_;
859 }
860
861 ASSERT(context_.Mask());
862 catch_block.try_begin_label = labels[TRY_BEGIN];
863 catch_block.try_end_label = labels[TRY_END];
864 catch_block.catch_begin_label = labels[CATCH_BEGIN];
865 if (full_catch_block) {
866 catch_block.catch_end_label = labels[CATCH_END];
867 } else {
868 catch_block.catch_end_label = labels[CATCH_BEGIN];
869 }
870 return catch_block;
871 }
872
ParseAsCatchDirective()873 void Parser::ParseAsCatchDirective()
874 {
875 ASSERT(*context_ == Token::Type::ID_CATCH || *context_ == Token::Type::ID_CATCHALL);
876
877 constexpr size_t CATCH_DIRECTIVE_TOKENS_NUM = 8;
878 constexpr size_t CATCHALL_DIRECTIVE_TOKENS_NUM = 6;
879 constexpr size_t CATCH_FULL_DIRECTIVE_TOKENS_NUM = 10;
880 constexpr size_t CATCHALL_FULL_DIRECTIVE_TOKENS_NUM = 8;
881
882 bool is_catchall = *context_ == Token::Type::ID_CATCHALL;
883 size_t size = context_.tokens.size();
884 if (is_catchall && size != CATCHALL_DIRECTIVE_TOKENS_NUM && size != CATCHALL_FULL_DIRECTIVE_TOKENS_NUM) {
885 context_.err = GetError(
886 "Incorrect catch block declaration. Must be in the format: .catchall <try_begin_label>, <try_end_label>, "
887 "<catch_begin_label>[, <catch_end_label>]",
888 Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
889 return;
890 }
891
892 if (!is_catchall && size != CATCH_DIRECTIVE_TOKENS_NUM && size != CATCH_FULL_DIRECTIVE_TOKENS_NUM) {
893 context_.err = GetError(
894 "Incorrect catch block declaration. Must be in the format: .catch <exception_record>, <try_begin_label>, "
895 "<try_end_label>, <catch_begin_label>[, <catch_end_label>]",
896 Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
897 return;
898 }
899
900 ++context_;
901
902 if (!is_catchall && !RecordValidName()) {
903 context_.err = GetError("Invalid name of the exception record.", Error::ErrorType::ERR_BAD_RECORD_NAME);
904 return;
905 }
906
907 Function::CatchBlock catch_block =
908 PrepareCatchBlock(is_catchall, size, CATCHALL_FULL_DIRECTIVE_TOKENS_NUM, CATCH_FULL_DIRECTIVE_TOKENS_NUM);
909
910 curr_func_->catch_blocks.push_back(catch_block);
911 }
912
ParseAsCatchall(const std::vector<Token> & tokens)913 void Parser::ParseAsCatchall(const std::vector<Token> &tokens)
914 {
915 std::string directive_name = *context_ == Token::Type::ID_CATCH ? ".catch" : ".catchall";
916 if (!func_def_) {
917 context_.err = GetError(directive_name + " directive is located outside of a function body.",
918 Error::ErrorType::ERR_INCORRECT_DIRECTIVE_LOCATION);
919 return;
920 }
921
922 LOG(DEBUG, ASSEMBLER) << "started parsing of " << directive_name << " directive (line " << line_stric_
923 << "): " << tokens[0].whole_line;
924
925 ParseAsCatchDirective();
926 }
927
ParseAsLanguage(const std::vector<Token> & tokens,bool & is_lang_parsed,bool & is_first_statement)928 void Parser::ParseAsLanguage(const std::vector<Token> &tokens, bool &is_lang_parsed, bool &is_first_statement)
929 {
930 if (is_lang_parsed) {
931 context_.err = GetError("Multiple .language directives", Error::ErrorType::ERR_MULTIPLE_DIRECTIVES);
932 return;
933 }
934
935 if (!is_first_statement) {
936 context_.err = GetError(".language directive must be specified before any other declarations",
937 Error::ErrorType::ERR_INCORRECT_DIRECTIVE_LOCATION);
938 return;
939 }
940
941 LOG(DEBUG, ASSEMBLER) << "started parsing of .language directive (line " << line_stric_
942 << "): " << tokens[0].whole_line;
943
944 ParseAsLanguageDirective();
945
946 is_lang_parsed = true;
947 }
948
ParseAfterLine(bool & is_first_statement)949 bool Parser::ParseAfterLine(bool &is_first_statement)
950 {
951 SetError();
952
953 if (!context_.Mask() && err_.err == Error::ErrorType::ERR_NONE) {
954 context_.err = GetError("There can be nothing after.", Error::ErrorType::ERR_BAD_END);
955 }
956
957 if (err_.err != Error::ErrorType::ERR_NONE) {
958 LOG(DEBUG, ASSEMBLER) << "processing aborted (error detected)";
959 return false;
960 }
961
962 LOG(DEBUG, ASSEMBLER) << "parsing of line " << line_stric_ << " is successful";
963
964 SetError();
965
966 is_first_statement = false;
967
968 return true;
969 }
970
ParseAfterMainLoop(const std::string & file_name)971 Expected<Program, Error> Parser::ParseAfterMainLoop(const std::string &file_name)
972 {
973 ParseResetFunctionLabelsAndParams();
974
975 if (open_ && err_.err == Error::ErrorType::ERR_NONE) {
976 context_.err = Error("Code area is not closed.", curr_func_->file_location->line_number,
977 Error::ErrorType::ERR_BAD_CLOSE, "", 0, curr_func_->name.size(), curr_func_->name);
978 SetError();
979 }
980
981 ParseResetTables();
982
983 if (err_.err != Error::ErrorType::ERR_NONE) {
984 return Unexpected(err_);
985 }
986
987 for (auto &func : program_.function_table) {
988 if (func.second.HasImplementation()) {
989 func.second.source_file = file_name;
990 }
991 }
992
993 for (auto &rec : program_.record_table) {
994 if (rec.second.HasImplementation()) {
995 rec.second.source_file = file_name;
996 }
997 }
998
999 return std::move(program_);
1000 }
1001
Parse(TokenSet & vectors_tokens,const std::string & file_name)1002 Expected<Program, Error> Parser::Parse(TokenSet &vectors_tokens, const std::string &file_name)
1003 {
1004 bool is_lang_parsed = false;
1005 bool is_first_statement = true;
1006
1007 for (const auto &tokens : vectors_tokens) {
1008 ++line_stric_;
1009
1010 if (tokens.empty()) {
1011 continue;
1012 }
1013
1014 LOG(DEBUG, ASSEMBLER) << "started parsing of line " << line_stric_ << ": " << tokens[0].whole_line;
1015
1016 context_.Make(tokens);
1017
1018 switch (*context_) {
1019 case Token::Type::ID_CATCH:
1020 case Token::Type::ID_CATCHALL: {
1021 ParseAsCatchall(tokens);
1022 break;
1023 }
1024 case Token::Type::ID_LANG: {
1025 ParseAsLanguage(tokens, is_lang_parsed, is_first_statement);
1026 break;
1027 }
1028 case Token::Type::ID_REC: {
1029 ParseAsRecord(tokens);
1030 break;
1031 }
1032 case Token::Type::ID_FUN: {
1033 ParseAsFunction(tokens);
1034 break;
1035 }
1036 case Token::Type::ID_ARR: {
1037 ParseAsArray(tokens);
1038 break;
1039 }
1040 case Token::Type::DEL_BRACE_R: {
1041 ParseAsBraceRight(tokens);
1042 break;
1043 }
1044 default: {
1045 if (func_def_) {
1046 ParseFunctionCode();
1047 } else if (record_def_) {
1048 ParseRecordFields();
1049 } else if (array_def_) {
1050 ParseArrayElements();
1051 }
1052 }
1053 }
1054 if (!ParseAfterLine(is_first_statement)) {
1055 break;
1056 }
1057 }
1058
1059 return ParseAfterMainLoop(file_name);
1060 }
1061
Parse(const std::string & source,const std::string & file_name)1062 Expected<Program, Error> Parser::Parse(const std::string &source, const std::string &file_name)
1063 {
1064 auto ss = std::stringstream(source);
1065 std::string line;
1066
1067 Lexer l;
1068 std::vector<std::vector<Token>> v;
1069
1070 while (std::getline(ss, line)) {
1071 auto [tokens, error] = l.TokenizeString(line);
1072 if (error.err != Error::ErrorType::ERR_NONE) {
1073 return Unexpected(error);
1074 }
1075
1076 v.push_back(tokens);
1077 }
1078
1079 return Parse(v, file_name);
1080 }
1081
SetError()1082 void Parser::SetError()
1083 {
1084 err_ = context_.err;
1085 }
1086
RegValidName()1087 bool Parser::RegValidName()
1088 {
1089 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1090 return false;
1091 }
1092
1093 if (curr_func_->GetParamsNum() > 0) {
1094 return context_.ValidateRegisterName('v') || context_.ValidateRegisterName('a', curr_func_->GetParamsNum() - 1);
1095 }
1096
1097 return context_.ValidateRegisterName('v');
1098 }
1099
ParamValidName()1100 bool Parser::ParamValidName()
1101 {
1102 return context_.ValidateParameterName(curr_func_->GetParamsNum());
1103 }
1104
IsAlphaNumeric(char c)1105 bool IsAlphaNumeric(char c)
1106 {
1107 return std::isalnum(c) != 0 || c == '_';
1108 }
1109
IsNonDigit(char c)1110 bool IsNonDigit(char c)
1111 {
1112 return std::isalpha(c) != 0 || c == '_';
1113 }
1114
PrefixedValidName()1115 bool Parser::PrefixedValidName()
1116 {
1117 auto s = context_.GiveToken();
1118 if (!IsNonDigit(s[0])) {
1119 return false;
1120 }
1121
1122 size_t i = 1;
1123
1124 while (i < s.size()) {
1125 if (s[i] == '.') {
1126 ++i;
1127 if (i >= s.size() || !IsNonDigit(s[i])) {
1128 return false;
1129 }
1130 } else if (!IsAlphaNumeric(s[i]) && s[i] != '$') {
1131 return false;
1132 }
1133
1134 ++i;
1135 }
1136
1137 return true;
1138 }
1139
RecordValidName()1140 bool Parser::RecordValidName()
1141 {
1142 return PrefixedValidName();
1143 }
1144
FunctionValidName()1145 bool Parser::FunctionValidName()
1146 {
1147 return PrefixedValidName();
1148 }
1149
ArrayValidName()1150 bool Parser::ArrayValidName()
1151 {
1152 return PrefixedValidName();
1153 }
1154
LabelValidName()1155 bool Parser::LabelValidName()
1156 {
1157 auto token = context_.GiveToken();
1158 if (!IsNonDigit(token[0])) {
1159 return false;
1160 }
1161
1162 token.remove_prefix(1);
1163
1164 for (auto i : token) {
1165 if (!IsAlphaNumeric(i)) {
1166 return false;
1167 }
1168 }
1169
1170 return true;
1171 }
1172
ParseLabel()1173 bool Parser::ParseLabel()
1174 {
1175 LOG(DEBUG, ASSEMBLER) << "label search started (line " << line_stric_ << "): " << context_.tokens[0].whole_line;
1176
1177 context_++;
1178
1179 if (*context_ == Token::Type::DEL_COLON) {
1180 context_--;
1181 if (LabelValidName()) {
1182 if (AddObjectInTable(true, *label_table_)) {
1183 set_label_ = true;
1184 label_ = context_.GiveToken();
1185
1186 LOG(DEBUG, ASSEMBLER) << "label detected (line " << line_stric_ << "): " << context_.GiveToken();
1187
1188 context_++;
1189 context_++;
1190 return !context_.Mask();
1191 }
1192
1193 LOG(DEBUG, ASSEMBLER) << "label is detected (line " << line_stric_ << "): " << context_.GiveToken()
1194 << ", but this label already exists";
1195
1196 context_.err = GetError("This label already exists.", Error::ErrorType::ERR_BAD_LABEL_EXT);
1197
1198 } else {
1199 LOG(DEBUG, ASSEMBLER) << "label with non-standard character is detected, attempt to create a label is "
1200 "supposed, but this cannot be any label name (line "
1201 << line_stric_ << "): " << context_.GiveToken();
1202
1203 context_.err = GetError(
1204 "Invalid name of label. Label contains only characters: '_', '0' - '9', 'a' - 'z', 'A' - 'Z'; and "
1205 "starts with any letter or with '_'.",
1206 Error::ErrorType::ERR_BAD_LABEL);
1207 }
1208
1209 return false;
1210 }
1211
1212 context_--;
1213
1214 LOG(DEBUG, ASSEMBLER) << "label is not detected (line " << line_stric_ << ")";
1215
1216 return true;
1217 }
1218
TokenToOpcode(Token::Type id)1219 static Opcode TokenToOpcode(Token::Type id)
1220 {
1221 ASSERT(id > Token::Type::OPERATION && id < Token::Type::KEYWORD);
1222 using utype = std::underlying_type_t<Token::Type>;
1223 return static_cast<Opcode>(static_cast<utype>(id) - static_cast<utype>(Token::Type::OPERATION) - 1);
1224 }
1225
ParseOperation()1226 bool Parser::ParseOperation()
1227 {
1228 if (context_.Mask()) {
1229 LOG(DEBUG, ASSEMBLER) << "no more tokens (line " << line_stric_ << "): " << context_.tokens[0].whole_line;
1230
1231 return false;
1232 }
1233
1234 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
1235 return false;
1236 }
1237
1238 LOG(DEBUG, ASSEMBLER) << "operaion search started (line " << line_stric_ << "): " << context_.tokens[0].whole_line;
1239
1240 if (*context_ > Token::Type::OPERATION && *context_ < Token::Type::KEYWORD) {
1241 SetOperationInformation();
1242
1243 context_.UpSignOperation();
1244 opcode_ = TokenToOpcode(context_.id);
1245
1246 LOG(DEBUG, ASSEMBLER) << "operatiuon is detected (line " << line_stric_ << "): " << context_.GiveToken()
1247 << " (operand type: " << OperandTypePrint(opcode_) << ")";
1248
1249 context_++;
1250 return true;
1251 }
1252
1253 LOG(DEBUG, ASSEMBLER) << "founded " << context_.GiveToken() << ", it is not an operation (line " << line_stric_
1254 << ")";
1255
1256 context_.err = GetError("Invalid operation.", Error::ErrorType::ERR_BAD_OPERATION_NAME);
1257
1258 return false;
1259 }
1260
ParseOperandVreg()1261 bool Parser::ParseOperandVreg()
1262 {
1263 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1264 return false;
1265 }
1266
1267 if (*context_ != Token::Type::ID) {
1268 context_.err = GetError("Expected register.", Error::ErrorType::ERR_BAD_OPERAND, +1);
1269 return false;
1270 }
1271
1272 std::string_view p = context_.GiveToken();
1273 if (p[0] == 'v') {
1274 p.remove_prefix(1);
1275 int64_t number = static_cast<int64_t>(ToNumber(p));
1276 if (number > *(context_.max_value_of_reg)) {
1277 *(context_.max_value_of_reg) = number;
1278 }
1279
1280 regs_.push_back(static_cast<uint16_t>(number));
1281 } else if (p[0] == 'a') {
1282 p.remove_prefix(1);
1283 regs_.push_back(static_cast<uint16_t>(ToNumber(p)));
1284 context_.function_arguments_list->emplace_back(context_.ins_number, regs_.size() - 1);
1285 }
1286
1287 ++context_;
1288 return true;
1289 }
1290
ParseOperandCall()1291 bool Parser::ParseOperandCall()
1292 {
1293 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1294 return false;
1295 }
1296
1297 if (!FunctionValidName()) {
1298 context_.err = GetError("Invalid name of function.", Error::ErrorType::ERR_BAD_NAME_REG);
1299 return false;
1300 }
1301
1302 const auto p = std::string(context_.GiveToken().data(), context_.GiveToken().length());
1303 ids_.emplace_back(p);
1304
1305 AddObjectInTable(false, program_.function_table);
1306
1307 ++context_;
1308
1309 std::string func_signature {};
1310
1311 if (!ParseOperandSignature(&func_signature)) {
1312 return false;
1313 }
1314
1315 if (func_signature.empty()) {
1316 const auto it_synonym = program_.function_synonyms.find(ids_.back());
1317 if (it_synonym == program_.function_synonyms.end()) {
1318 return true;
1319 }
1320
1321 if (it_synonym->second.size() > 1) {
1322 context_.err = GetError("Unable to resolve ambiguous function call",
1323 Error::ErrorType::ERR_FUNCTION_MULTIPLE_ALTERNATIVES);
1324 return false;
1325 }
1326
1327 program_.function_table.erase(p);
1328 } else {
1329 ids_.back() += func_signature;
1330
1331 if (program_.function_table.find(ids_.back()) == program_.function_table.end()) {
1332 auto node_handle = program_.function_table.extract(p);
1333 node_handle.key() = ids_.back();
1334 program_.function_table.insert(std::move(node_handle));
1335 } else {
1336 program_.function_table.erase(p);
1337 }
1338 }
1339
1340 return true;
1341 }
1342
ParseOperandSignature(std::string * sign)1343 bool Parser::ParseOperandSignature(std::string *sign)
1344 {
1345 if (*context_ != Token::Type::DEL_COLON) {
1346 // no signature provided
1347 return true;
1348 }
1349
1350 ++context_;
1351
1352 if (*context_ != Token::Type::DEL_BRACKET_L) {
1353 context_.err = GetError("Expected \'(\' before signature", Error::ErrorType::ERR_BAD_SIGNATURE);
1354 return false;
1355 }
1356
1357 ++context_;
1358
1359 *sign += ":(";
1360
1361 if (!ParseOperandSignatureTypesList(sign)) {
1362 return false;
1363 }
1364
1365 if (*context_ != Token::Type::DEL_BRACKET_R) {
1366 context_.err = GetError("Expected \')\' at the end of the signature", Error::ErrorType::ERR_BAD_SIGNATURE);
1367 return false;
1368 }
1369
1370 *sign += ")";
1371
1372 ++context_;
1373
1374 return true;
1375 }
1376
ParseOperandSignatureTypesList(std::string * sign)1377 bool Parser::ParseOperandSignatureTypesList(std::string *sign)
1378 {
1379 bool comma = false;
1380
1381 while (true) {
1382 if (context_.Mask()) {
1383 return true;
1384 }
1385
1386 if (*context_ != Token::Type::DEL_COMMA && *context_ != Token::Type::ID) {
1387 break;
1388 }
1389
1390 if (comma) {
1391 *sign += ",";
1392 }
1393
1394 if (!ParseFunctionArgComma(comma)) {
1395 return false;
1396 }
1397
1398 if (*context_ != Token::Type::ID) {
1399 context_.err = GetError("Expected signature arguments", Error::ErrorType::ERR_BAD_SIGNATURE_PARAMETERS);
1400 return false;
1401 }
1402
1403 if (!TypeValidName()) {
1404 context_.err = GetError("Expected valid type", Error::ErrorType::ERR_BAD_TYPE);
1405 return false;
1406 }
1407
1408 Type type;
1409 if (!ParseType(&type)) {
1410 return false;
1411 }
1412
1413 *sign += type.GetName();
1414 }
1415
1416 return true;
1417 }
1418
IsOctal(char c)1419 static bool IsOctal(char c)
1420 {
1421 return c >= '0' && c <= '7';
1422 }
1423
IsHex(char c)1424 static bool IsHex(char c)
1425 {
1426 return std::isxdigit(c) != 0;
1427 }
1428
FromHex(char c)1429 static uint8_t FromHex(char c)
1430 {
1431 constexpr size_t DIGIT_NUM = 10;
1432
1433 if (c >= '0' && c <= '9') {
1434 return c - '0';
1435 }
1436
1437 if (c >= 'A' && c <= 'F') {
1438 return c - 'A' + DIGIT_NUM;
1439 }
1440
1441 return c - 'a' + DIGIT_NUM;
1442 }
1443
FromOctal(char c)1444 static uint8_t FromOctal(char c)
1445 {
1446 return c - '0';
1447 }
1448
ParseOctalEscapeSequence(std::string_view s,size_t * i)1449 Expected<char, Error> Parser::ParseOctalEscapeSequence(std::string_view s, size_t *i)
1450 {
1451 constexpr size_t OCT_SHIFT = 3;
1452
1453 size_t idx = *i;
1454 size_t n = 0;
1455 uint32_t r = 0;
1456
1457 while (idx < s.length() && IsOctal(s[idx]) && n < OCT_SHIFT) {
1458 r |= FromOctal(s[idx++]);
1459 r <<= 3U;
1460 ++n;
1461 }
1462
1463 r >>= 3U;
1464 *i += n;
1465
1466 return r;
1467 }
1468
ParseHexEscapeSequence(std::string_view s,size_t * i)1469 Expected<char, Error> Parser::ParseHexEscapeSequence(std::string_view s, size_t *i)
1470 {
1471 constexpr size_t HEX_SHIFT = 2;
1472
1473 uint32_t r = 0;
1474 size_t idx = *i;
1475
1476 for (size_t j = 0; j < HEX_SHIFT; j++) {
1477 char v = s[(*i)++];
1478
1479 if (!IsHex(v)) {
1480 return Unexpected(GetError("Invalid \\x escape sequence",
1481 Error::ErrorType::ERR_BAD_STRING_INVALID_HEX_ESCAPE_SEQUENCE, idx - HEX_SHIFT));
1482 }
1483
1484 r |= FromHex(v);
1485 r <<= 4U;
1486 }
1487
1488 r >>= 4U;
1489
1490 return r;
1491 }
1492
ParseEscapeSequence(std::string_view s,size_t * i)1493 Expected<char, Error> Parser::ParseEscapeSequence(std::string_view s, size_t *i)
1494 {
1495 size_t idx = *i;
1496
1497 char c = s[idx];
1498
1499 if (IsOctal(c)) {
1500 return ParseOctalEscapeSequence(s, i);
1501 }
1502
1503 ++(*i);
1504
1505 switch (c) {
1506 case '\'':
1507 case '"':
1508 case '\\':
1509 return c;
1510 case 'a':
1511 return '\a';
1512 case 'b':
1513 return '\b';
1514 case 'f':
1515 return '\f';
1516 case 'n':
1517 return '\n';
1518 case 'r':
1519 return '\r';
1520 case 't':
1521 return '\t';
1522 case 'v':
1523 return '\v';
1524 default:
1525 break;
1526 }
1527
1528 if (c == 'x') {
1529 return ParseHexEscapeSequence(s, i);
1530 }
1531
1532 return Unexpected(
1533 GetError("Unknown escape sequence", Error::ErrorType::ERR_BAD_STRING_UNKNOWN_ESCAPE_SEQUENCE, idx - 1));
1534 }
1535
ParseStringLiteral()1536 std::optional<std::string> Parser::ParseStringLiteral()
1537 {
1538 auto token = context_.GiveToken();
1539 if (*context_ != Token::Type::ID_STRING) {
1540 context_.err = GetError("Expected string literal", Error::ErrorType::ERR_BAD_OPERAND);
1541 return {};
1542 }
1543
1544 size_t i = 1; /* skip leading quote */
1545 size_t len = token.length();
1546
1547 std::string s;
1548
1549 while (i < len - 1) {
1550 char c = token[i++];
1551
1552 if (c != '\\') {
1553 s.append(1, c);
1554 continue;
1555 }
1556
1557 auto res = ParseEscapeSequence(token, &i);
1558 if (!res) {
1559 context_.err = res.Error();
1560 return {};
1561 }
1562
1563 s.append(1, res.Value());
1564 }
1565
1566 program_.strings.insert(s);
1567
1568 return s;
1569 }
1570
ParseOperandString()1571 bool Parser::ParseOperandString()
1572 {
1573 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1574 return false;
1575 }
1576
1577 auto res = ParseStringLiteral();
1578 if (!res) {
1579 return false;
1580 }
1581
1582 ids_.push_back(res.value());
1583
1584 ++context_;
1585
1586 return true;
1587 }
1588
ParseOperandComma()1589 bool Parser::ParseOperandComma()
1590 {
1591 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1592 return false;
1593 }
1594
1595 if (context_++ != Token::Type::DEL_COMMA) {
1596 if (!context_.Mask() && *context_ != Token::Type::DEL_BRACKET_R) {
1597 --context_;
1598 }
1599
1600 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1601 return false;
1602 }
1603
1604 return true;
1605 }
1606
ParseInteger(int64_t * value)1607 bool Parser::ParseInteger(int64_t *value)
1608 {
1609 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1610 return false;
1611 }
1612
1613 if (*context_ != Token::Type::ID) {
1614 if (*context_ == Token::Type::DEL_BRACE_R) {
1615 --context_;
1616 }
1617 context_.err = GetError("Expected immediate.", Error::ErrorType::ERR_BAD_OPERAND, +1);
1618 return false;
1619 }
1620
1621 std::string_view p = context_.GiveToken();
1622 if (!ValidateInteger(p)) {
1623 context_.err = GetError("Expected integer.", Error::ErrorType::ERR_BAD_INTEGER_NAME);
1624 return false;
1625 }
1626
1627 *value = IntegerNumber(p);
1628 if (errno == ERANGE) {
1629 context_.err =
1630 GetError("Too large immediate (length is more than 64 bit).", Error::ErrorType::ERR_BAD_INTEGER_WIDTH);
1631 return false;
1632 }
1633
1634 return true;
1635 }
1636
ParseFloat(double * value,bool is_64bit)1637 bool Parser::ParseFloat(double *value, bool is_64bit)
1638 {
1639 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1640 return false;
1641 }
1642
1643 if (*context_ != Token::Type::ID) {
1644 if (*context_ == Token::Type::DEL_BRACE_R) {
1645 --context_;
1646 }
1647 context_.err = GetError("Expected immediate.", Error::ErrorType::ERR_BAD_OPERAND, +1);
1648 return false;
1649 }
1650
1651 std::string_view p = context_.GiveToken();
1652 if (!ValidateFloat(p)) {
1653 context_.err = GetError("Expected float.", Error::ErrorType::ERR_BAD_FLOAT_NAME);
1654 return false;
1655 }
1656
1657 *value = FloatNumber(p, is_64bit);
1658 if (errno == ERANGE) {
1659 context_.err =
1660 GetError("Too large immediate (length is more than 64 bit).", Error::ErrorType::ERR_BAD_FLOAT_WIDTH);
1661 return false;
1662 }
1663
1664 return true;
1665 }
1666
ParseOperandInteger()1667 bool Parser::ParseOperandInteger()
1668 {
1669 int64_t n;
1670 if (!ParseInteger(&n)) {
1671 return false;
1672 }
1673
1674 imms_.push_back(n);
1675 ++context_;
1676 return true;
1677 }
1678
ParseOperandFloat(bool is_64bit)1679 bool Parser::ParseOperandFloat(bool is_64bit)
1680 {
1681 double n;
1682 if (!ParseFloat(&n, is_64bit)) {
1683 return false;
1684 }
1685
1686 imms_.push_back(n);
1687 ++context_;
1688 return true;
1689 }
1690
ParseOperandLabel()1691 bool Parser::ParseOperandLabel()
1692 {
1693 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1694 return false;
1695 }
1696
1697 if (!LabelValidName()) {
1698 context_.err = GetError("Invalid name of Label.", Error::ErrorType::ERR_BAD_NAME_ID);
1699 return false;
1700 }
1701
1702 std::string_view p = context_.GiveToken();
1703 ids_.emplace_back(p.data(), p.length());
1704 AddObjectInTable(false, *label_table_);
1705
1706 ++context_;
1707
1708 return true;
1709 }
1710
ParseOperandId()1711 bool Parser::ParseOperandId()
1712 {
1713 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1714 return false;
1715 }
1716
1717 if (*context_ != Token::Type::ID) {
1718 context_.err = GetError("Expected Label.", Error::ErrorType::ERR_BAD_OPERAND);
1719 return false;
1720 }
1721 if (!LabelValidName()) {
1722 context_.err = GetError("Invalid name of Label.", Error::ErrorType::ERR_BAD_NAME_ID);
1723 return false;
1724 }
1725
1726 std::string_view p = context_.GiveToken();
1727 ids_.emplace_back(p.data(), p.length());
1728 AddObjectInTable(false, *label_table_);
1729
1730 ++context_;
1731
1732 return true;
1733 }
1734
ParseOperandType(Type::VerificationType ver_type)1735 bool Parser::ParseOperandType(Type::VerificationType ver_type)
1736 {
1737 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1738 return false;
1739 }
1740
1741 if (*context_ != Token::Type::ID) {
1742 context_.err = GetError("Expected type.", Error::ErrorType::ERR_BAD_OPERAND);
1743 return false;
1744 }
1745 if (!TypeValidName()) {
1746 context_.err = GetError("Invalid name of type.", Error::ErrorType::ERR_BAD_NAME_ID);
1747 return false;
1748 }
1749
1750 Type type;
1751 if (!ParseType(&type)) {
1752 return false;
1753 }
1754
1755 bool is_object = (context_.GiveToken() == "]") ? (false) : (true);
1756
1757 if (is_object) {
1758 AddObjectInTable(false, program_.record_table);
1759
1760 if (ver_type == Type::VerificationType::TYPE_ID_ARRAY) {
1761 GetWarning("Unexpected type_id recieved! Expected array, but object given",
1762 Error::ErrorType::WAR_UNEXPECTED_TYPE_ID);
1763 }
1764 } else {
1765 if (!type.IsArrayContainsPrimTypes() &&
1766 program_.record_table.find(type.GetComponentName()) == program_.record_table.end()) {
1767 std::string ComponentName = type.GetComponentName();
1768 context_.token = ComponentName;
1769 AddObjectInTable(false, program_.record_table);
1770 }
1771
1772 if (ver_type == Type::VerificationType::TYPE_ID_OBJECT) {
1773 GetWarning("Unexpected type_id recieved! Expected object, but array given",
1774 Error::ErrorType::WAR_UNEXPECTED_TYPE_ID);
1775 }
1776 }
1777
1778 ids_.push_back(type.GetName());
1779
1780 return true;
1781 }
1782
ParseOperandLiteralArray()1783 bool Parser::ParseOperandLiteralArray()
1784 {
1785 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1786 return false;
1787 }
1788
1789 if (*context_ != Token::Type::ID) {
1790 context_.err = GetError("Expected array id.", Error::ErrorType::ERR_BAD_OPERAND);
1791 return false;
1792 }
1793 if (!ArrayValidName()) {
1794 context_.err = GetError("Invalid name of array.", Error::ErrorType::ERR_BAD_NAME_ID);
1795 return false;
1796 }
1797
1798 std::string_view p = context_.GiveToken();
1799 auto array_id = std::string(p.data(), p.length());
1800 if (program_.literalarray_table.find(array_id) == program_.literalarray_table.end()) {
1801 context_.err = GetError("No array was found for this array id", Error::ErrorType::ERR_BAD_ID_ARRAY);
1802 return false;
1803 }
1804
1805 ids_.emplace_back(p.data(), p.length());
1806
1807 ++context_;
1808
1809 return true;
1810 }
1811
ParseOperandField()1812 bool Parser::ParseOperandField()
1813 {
1814 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1815 return false;
1816 }
1817
1818 if (*context_ != Token::Type::ID) {
1819 context_.err = GetError("Expected field.", Error::ErrorType::ERR_BAD_OPERAND);
1820 return false;
1821 }
1822 if (!PrefixedValidName()) {
1823 context_.err = GetError("Invalid name of field.", Error::ErrorType::ERR_BAD_NAME_ID);
1824 return false;
1825 }
1826
1827 std::string_view p = context_.GiveToken();
1828 std::string record_full_name = std::string(p);
1829 // Some names of records in pandastdlib starts with 'panda.', therefore,
1830 // the record name is before the second dot, and the field name is after the second dot
1831 auto pos_point = record_full_name.find_last_of('.');
1832 std::string record_name = record_full_name.substr(0, pos_point);
1833 std::string field_name = record_full_name.substr(pos_point + 1);
1834
1835 auto it_record = program_.record_table.find(record_name);
1836 if (it_record == program_.record_table.end()) {
1837 context_.token = record_name;
1838 AddObjectInTable(false, program_.record_table);
1839 it_record = program_.record_table.find(record_name);
1840 }
1841
1842 auto it_field = std::find_if(it_record->second.field_list.begin(), it_record->second.field_list.end(),
1843 [&field_name](pandasm::Field &field) { return field_name == field.name; });
1844
1845 if (!field_name.empty() && it_field == it_record->second.field_list.end()) {
1846 it_record->second.field_list.emplace_back(program_.lang);
1847 auto &field = it_record->second.field_list.back();
1848 field.name = field_name;
1849 field.line_of_def = line_stric_;
1850 field.whole_line = context_.tokens[context_.number - 1].whole_line;
1851 field.bound_left = context_.tokens[context_.number - 1].bound_left + record_name.length() + 1;
1852 field.bound_right = context_.tokens[context_.number - 1].bound_right;
1853 field.is_defined = false;
1854 }
1855
1856 ids_.emplace_back(p.data(), p.length());
1857
1858 ++context_;
1859
1860 return true;
1861 }
1862
ParseOperandNone()1863 bool Parser::ParseOperandNone()
1864 {
1865 if (context_.err.err != Error::ErrorType::ERR_NONE) {
1866 return false;
1867 }
1868
1869 if (open_ && *context_ == Token::Type::DEL_BRACE_R) {
1870 return false;
1871 }
1872
1873 if (!context_.Mask()) {
1874 context_.err = GetError("Invalid number of operands.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1875 --context_;
1876 return false;
1877 }
1878 return true;
1879 }
1880
ParseRecordFullSign()1881 bool Parser::ParseRecordFullSign()
1882 {
1883 return ParseRecordName();
1884 }
1885
ParseFunctionFullSign()1886 bool Parser::ParseFunctionFullSign()
1887 {
1888 if (!ParseFunctionReturn()) {
1889 return false;
1890 }
1891
1892 if (!ParseFunctionName()) {
1893 return false;
1894 }
1895
1896 if (*context_ == Token::Type::DEL_BRACKET_L) {
1897 ++context_;
1898
1899 if (ParseFunctionArgs()) {
1900 if (*context_ == Token::Type::DEL_BRACKET_R) {
1901 ++context_;
1902
1903 return UpdateFunctionName();
1904 }
1905 context_.err = GetError("Expected ')'.", Error::ErrorType::ERR_BAD_ARGS_BOUND);
1906 }
1907 } else {
1908 context_.err = GetError("Expected '('.", Error::ErrorType::ERR_BAD_ARGS_BOUND);
1909 }
1910
1911 return false;
1912 }
1913
UpdateFunctionName()1914 bool Parser::UpdateFunctionName()
1915 {
1916 auto signature = GetFunctionSignatureFromName(curr_func_->name, curr_func_->params);
1917 auto iter = program_.function_table.find(signature);
1918 if (iter == program_.function_table.end() || !iter->second.file_location->is_defined) {
1919 program_.function_synonyms[curr_func_->name].push_back(signature);
1920 program_.function_table.erase(signature);
1921 auto node_handle = program_.function_table.extract(curr_func_->name);
1922 node_handle.key() = signature;
1923 program_.function_table.insert(std::move(node_handle));
1924 curr_func_->name = signature;
1925 context_.max_value_of_reg = &(curr_func_->value_of_first_param);
1926 context_.function_arguments_list = &(context_.function_arguments_lists[curr_func_->name]);
1927
1928 return true;
1929 }
1930
1931 context_.err = GetError("This function already exists.", Error::ErrorType::ERR_BAD_ID_FUNCTION);
1932
1933 return false;
1934 }
1935
ParseArrayFullSign()1936 bool Parser::ParseArrayFullSign()
1937 {
1938 if (!ParseArrayName()) {
1939 return false;
1940 }
1941
1942 if (*context_ == Token::Type::DEL_BRACE_L) {
1943 return true;
1944 }
1945
1946 curr_array_->literals_.push_back(panda::pandasm::LiteralArray::Literal());
1947 curr_array_elem_ = &(curr_array_->literals_[curr_array_->literals_.size() - 1]);
1948
1949 if (!ParseArrayElementType()) {
1950 context_.err = GetError("Invalid array type for static array.", Error::ErrorType::ERR_BAD_ARRAY_TYPE);
1951 return false;
1952 }
1953
1954 curr_array_elem_->value_ = static_cast<uint8_t>(curr_array_elem_->tag_);
1955 curr_array_elem_->tag_ = panda_file::LiteralTag::TAGVALUE;
1956
1957 if (*context_ == Token::Type::DEL_BRACE_L) {
1958 context_.err = GetError("No array size for static array.", Error::ErrorType::ERR_BAD_ARRAY_SIZE);
1959 return false;
1960 }
1961
1962 curr_array_->literals_.push_back(panda::pandasm::LiteralArray::Literal());
1963 curr_array_elem_ = &(curr_array_->literals_[curr_array_->literals_.size() - 1]);
1964 curr_array_elem_->tag_ = panda_file::LiteralTag::INTEGER;
1965
1966 if (!ParseArrayElementValueInteger()) {
1967 context_.err =
1968 GetError("Invalid value for static array size value.", Error::ErrorType::ERR_BAD_ARRAY_SIZE_VALUE);
1969 return false;
1970 }
1971
1972 ++context_;
1973
1974 return true;
1975 }
1976
ParseRecordName()1977 bool Parser::ParseRecordName()
1978 {
1979 LOG(DEBUG, ASSEMBLER) << "started searching for record name (line " << line_stric_
1980 << "): " << context_.tokens[context_.number - 1].whole_line;
1981
1982 if (!RecordValidName()) {
1983 if (*context_ == Token::Type::DEL_BRACKET_L) {
1984 context_.err = GetError("No record name.", Error::ErrorType::ERR_BAD_RECORD_NAME);
1985 return false;
1986 }
1987 context_.err = GetError("Invalid name of the record.", Error::ErrorType::ERR_BAD_RECORD_NAME);
1988 return false;
1989 }
1990
1991 auto iter = program_.record_table.find(std::string(context_.GiveToken().data(), context_.GiveToken().length()));
1992 if (iter == program_.record_table.end() || !iter->second.file_location->is_defined) {
1993 SetRecordInformation();
1994 } else {
1995 context_.err = GetError("This record already exists.", Error::ErrorType::ERR_BAD_ID_RECORD);
1996 return false;
1997 }
1998
1999 LOG(DEBUG, ASSEMBLER) << "record name found (line " << line_stric_ << "): " << context_.GiveToken();
2000
2001 ++context_;
2002
2003 return true;
2004 }
2005
SetRecordInformation()2006 void Parser::SetRecordInformation()
2007 {
2008 AddObjectInTable(true, program_.record_table);
2009 curr_record_ = &(program_.record_table.at(std::string(context_.GiveToken().data(), context_.GiveToken().length())));
2010 }
2011
ParseFunctionName()2012 bool Parser::ParseFunctionName()
2013 {
2014 LOG(DEBUG, ASSEMBLER) << "started searching for function name (line " << line_stric_
2015 << "): " << context_.tokens[context_.number - 1].whole_line;
2016
2017 if (!FunctionValidName()) {
2018 if (*context_ == Token::Type::DEL_BRACKET_L) {
2019 context_.err = GetError("No function name.", Error::ErrorType::ERR_BAD_FUNCTION_NAME);
2020 return false;
2021 }
2022 context_.err = GetError("Invalid name of the function.", Error::ErrorType::ERR_BAD_FUNCTION_NAME);
2023 return false;
2024 }
2025
2026 // names are mangled, so no need to check for same names here
2027 SetFunctionInformation();
2028
2029 LOG(DEBUG, ASSEMBLER) << "function name found (line " << line_stric_ << "): " << context_.GiveToken();
2030
2031 ++context_;
2032
2033 return true;
2034 }
2035
SetFunctionInformation()2036 void Parser::SetFunctionInformation()
2037 {
2038 std::string p = std::string(context_.GiveToken());
2039 AddObjectInTable(true, program_.function_table);
2040 curr_func_ = &(program_.function_table.at(p));
2041 label_table_ = &(curr_func_->label_table);
2042 curr_func_->return_type = context_.curr_func_return_type;
2043 }
2044
ParseArrayName()2045 bool Parser::ParseArrayName()
2046 {
2047 LOG(DEBUG, ASSEMBLER) << "started searching for array name (line " << line_stric_
2048 << "): " << context_.tokens[context_.number - 1].whole_line;
2049
2050 if (!ArrayValidName()) {
2051 if (*context_ == Token::Type::DEL_BRACKET_L) {
2052 context_.err = GetError("No array name.", Error::ErrorType::ERR_BAD_ARRAY_NAME);
2053 return false;
2054 }
2055 context_.err = GetError("Invalid name of the array.", Error::ErrorType::ERR_BAD_ARRAY_NAME);
2056 return false;
2057 }
2058
2059 auto iter =
2060 program_.literalarray_table.find(std::string(context_.GiveToken().data(), context_.GiveToken().length()));
2061 if (iter == program_.literalarray_table.end()) {
2062 SetArrayInformation();
2063 } else {
2064 context_.err = GetError("This array already exists.", Error::ErrorType::ERR_BAD_ID_ARRAY);
2065 return false;
2066 }
2067
2068 LOG(DEBUG, ASSEMBLER) << "array id found (line " << line_stric_ << "): " << context_.GiveToken();
2069
2070 ++context_;
2071
2072 return true;
2073 }
2074
SetArrayInformation()2075 void Parser::SetArrayInformation()
2076 {
2077 program_.literalarray_table.try_emplace(std::string(context_.GiveToken().data(), context_.GiveToken().length()),
2078 panda::pandasm::LiteralArray());
2079
2080 curr_array_ =
2081 &(program_.literalarray_table.at(std::string(context_.GiveToken().data(), context_.GiveToken().length())));
2082 }
2083
SetOperationInformation()2084 void Parser::SetOperationInformation()
2085 {
2086 context_.ins_number = curr_func_->ins.size() + 1;
2087 curr_debug_.line_number = line_stric_;
2088 }
2089
ParseFunctionReturn()2090 bool Parser::ParseFunctionReturn()
2091 {
2092 LOG(DEBUG, ASSEMBLER) << "started searching for return function value (line " << line_stric_
2093 << "): " << context_.tokens[context_.number - 1].whole_line;
2094
2095 if (!TypeValidName()) {
2096 if (*context_ == Token::Type::DEL_BRACKET_L) {
2097 context_.err = GetError("No return type.", Error::ErrorType::ERR_BAD_FUNCTION_RETURN_VALUE);
2098 return false;
2099 }
2100 context_.err = GetError("Not a return type.", Error::ErrorType::ERR_BAD_FUNCTION_RETURN_VALUE);
2101 return false;
2102 }
2103
2104 if (!ParseType(&context_.curr_func_return_type)) {
2105 return false;
2106 }
2107
2108 LOG(DEBUG, ASSEMBLER) << "return type found (line " << line_stric_ << "): " << context_.GiveToken();
2109
2110 return true;
2111 }
2112
TypeValidName()2113 bool Parser::TypeValidName()
2114 {
2115 if (Type::GetId(context_.GiveToken()) != panda_file::Type::TypeId::REFERENCE) {
2116 return true;
2117 }
2118
2119 return PrefixedValidName();
2120 }
2121
ParseFunctionArg()2122 bool Parser::ParseFunctionArg()
2123 {
2124 if (*context_ != Token::Type::ID) {
2125 context_.err = GetError("Expected identifier.", Error::ErrorType::ERR_BAD_FUNCTION_PARAMETERS);
2126 return false;
2127 }
2128
2129 if (!TypeValidName()) {
2130 context_.err = GetError("Expected parameter type.", Error::ErrorType::ERR_BAD_TYPE);
2131 return false;
2132 }
2133
2134 Type type;
2135 if (!ParseType(&type)) {
2136 return false;
2137 }
2138
2139 if (context_.Mask()) {
2140 return false;
2141 }
2142
2143 if (*context_ != Token::Type::ID) {
2144 context_.err = GetError("Expected identifier.", Error::ErrorType::ERR_BAD_FUNCTION_PARAMETERS);
2145 return false;
2146 }
2147
2148 if (!ParamValidName()) {
2149 context_.err = GetError("Incorrect name of parameter.", Error::ErrorType::ERR_BAD_PARAM_NAME);
2150 return false;
2151 }
2152
2153 ++context_;
2154
2155 Function::Parameter parameter(type, program_.lang);
2156
2157 if (*context_ == Token::Type::DEL_LT && !ParseMetaDef()) {
2158 return false;
2159 }
2160
2161 curr_func_->params.push_back(std::move(parameter));
2162
2163 return true;
2164 }
2165
ParseFunctionArgComma(bool & comma)2166 bool Parser::ParseFunctionArgComma(bool &comma)
2167 {
2168 if (comma && *context_ != Token::Type::DEL_COMMA) {
2169 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
2170 return false;
2171 }
2172
2173 if (comma) {
2174 ++context_;
2175 }
2176
2177 comma = true;
2178
2179 return true;
2180 }
2181
ParseFunctionArgs()2182 bool Parser::ParseFunctionArgs()
2183 {
2184 LOG(DEBUG, ASSEMBLER) << "started searching for function parameters (line " << line_stric_
2185 << "): " << context_.tokens[context_.number - 1].whole_line;
2186
2187 bool comma = false;
2188
2189 while (true) {
2190 if (context_.Mask()) {
2191 return false;
2192 }
2193
2194 if (context_.id != Token::Type::DEL_COMMA && context_.id != Token::Type::ID) {
2195 break;
2196 }
2197
2198 if (!ParseFunctionArgComma(comma)) {
2199 return false;
2200 }
2201
2202 if (!ParseFunctionArg()) {
2203 return false;
2204 }
2205 }
2206
2207 LOG(DEBUG, ASSEMBLER) << "parameters found (line " << line_stric_ << "): ";
2208
2209 return true;
2210 }
2211
ParseMetaDef()2212 bool Parser::ParseMetaDef()
2213 {
2214 LOG(DEBUG, ASSEMBLER) << "started searching for meta information (line " << line_stric_
2215 << "): " << context_.tokens[context_.number - 1].whole_line;
2216
2217 bool flag = false;
2218
2219 if (context_.Mask()) {
2220 return false;
2221 }
2222
2223 if (*context_ == Token::Type::DEL_LT) {
2224 flag = true;
2225 ++context_;
2226 }
2227
2228 if (!ParseMetaList(flag)) {
2229 return false;
2230 }
2231
2232 if (!flag && *context_ == Token::Type::DEL_GT) {
2233 context_.err = GetError("Expected '<'.", Error::ErrorType::ERR_BAD_METADATA_BOUND);
2234 ++context_;
2235 return false;
2236 }
2237
2238 LOG(DEBUG, ASSEMBLER) << "searching for meta information (line " << line_stric_ << ") is successful";
2239
2240 if (flag && context_.err.err == Error::ErrorType::ERR_NONE) {
2241 ++context_;
2242 }
2243
2244 return true;
2245 }
2246
SetMetadataContextError(const Metadata::Error & err,bool has_value)2247 void Parser::SetMetadataContextError(const Metadata::Error &err, bool has_value)
2248 {
2249 constexpr int64_t NO_VALUE_OFF = -1;
2250 constexpr int64_t SPECIAL_OFF = -2;
2251 constexpr int64_t STANDARD_OFF = -3;
2252
2253 switch (err.GetType()) {
2254 case Metadata::Error::Type::UNKNOWN_ATTRIBUTE: {
2255 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_UNKNOWN_ATTRIBUTE, 0,
2256 has_value ? STANDARD_OFF : NO_VALUE_OFF);
2257 break;
2258 }
2259 case Metadata::Error::Type::MISSING_ATTRIBUTE: {
2260 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_MISSING_ATTRIBUTE);
2261 break;
2262 }
2263 case Metadata::Error::Type::MISSING_VALUE: {
2264 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_MISSING_VALUE);
2265 break;
2266 }
2267 case Metadata::Error::Type::UNEXPECTED_ATTRIBUTE: {
2268 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_UNEXPECTED_ATTRIBUTE, 0,
2269 has_value ? STANDARD_OFF : NO_VALUE_OFF);
2270 break;
2271 }
2272 case Metadata::Error::Type::UNEXPECTED_VALUE: {
2273 context_.err =
2274 GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_UNEXPECTED_VALUE, 0, SPECIAL_OFF);
2275 break;
2276 }
2277 case Metadata::Error::Type::INVALID_VALUE: {
2278 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_INVALID_VALUE, 0, -1);
2279 break;
2280 }
2281 case Metadata::Error::Type::MULTIPLE_ATTRIBUTE: {
2282 context_.err = GetError(err.GetMessage(), Error::ErrorType::ERR_BAD_METADATA_MULTIPLE_ATTRIBUTE, 0,
2283 has_value ? STANDARD_OFF : NO_VALUE_OFF);
2284 break;
2285 }
2286 default: {
2287 UNREACHABLE();
2288 }
2289 }
2290 }
2291
ParseMetaListComma(bool & comma,bool eq)2292 bool Parser::ParseMetaListComma(bool &comma, bool eq)
2293 {
2294 if (!eq && comma && *context_ != Token::Type::DEL_COMMA) {
2295 context_.err = GetError("Expected comma.", Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
2296 return false;
2297 }
2298
2299 if (!eq && comma) {
2300 ++context_;
2301 }
2302
2303 comma = true;
2304
2305 return true;
2306 }
2307
MeetExpMetaList(bool eq)2308 bool Parser::MeetExpMetaList(bool eq)
2309 {
2310 if (!eq && *context_ != Token::Type::ID) {
2311 context_.err = GetError("Expected identifier.", Error::ErrorType::ERR_BAD_DEFINITION_METADATA, +1);
2312 return false;
2313 }
2314
2315 if (eq && *context_ != Token::Type::ID && *context_ != Token::Type::ID_STRING) {
2316 context_.err =
2317 GetError("Expected identifier or string literal.", Error::ErrorType::ERR_BAD_DEFINITION_METADATA, +1);
2318 return false;
2319 }
2320
2321 if (!eq && !PrefixedValidName()) {
2322 context_.err = GetError("Invalid attribute name.", Error::ErrorType::ERR_BAD_NAME_ID);
2323 return false;
2324 }
2325
2326 return true;
2327 }
2328
BuildMetaListAttr(bool & eq,std::string & attribute_name,std::string & attribute_value)2329 bool Parser::BuildMetaListAttr(bool &eq, std::string &attribute_name, std::string &attribute_value)
2330 {
2331 if (eq && *context_ == Token::Type::ID_STRING) {
2332 auto res = ParseStringLiteral();
2333 if (!res) {
2334 return false;
2335 }
2336
2337 attribute_value = res.value();
2338 } else if (eq) {
2339 std::string sign {};
2340 attribute_value = context_.GiveToken();
2341 ++context_;
2342
2343 if (!ParseOperandSignature(&sign)) {
2344 return false;
2345 }
2346
2347 --context_;
2348 attribute_value += sign;
2349 } else {
2350 attribute_name = context_.GiveToken();
2351 }
2352
2353 ++context_;
2354
2355 if (context_.Mask()) {
2356 return false;
2357 }
2358
2359 if (*context_ == Token::Type::DEL_EQ) {
2360 if (eq) {
2361 context_.err = GetError("'=' was not expected.", Error::ErrorType::ERR_BAD_NOEXP_DELIM);
2362 return false;
2363 }
2364
2365 ++context_;
2366 eq = true;
2367 } else {
2368 std::optional<Metadata::Error> res;
2369 bool has_value = eq;
2370 if (has_value) {
2371 res = metadata_->SetAttributeValue(attribute_name, attribute_value);
2372 } else {
2373 res = metadata_->SetAttribute(attribute_name);
2374 }
2375
2376 eq = false;
2377
2378 if (res) {
2379 auto err = res.value();
2380 SetMetadataContextError(err, has_value);
2381 return false;
2382 }
2383 }
2384
2385 return true;
2386 }
2387
ParseMetaList(bool flag)2388 bool Parser::ParseMetaList(bool flag)
2389 {
2390 if (!flag && !context_.Mask() && *context_ != Token::Type::DEL_GT && *context_ != Token::Type::DEL_BRACE_L) {
2391 context_.err = GetError("No meta data expected.", Error::ErrorType::ERR_BAD_DEFINITION_METADATA);
2392 return false;
2393 }
2394
2395 bool comma = false;
2396 bool eq = false;
2397
2398 std::string attribute_name;
2399 std::string attribute_value;
2400
2401 while (true) {
2402 if (context_.Mask()) {
2403 context_.err = GetError("Expected '>'.", Error::ErrorType::ERR_BAD_METADATA_BOUND, +1);
2404 return false;
2405 }
2406
2407 if (context_.id != Token::Type::DEL_COMMA && context_.id != Token::Type::ID &&
2408 context_.id != Token::Type::ID_STRING && context_.id != Token::Type::DEL_EQ) {
2409 break;
2410 }
2411
2412 if (!ParseMetaListComma(comma, eq)) {
2413 return false;
2414 }
2415
2416 if (!MeetExpMetaList(eq)) {
2417 return false;
2418 }
2419
2420 if (!BuildMetaListAttr(eq, attribute_name, attribute_value)) {
2421 return false;
2422 }
2423 }
2424
2425 if (flag && *context_ != Token::Type::DEL_GT) {
2426 context_.err = GetError("Expected '>'.", Error::ErrorType::ERR_BAD_METADATA_BOUND);
2427 ++context_;
2428
2429 return false;
2430 }
2431
2432 auto res = metadata_->ValidateData();
2433 if (res) {
2434 auto err = res.value();
2435 SetMetadataContextError(err, false);
2436 return false;
2437 }
2438
2439 return true;
2440 }
2441
ParseFunctionInstruction()2442 bool Parser::ParseFunctionInstruction()
2443 {
2444 if (ParseLabel()) {
2445 if (ParseOperation()) {
2446 if (ParseOperands()) {
2447 return true;
2448 }
2449 }
2450 }
2451
2452 return context_.Mask();
2453 }
2454
2455 } // namespace panda::pandasm
2456