NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
macro.cpp
Go to the documentation of this file.
1//#include "pch.h"
2
3#include "lexer.h"
4#include "builtin.h"
5
6#include "macro.h"
7#include "parser.h"
8
9using namespace newlang;
10
11const std::string Macro::deny_chars_from_macro(";@:&^#?!{}+-%*~`\"',/|\\()[]<>");
12
15
16std::string Macro::toMacroHash(TermPtr &term) {
17 if (term->isMacro()) {
18 ASSERT(!GetMacroId(term).empty());
19 return toMacroHashName(GetMacroId(term)[0]->m_text);
20 }
21 return toMacroHashName(term->m_text);
22}
23
24// replase
25
27
28 if (!parser.m_macro && parser.m_diag) {
29 parser.m_diag->Emit(Diag::DIAG_MACRO_NOT_FOUND, term);
30 return term;
31 }
32
33 if (term->m_bracket_depth) {
34 NL_PARSER(term, "Macro definitions allowed at the top level only, not inside conditions, namespace or any brackets!");
35 }
36
37 if (parser.m_macro) {
38 return parser.m_macro->EvalOpMacros(term);
39 }
40 return term;
41}
42
43// replase
44
46
47 size_t counter = 0;
48 if (parser.m_macro) {
49
50 // Макрос должне начинаться всегда с термина
51 if (!(parser.m_macro_analisys_buff[0]->getTermID() == TermID::MACRO || parser.m_macro_analisys_buff[0]->getTermID() == TermID::NAME)) {
53 }
54
55 TermPtr macro_done = nullptr;
56
57 // Итератор для списка макросов, один из которых может соответствовать текущему буферу (по первому термину буфера)
58 Macro::iterator found = parser.m_macro->map::find(Macro::toMacroHash(parser.m_macro_analisys_buff[0]));
59
60 if (found == parser.m_macro->end()) {
61
62 // // Если макрос не найден - ошибка
63 // if(isMacro(parser.m_macro_analisys_buff[0]->parser.m_text)) {
64 // LOG_RUNTIME("Macro '%s' not found!", parser.m_macro_analisys_buff[0]->toString().c_str());
65 // }
66
68 }
69
70 macro_done.reset();
71 // Перебрать все макросы и сравнить с буфером
72 for (auto iter = found->second.begin(); iter != found->second.end(); ++iter) {
73
75
76 if (macro_done) {
77 LOG_RUNTIME("Macro duplication %s and '%s'!", macro_done->toString().c_str(), (*iter)->toString().c_str());
78 }
79 macro_done = *iter;
80 }
81 }
82
83 ASSERT(found != parser.m_macro->end());
84
85 if (macro_done) {
86
87 counter++;
88 if (counter > 100) {
89 LOG_RUNTIME("Macro expansion '%s' stack overflow?", macro_done->toString().c_str());
90 }
91
92 // compare_macro = true; // Раскрывать макросы в теле раскрытого макроса
93
94 ASSERT(parser.m_macro_analisys_buff.size() >= macro_done->m_macro_seq.size());
95 ASSERT(macro_done->m_right);
96
97 Macro::MacroArgsType macro_args;
98 size_t size_remove = Macro::ExtractArgs(parser.m_macro_analisys_buff, macro_done, macro_args);
99
100 // LOG_TEST_DUMP("buffer '%s' DumpArgs: %s", Macro::Dump(parser.m_macro_analisys_buff).c_str(), Macro::Dump(macro_args).c_str());
101
102
103 ASSERT(size_remove);
104 ASSERT(size_remove <= parser.m_macro_analisys_buff.size());
105
106 std::string temp = "";
107 for (auto &elem : parser.m_macro_analisys_buff) {
108 if (!temp.empty()) {
109 temp += " ";
110 }
111 temp += elem->m_text;
112 temp += ":";
113 temp += toString(elem->m_id);
114 }
115 // LOG_TEST("From: %s (remove %d)", temp.c_str(), (int) size_remove);
116
117 parser.m_macro_analisys_buff.erase(parser.m_macro_analisys_buff.begin(), parser.m_macro_analisys_buff.begin() + size_remove);
118
119 if (macro_done->m_right->getTermID() == TermID::MACRO_STR) {
120
121 std::string macro_str = Macro::ExpandString(macro_done, macro_args);
122 parser.lexer->source_string = std::make_shared<std::string>(Macro::ExpandString(macro_done, macro_args));
123 parser.lexer->m_macro_iss = new std::istringstream(*parser.lexer->source_string);
124 parser.lexer->m_macro_loc = *parser.lexer->m_loc; // save
125 parser.lexer->m_loc->initialize();
126 parser.lexer->yypush_buffer_state(parser.lexer->yy_create_buffer(parser.lexer->m_macro_iss, parser.lexer->source_string->size()));
127
128 // if(lexer->parser.m_data.size() > 100) {
129 // LOG_RUNTIME("Macro expansion '%s' stack overflow?", macro_done->toString().c_str());
130 // }
131 //
132 // std::string macro_str = MacroBuffer::ExpandString(macro_done, macro_args);
133 // lexer->source_string = std::make_shared<std::string>(MacroBuffer::ExpandString(macro_done, macro_args));
134 // lexer->parser.m_data.push_back({lexer->source_string, new std::istringstream(*lexer->source_string), *lexer->parser.m_loc});
135 // lexer->parser.m_loc->initialize();
136 // lexer->yypush_buffer_state(lexer->yy_create_buffer(lexer->parser.m_data[lexer->parser.m_data.size() - 1].iss, lexer->source_string->size()));
137
138 parser.m_is_lexer_complete = false;
139
141 // goto go_parse_string;
142
143 } else {
144
145 ASSERT(macro_done->m_right);
146 BlockType macro_block = Macro::ExpandMacros(macro_done, macro_args);
147 parser.m_macro_analisys_buff.insert(parser.m_macro_analisys_buff.begin(), macro_block.begin(), macro_block.end());
148
149 std::string temp = "";
150 for (auto &elem : parser.m_macro_analisys_buff) {
151 if (!temp.empty()) {
152 temp += " ";
153 }
154 temp += elem->m_text;
155 temp += ":";
156 temp += toString(elem->m_id);
157 }
158 // LOG_TEST("To: %s", temp.c_str());
159 }
160
162
163 } else {
164 // if(parser.m_macro_analisys_buff[0]->getTermID() == TermID::MACRO) { // || found != parser.m_macro->end()
165
166 LOG_RUNTIME("Macro mapping '%s' not found!\nThe following macro mapping are available:\n%s",
167 parser.m_macro_analisys_buff[0]->toString().c_str(),
168 parser.m_macro->GetMacroMaping(Macro::toMacroHash(parser.m_macro_analisys_buff[0]), "\n").c_str());
169
170 // }
171 }
172 }
174}
175
177
179 size_t pos = 0;
180 TermPtr term;
181 size_t done;
182
183 while (pos < seq.size()) {
184
185 if (Macro::deny_chars_from_macro.find(seq[pos]->m_text[0]) != std::string::npos) {
186 NL_PARSER(seq[pos], "Symbol '%c' in lexem sequence not allowed!", seq[pos]->m_text[0]);
187 }
188
189 done = Parser::ParseTerm(term, seq, pos);
190 if (done) {
191 result.push_back(term);
192 pos = done;
193 } else {
194 LOG_RUNTIME("Fail convert %s", seq[pos]->toString().c_str());
195 }
196 }
197 // std::vector<std::string> result;
198 // for (auto &elem : m_macro_id) {
199 // result.push_back(MacroBuffer::toHashTermName(elem->m_text));
200 // }
201 return result;
202}
203
205 if (!term->isMacro()) {
206 LOG_RUNTIME("Term '%s' as %s not a macro!", term->toString().c_str(), newlang::toString(term->m_id));
207 }
208
209 if (term->m_macro_id.empty()) {
210
211 if (term->m_id == TermID::MACRO_DEL) {
212 ASSERT(term->m_macro_seq.size());
213
214 term->m_macro_id = MakeMacroId(term->m_macro_seq);
215
216 } else {
217 ASSERT(term->isCreate());
218 ASSERT(term->m_left);
219 ASSERT(term->m_left->m_id == TermID::MACRO_SEQ);
220 ASSERT(term->m_left->m_macro_seq.size());
221
222 term->m_macro_id = MakeMacroId(term->m_left->m_macro_seq);
223 term->m_left->m_macro_id = term->m_macro_id;
224 }
225
226 ASSERT(term->m_macro_id.size());
227 }
228 return term->m_macro_id;
229}
230
231
232//void Macro::Push(const TermPtr term) {
233// // ASSERT(!m_diag_stack.empty());
234// // m_diag_stack.push_back(m_diag_stack[m_diag_stack.size() - 1]);
235//}
236//
237//void Macro::Pop(const TermPtr term) {
238// // if(m_diag_stack.empty()) {
239// // if(term) {
240// // NL_PARSER(term, "Empty stack diags at '%s'!", term->toString().c_str());
241// // } else {
242// // LOG_RUNTIME("Empty stack diags!");
243// // }
244// // }
245// // m_diag_stack.pop_back();
246//}
247
248std::string Macro::GetMacroMaping(const std::string str, const char *separator) {
249
250 std::string result;
251
252 // Итератор для списка макросов, один из которых может соответствовать текущему буферу (по первому термину буфера)
253 iterator found = this->map::find(str);
254
255 for (auto iter = found->second.begin(); found != end() && iter != found->second.end(); ++iter) {
256
257 if (!result.empty() && separator) {
258 result += separator;
259 }
260
261 result += (*iter)->toString();
262 }
263 return result;
264}
265
266bool Macro::CheckMacro(const TermPtr & term) {
267 if (!term) {
268 ASSERT(term);
269 }
270 ASSERT(term->m_left);
271 ASSERT(term->m_right);
272
273
274 if (term->isPure()) {
275 NL_PARSER(term, "Hygienic macros are not implemented!");
276 }
277
278 TermPtr op_term;
279 bool is_operator = false;
280 TermPtr args; // Arguments @macro(name)
281 std::set<std::string> tmpl; // Templates $name
282
283 ASSERT(!term->m_left->m_macro_seq.empty());
284 for (auto &elem : MakeMacroId(term->m_left->m_macro_seq)) {
285 if (elem->isCall()) {
286 if (args) {
287 NL_PARSER(elem, "Only one term in a macro can have arguments");
288 }
289 args = elem;
290 } else if (isLocalName(elem->m_text)) {
291 if (tmpl.find(elem->m_text) != tmpl.end()) {
292 NL_PARSER(elem, "Reuse of argument name!");
293 }
294 if (elem->m_text.compare("$...") == 0) {
295 if (is_operator) {
296 NL_PARSER(elem, "Statement pattern should be only one!");
297 }
298 op_term = elem;
299 is_operator = true;
300 }
301 tmpl.insert(elem->m_text);
302 } else if (elem->m_id == TermID::NAME) {
303 if (isReservedName(elem->m_text)) {
304 NL_PARSER(elem, "Reserved term name used!");
305 }
306 // OK
307 } else {
308 NL_PARSER(elem, "Unexpected term in macro!");
309 }
310 }
311
312 if (is_operator) {
313 if (term->m_left->m_macro_seq.back()->m_text.compare("$...") != 0) {
314 NL_PARSER(op_term, "Statement pattern must be the last term!");
315 }
316 if (args) {
317 NL_PARSER(args, "The statement macro cannot be a function call!");
318 }
319 }
320
321 std::set<std::string> args_name;
322
323 int arg_count = args ? args->size() : 0; // +1 to self object
324 bool named = false;
325 bool is_ellips = false;
326 for (int i = 0; args && i < args->size(); i++) {
327 if (!args->at(i).first.empty()) {
328 named = true;
329 if (args_name.find(args->at(i).first) != args_name.end()) {
330 NL_PARSER(args->at(i).second, "Reuse of argument name!");
331 }
332 args_name.insert(args->at(i).first);
333 } else {
334 if (args->at(i).second->m_id == TermID::ELLIPSIS) {
335 if (i + 1 != args->size()) {
336 NL_PARSER(args->at(i).second, "The ellipsis can only be the last in the list of arguments!");
337 }
338 arg_count--;
339 is_ellips = true;
340 break;
341 }
342 if (named) {
343 NL_PARSER(args->at(i).second, "Positional arguments must come before named arguments!");
344 }
345 }
346 if (args_name.find(args->at(i).second->m_text) != args_name.end()) {
347 NL_PARSER(args->at(i).second, "Reuse of argument name!");
348 }
349 args_name.insert(args->at(i).second->m_text);
350 }
351
352
353 if (term->m_right->getTermID() == TermID::MACRO_SEQ) {
354
355
356 //"@$"{name} YY_TOKEN(MACRO_ARGNAME);
357
358 //"@$..." YY_TOKEN(MACRO_ARGUMENT);
359 //"@$*" YY_TOKEN(MACRO_ARGUMENT); - All OK
360
361 //"@$"[0-9]+ YY_TOKEN(MACRO_ARGNUM);
362 //"@$#" YY_TOKEN(MACRO_ARGCOUNT); - All OK
363
364 for (auto &elem : term->m_right->m_macro_seq) {
365 if (elem->m_id == TermID::MACRO_ARGUMENT && elem->m_text.compare("@$...") == 0) {
366 if (!is_ellips && !is_operator) {
367 NL_PARSER(elem, "The macro has a fixed number of arguments, ellipsis cannot be used!");
368 }
369 } else if (elem->m_id == TermID::MACRO_ARGPOS) {
370 int64_t num = parseInteger(elem->m_text.substr(2).c_str());
371 if (num >= arg_count) {
372 NL_PARSER(elem, "Invalid argument number!");
373 }
374 } else if (elem->m_id == TermID::MACRO_ARGNAME) {
375 if (args_name.find(elem->m_text.substr(2)) == args_name.end() && tmpl.find(elem->m_text.substr(1)) == tmpl.end()) {
376 NL_PARSER(elem, "Macro argument name not found!");
377 }
378 // } else if (isLocalName(elem->m_text)) {
379 // if (args_name.find(elem->m_text.substr(1)) == args_name.end()) {
380 // NL_PARSER(elem, "Local name without macro prefix!");
381 // }
382 }
383 }
384 }
385
386 return true;
387
388}
389
391
392 ASSERT(term);
393
394 if (term->getTermID() == TermID::MACRO_DEL) {
395 if (!RemoveMacro(term)) {
396 LOG_WARNING("Macro '%s' not found!", toMacroHash(term).c_str());
397 }
398 return term;
399 }
400
401 if (!term->m_left) {
402 ASSERT(term->m_left);
403 }
404 if (term->m_left->getTermID() != TermID::MACRO_SEQ) {
405 NL_PARSER(term, "Operand '%s' not a macros!", term->m_left->toString().c_str());
406 }
407
408 if (term->m_right->getTermID() == TermID::MACRO_DEL || term->m_right->getTermID() == TermID::END) {
409 NL_PARSER(term, "For remove macro use operator @@@@ %s @@@@;)", term->m_left->m_text.c_str());
410 }
411
412 CheckMacro(term);
413
414
415 TermPtr macro = GetMacroById(GetMacroId(term));
416
417 if (macro) {
418
419 if (term->getTermID() == TermID::CREATE_NEW || term->getTermID() == TermID::PURE_NEW) {
420 NL_PARSER(term, "Macros '%s' already exists!", term->m_left->toString().c_str());
421 }
422
423 // Итератор для списка макросов, один из которых может соответствовать текущему буферу (по первому термину буфера)
424 Macro::iterator found = map::find(toMacroHash(term));
425 for (auto iter = found->second.begin(); found != end() && iter != found->second.end(); ++iter) {
426 if (Macro::IdentityMacro(GetMacroId(term), *iter) || Macro::IdentityMacro(GetMacroId(*iter), term)) {
427
428 if (term->getTermID() == TermID::CREATE_NEW || term->getTermID() == TermID::PURE_NEW || (iter->get() != macro.get())) {
429 LOG_RUNTIME("Macro duplication '%s' and '%s'!", term->m_left->toString().c_str(), (*iter)->toString().c_str());
430 }
431 }
432 }
433
434 macro->m_right = term->m_right;
435
436 } else {
437
438 if (term->getTermID() == TermID::ASSIGN) {
439 NL_PARSER(term, "Macros '%s' not exists!", term->m_left->toString().c_str());
440 }
441
442 TermPtr temp = term->m_left;
443 // Итератор для списка макросов, один из которых может соответствовать текущему буферу (по первому термину буфера)
444 Macro::iterator found = map::find(toMacroHash(temp));
445 for (auto iter = found->second.begin(); found != end() && iter != found->second.end(); ++iter) {
446 TermPtr temp2 = *iter;
447 if (Macro::IdentityMacro(GetMacroId(term), *iter) || Macro::IdentityMacro(GetMacroId(temp2), term)) {
448 LOG_RUNTIME("Macro duplication '%s' and '%s'!", term->m_left->toString().c_str(), (*iter)->toString().c_str());
449 }
450 }
451
452
453 //@todo Сделать два типа макросов, явные и не явные (::- :- или ::= :=), что позволит
454 // контролировать обязательность указания признака макроса @ для явных макросов,
455 // а не явные применять всегда (как сейчас)
456
457
458 macro = term;
459
460 iterator iter = map::find(toMacroHash(macro));
461 if (iter == end()) {
462 insert(std::make_pair<std::string, BlockType>(toMacroHash(macro),{macro}));
463 } else {
464 iter->second.push_back(macro);
465 }
466 }
467
468
469 return macro;
470}
471
473
474 BlockType list = GetMacroId(term);
475 ASSERT(!list.empty());
476
477
478 if (term->m_id == TermID::MACRO_DEL && list.size() == 1 && list[0]->m_text.compare("_") == 0) {
479 clear();
480 return true;
481 }
482
483 iterator found = map::find(toMacroHash(term));
484
485 if (found != end()) {
486 for (BlockType::iterator iter = found->second.begin(); iter != found->second.end(); ++iter) {
487
488 BlockType names = GetMacroId(*iter);
489
490 // for (auto &elem : names) {
491 // LOG_DEBUG("%s ", elem.c_str());
492 // }
493
494
495 if (names.size() != list.size()) {
496 continue;
497 }
498
499 for (int pos = 0; pos < list.size(); pos++) {
500 if (!CompareMacroName(list[pos]->m_text.c_str(), names[pos]->m_text.c_str())) {
501 goto skip_remove;
502 }
503 }
504
505 found->second.erase(iter);
506
507 if (found->second.empty()) {
508
509 erase(list[0]->m_text.c_str());
510 }
511
512 return true;
513
514skip_remove:
515 ;
516 }
517 }
518 return false;
519}
520
521std::string Macro::Dump() {
522 std::string result;
523 auto iter = begin();
524 while (iter != end()) {
525 if (!result.empty()) {
526 result += ", ";
527 }
528
529 for (int pos = 0; pos < iter->second.size(); pos++) {
530
531 std::string str;
532 for (auto &elem : iter->second[pos]->m_macro_id) {
533 if (!str.empty()) {
534 str += " ";
535 }
536 str += elem->m_text;
537 if (iter->second[pos]->isCall()) {
538 str += "(";
539 }
540 }
541 result += iter->first + "->'" + str + "'";
542 if (pos + 1 < iter->second.size()) {
543
544 result += "; ";
545 }
546 }
547
548 iter++;
549 }
550 return result;
551}
552
553std::string Macro::Dump(const MacroArgsType & var) {
554 std::string result;
555 auto iter = var.begin();
556 while (iter != var.end()) {
557 if (!result.empty()) {
558 result += ", ";
559 }
560
561 std::string str;
562 for (int pos = 0; pos < iter->second.size(); pos++) {
563 if (!str.empty()) {
564
565 str += " ";
566 }
567 str += iter->second[pos]->toString();
568 }
569
570 result += iter->first + "->'" + str + "'";
571 iter++;
572 }
573 return result;
574}
575
576std::string Macro::Dump(const BlockType & arr) {
577 std::string result;
578 auto iter = arr.begin();
579 while (iter != arr.end()) {
580 if (!result.empty()) {
581
582 result += " ";
583 }
584 result += (*iter)->toString();
585 iter++;
586 }
587 return result;
588}
589
590std::string Macro::DumpText(const BlockType & arr) {
591 std::string result;
592 auto iter = arr.begin();
593 while (iter != arr.end()) {
594 if (!result.empty()) {
595
596 result += " ";
597 }
598 result += (*iter)->m_text;
599 iter++;
600 }
601 return result;
602}
603
604bool Macro::CompareMacroName(const std::string & term_name, const std::string & macro_name) {
605 // LOG_DEBUG("%s == %s", term_name.c_str(), macro_name.c_str());
606 if (isLocalName(macro_name)) {
607 // Шаблон соответствует любому термину входного буфера
608 return true;
609 }
610 if (isMacroName(term_name)) {
611 // Если термин в буфере - имя макроса
612 if (isMacroName(macro_name)) {
613 return macro_name.compare(term_name) == 0;
614 }
615 // Префикс макроса не учавтствует в сравнении
616 return macro_name.compare(&term_name.c_str()[1]) == 0;
617
618 } else if (isMacroName(macro_name)) {
619 // Если термин в буфере - имя макроса
620 if (isMacroName(term_name)) {
621 return macro_name.compare(term_name) == 0;
622 }
623 // Префикс макроса не учавтствует в сравнении
624 return term_name.compare(&macro_name.c_str()[1]) == 0;
625
626 } else if (isLocalAnyName(term_name.c_str())) {
627 // Любой другой термин не подходит
628
629 return false;
630 }
631 // Без префиксов оба термина
632 return term_name.compare(macro_name) == 0;
633}
634
635/*
636 * < first second >
637 * first != first second
638 * first second == first second
639 * first second ( ) == first second
640 *
641 * < first second ( ) >
642 * first != first second ( )
643 * first second != first second ( ) <- Exception
644 * first second ( ) == first second ( )
645 *
646 * func name()
647 * virtual func name()
648 * override func name()
649 * final func name()
650 *
651 * override virtual func name()
652 * virtual override func name()
653 * override final func name()
654 * virtual final func name()
655 * final override virtual func name()
656 * final virtual override func name()
657 *
658 *
659 * * func name()
660 * virtual func name()
661 * override func name()
662 * final func name()
663 *
664 *
665 * Классификация аннотаций Java
666 * Аннотации можно классифицировать по количеству передаваемых в них параметров: без параметров, с одним параметром и с несколькими параметрами.
667 * Маркерные аннотации - Маркерные аннотации не содержат никаких членов или данных. Для определения наличия аннотации можно использовать метод isAnnotationPresent().
668 * Аннотации с одним значением содержат только один атрибут, который принято называть value.
669 * Полные аннотации (из нескольких пар "имя-значение". Например, Company(name = "ABC", city = "XYZ"). )
670 *
671 * Аннотации в NewLang всегда сожержат только один атрибут, маркертные имитируются установкой значения 1,
672 * а полные аннотации не поддериватся (по крайнемй мера пока)
673 *
674 * Прагмы обработываются и доступны только во время компиляции,
675 * а Аннотации доступна и во время компиляции и во время выполнения в виде системых?????? свойств объектов.
676 *
677 * Прагмы применяются для всего текущего окружения (экземпляра компилятора),
678 * а аннотации только к одному создаваемому объекту (к следующей операции создания объекта/присвоения значения);
679 *
680 *
681 * @@ override @@ := @@ @__ANNOTATION_SET__(override, 1) @__PRAGMA_UNEXPECTED__( (, <, [, {, {+, {-, {*) @@
682 * @@ nothrow @@ := @@ @__ANNOTATION_SET__(nothrow, 1) @__PRAGMA_UNEXPECTED__( (, <, [, {, {+, {-, {*) @@
683 * @@ func $name (...) @@ := @@ @$name ( @$* ) @__ANNOTATION_IIF__(override, =, ::=)
684 * @__ANNOTATION_IF_EXPECTED__(nothrow, {*)
685 * @__ANNOTATION_ELSE_EXPECTED__(nothrow, {, {+, {-, {*) @@
686 *
687 * @@ __name__ @@ ::= @@ . @__PRAGMA_NO_MACRO__() __name__ @@ # -> \.__name__
688 *
689 * @__PRAGMA_INDENT_BLOCK__( +} )
690 *
691 *
692 * func name() { # -> name() ::= {
693 * };
694 *
695 * @override
696 * func name() { # -> name() = {
697 * };
698 *
699 * @override
700 * \\nothrow
701 * func name() { # -> name() = {*
702 * *};
703 *
704 *
705 *
706 *
707 * @@ property(name, value) @@ := @@ @__ANNOTATION_SET__(@$name, @$value) @@
708 *
709 * @property(name, "ABC")
710 * @property(city, "XYZ")
711 *
712 * @override -> @__ANNOTATION_SET__(override, 1)
713 * @virtual -> @__ANNOTATION_SET__(virtual, 1) @__PRAGMA_PROP_SET__(virtual)
714 * @final -> @__ANNOTATION_SET__(final, 1) @__PRAGMA_PROP_SET__(final)
715 * @const -> @__ANNOTATION_SET__(const, 1) @__PRAGMA_PROP_SET__(const)
716 * @data(1,2,3) -> @__ANNOTATION_SET__(data, 1,2,3)
717 * @data([1,2,3,]) -> @__ANNOTATION_SET__(data, [1,2,3,])
718 * @data((1,2,3,)) -> @__ANNOTATION_SET__(data, (1,2,3,))
719 *
720 * @Company( name="ABC", city="XYZ" ) -> name="ABC"; city="XYZ";
721 *
722 * func name()
723 *
724 * @__ANNOTATION_IIF__()
725 * @__PRAGMA_PROP_CHECK__(override, = , ::=)
726 * @__PRAGMA_PROP_CHECK__(const, ^)
727 * @__PRAGMA_PROP_TEST__(const, ^)
728 * @__PRAGMA_PROP_TEST__(const, ^)
729 *
730 *
731 * Запускать тесты
732 * Определять тесты
733 * Выполнять утверждения в тестах
734 * @Test("Group", "Name", timeout = 100) {
735 *
736 * };
737 *
738 * @@ TEST_FATAL @@ ::= 1;
739 * @@ TEST_NOT_FATAL @@ ::= 0;
740 *
741 * @@ TEST (...) @@ ::= @@ @__PRAGMA_TEST__(@$*)__; @__PRAGMA_EXPECTED__( { ) @@
742 *
743 * @@ ASSERT_TRUE ( exp ) @@ ::= @@ @__PRAGMA_TEST_BOOL__(@$exp, @# @$exp, @TEST_FATAL, @__FILE_NAME__, @__FILE_LINE__) @@
744 * @@ EXPECT_TRUE ( exp ) @@ ::= @@ @__PRAGMA_TEST_BOOL__(@$exp, @# @$exp, @TEST_NOT_FATAL, @__FILE_NAME__, @__FILE_LINE__) @@
745 * @@ ASSERT_FALSE ( exp ) @@ ::= @@ @__PRAGMA_TEST_BOOL__(! @$exp, @# @$exp, @TEST_FATAL, @__FILE_NAME__, @__FILE_LINE__) @@
746 * @@ EXPECT_FALSE ( exp ) @@ ::= @@ @__PRAGMA_TEST_BOOL__(! @$exp, @# @$exp, @TEST_NOT_FATAL, @__FILE_NAME__, @__FILE_LINE__) @@
747 *
748 * @@@@ TEST_FATAL @@@@;
749 * @@@@ TEST_NOT_FATAL @@@@;
750 *
751 *
752 */
753bool Macro::IdentityMacro(const BlockType &buffer, TermPtr & macro) {
754
755 if (!macro || !macro->isMacro()) {// || buffer.size() < macro->m_macro_id.size()) {
756 return false;
757 }
758
759
760 int buff_offset = 0;
761 int macro_offset = 0;
762 while (buff_offset < buffer.size() && macro_offset < GetMacroId(macro).size()) {
763
764 if (buffer[buff_offset]->getTermID() == TermID::END) {
765 return false;
766 }
767
768 // LOG_DEBUG("TermID: %s, '%s' '%s'", toString(buffer[buff_offset]->getTermID()),
769 // buffer[buff_offset]->m_text.c_str(), macro->m_macro_id[macro_offset]->m_text.c_str());
770 // Текст термина сравнивается только для опредленных терминов
771 if (!CompareMacroName(buffer[buff_offset]->m_text, GetMacroId(macro)[macro_offset]->m_text)) {
772 return false;
773 } else {
774
775 buff_offset++;
776
777 if (GetMacroId(macro)[macro_offset]->isCall()) {
778 // Пропускаем скобки и все что находится между ними
779 size_t skip = Parser::SkipBrackets(buffer, buff_offset);
780 if (!skip) {
781 return false;
782 }
783 buff_offset += skip;
784
785 }
786 }
787
788 macro_offset++;
789
790 if (macro_offset == GetMacroId(macro).size()) {
791 // LOG_DEBUG("Macro '%s' done for %d lexem!", macro->toString().c_str(), buff_offset);
792
793 return true;
794 }
795
796 // buff_offset++;
797 }
798 // Нужен следующий термин для сопоставления
799 return false;
800}
801
802void Macro::InsertArg_(MacroArgsType & args, std::string name, BlockType & buffer, size_t pos) {
803
804 if (args.find(name) != args.end()) {
805 LOG_RUNTIME("Duplicate arg %s!", name.c_str());
806 }
807
808 BlockType vect;
809 if (pos == static_cast<size_t> (-1)) {
810 for (auto &elem : buffer) {
811 vect.push_back(elem->Clone());
812 }
813 } else {
814 if (pos >= buffer.size()) {
815
816 LOG_RUNTIME("No data for input buffer! Pos %d for size %d!", (int) pos, (int) buffer.size());
817 }
818 vect.push_back(buffer[pos]->Clone());
819 }
820 args.insert(std::make_pair(name, vect));
821}
822
823BlockType Macro::SymbolSeparateArg_(const BlockType &buffer, size_t pos, std::vector<std::string> sym, std::string & error) {
824 error.clear();
826 size_t skip;
827 while (pos < buffer.size()) {
828 if (buffer[pos]->getTermID() == TermID::SYMBOL) {
829 for (auto &elem : sym) {
830 if (buffer[pos]->m_text.compare(elem) == 0) {
831 return result;
832 }
833 }
834
835 }
836
837 skip = Parser::SkipBrackets(buffer, pos);
838 for (int i = 0; skip && i < skip - 1; i++) {
839 result.push_back(buffer[pos]->Clone());
840 pos++;
841 }
842
843 result.push_back(buffer[pos]->Clone());
844 pos++;
845 }
846
847 for (auto &elem : sym) {
848 if (!error.empty()) {
849 error += " or ";
850 }
851 error += "'";
852 error += elem;
853 error += "'";
854 }
855
856 error.insert(0, "Expected symbol ");
857 error += "!";
858
859 return result;
860}
861
862size_t Macro::ExtractArgs(BlockType &buffer, TermPtr &term, MacroArgsType & args) {
863
864 ASSERT(term);
865
866 if (!term->isMacro()) { //((term->getTermID() == TermID::MACRO_SEQ || term->getTermID() == TermID::MACRO_STR || term->getTermID() == TermID::MACRO_DEL))) {
867 LOG_RUNTIME("Term is not a macro! '%s'", term->toString().c_str());
868 }
869
870 args.clear();
871
872 size_t pos_buf = 0; //Позиция во входном буфере
873 int pos_id = 0; // Позиция в идентификаторе макроса
874
875 std::string arg_name; // Имя аргумента
876 BlockType args_dict; // Последовательность терминов для @$*
877 BlockType args_exta; // Последовательность терминов для @$...
878
879 size_t arg_count = 0; // Кол-во аругментов
880 size_t arg_offset = 0; // Позиция аргумента во входном буфере
881
882 bool arg_ellipsys = false;
883 bool all_args_done = false; // Маркер анализа аргументов (могту быть только у одного термина)
884
885 // Перебор идентификатора макроса
886 while (pos_id < GetMacroId(term).size()) {
887
888
889 if (GetMacroId(term)[pos_id]->m_text.compare("$...") == 0) {
890
891 size_t stmt_start = pos_buf;
892 for (int i = pos_buf; i < buffer.size(); i++) {
893 if (buffer[pos_buf]->getTermID() == TermID::END || buffer[pos_buf]->m_text.compare(";") == 0) {
894 break;
895 }
896 pos_buf++;
897 }
898
899 // Шаблон оператора - все до конца входных данных
900 args_exta.insert(args_exta.end(), buffer.begin() + stmt_start, buffer.begin() + pos_buf);
901 pos_id = GetMacroId(term).size();
902 break;
903
904 } else if (isLocalName(GetMacroId(term)[pos_id]->m_text)) {
905
906 // Имя локальной переменной в идентификаторе макроса - это шаблон для замещения при его последующем раскрытии тела макроса
907 InsertArg_(args, GetMacroId(term)[pos_id]->m_text, buffer, pos_buf);
908
909 // Для термина с аргументами
910 } else if (GetMacroId(term)[pos_id]->isCall()) {
911
912 // Аругменты поддерживаются только у одного термина
913 if (all_args_done) {
914 LOG_RUNTIME("Support single term call only!");
915 }
916 all_args_done = true;
917
918
919 // Пропустить открывающую скобку
920 pos_buf++;
921 if (pos_buf >= buffer.size() || buffer[pos_buf]->getTermID() != TermID::SYMBOL || buffer[pos_buf]->m_text.compare("(") != 0) {
922 LOG_RUNTIME("Expected '('!");
923 }
924 pos_buf++;
925
926 std::string error_str;
927 BlockType arg_seq;
928 while (1) {
929 // Последовательность терминов в качестве аргумента, включая вложенные скобки
930 arg_seq = SymbolSeparateArg_(buffer, pos_buf,{")", ","}, error_str);
931
932 if (!error_str.empty()) {
933 LOG_RUNTIME("%s", error_str.c_str());
934 }
935
936 if (!arg_seq.empty()) {
937
938 args_dict.insert(args_dict.end(), arg_seq.begin(), arg_seq.end());
939
940 pos_buf += arg_seq.size();
941
942 ASSERT(pos_buf < buffer.size());
943
944 arg_count++;
945
946 // Порядковый номер аргумента @$1, @$2 и т.д.
947 arg_name = "@$";
948 arg_name += std::to_string(arg_count);
949 InsertArg_(args, arg_name, arg_seq);
950
951 if (arg_count - 1 < GetMacroId(term)[pos_id]->size()) {
952
953 // Именованные аругменты из прототипа макроса
954 arg_name = GetMacroId(term)[pos_id]->at(arg_count - 1).second->m_text;
955
956 if (arg_name.compare("...") == 0) {
957
958 if (arg_ellipsys) {
959 NL_PARSER(arg_seq[0], "Fail ellipsys args in prototype '%s'!", GetMacroId(term)[pos_id]->toString().c_str());
960 }
961 arg_ellipsys = true;
962
963 } else {
964
965 // if(arg_name.find("$") == 0) {
966 // arg_name.insert(0, "@");
967 // } else {
968 arg_name.insert(0, "@$");
969 // }
970 InsertArg_(args, arg_name, arg_seq);
971 }
972
973 } else {
974 // @todo Сделать проверку аргументов у маркосов
975 // if(!arg_ellipsys) {
976 // NL_PARSER(buffer[pos + arg_offset - 1], "Extra args for prototype '%s'!", term->GetMacroId()[i]->toString().c_str());
977 // }
978 }
979
980 if (arg_ellipsys) {
981 if (!args_exta.empty()) {
982 args_exta.insert(args_exta.end(), Term::CreateSymbol(','));
983 }
984 args_exta.insert(args_exta.end(), arg_seq.begin(), arg_seq.end());
985 }
986
987 } else if (buffer[pos_buf]->m_text == ",") {
988 args_dict.push_back(buffer[pos_buf]);
989 pos_buf++;
990 } else if (buffer[pos_buf]->m_text == ")") {
991 break;
992 } else {
993 LOG_RUNTIME("Unexpected symbol %s ?????????", buffer[pos_buf]->m_text.c_str());
994 }
995 }
996 }
997
998 pos_buf++;
999 pos_id++;
1000 }
1001
1002
1003
1004 BlockType cnt{Term::Create(TermID::INTEGER, std::to_string(arg_count).c_str(), parser::token_type::INTEGER)};
1005 arg_name = "@$#";
1006 InsertArg_(args, arg_name, cnt);
1007
1008 InsertArg_(args, "@$...", args_exta);
1009 // LOG_TEST_DUMP("args_exta: %s", Dump(args_exta).c_str());
1010
1011 // As dictionary
1012 args_dict.insert(args_dict.begin(), Term::CreateSymbol('('));
1013 args_dict.push_back(Term::CreateSymbol(','));
1014 args_dict.push_back(Term::CreateSymbol(')'));
1015 // LOG_TEST_DUMP("args_dict: %s", Dump(args_dict).c_str());
1016
1017 InsertArg_(args, "@$*", args_dict);
1018
1019 std::string ttt;
1020 for (size_t j = 0; j < GetMacroId(term).size(); j++) {
1021 if (j) {
1022 ttt += " ";
1023 }
1024 ttt += Macro::toMacroHashName(GetMacroId(term)[j]->m_text);
1025 }
1026 // LOG_DEBUG("m_macro_id: '%s' args: %s", ttt.c_str(), Dump(args).c_str());
1027
1028
1029 if (((pos_id == GetMacroId(term).size()) //term->getTermID() == TermID::MACRO
1030 || (term->getTermID() == TermID::MACRO_SEQ && pos_id == GetMacroId(term).size()))
1031 && pos_buf + arg_offset <= buffer.size()) {
1032 ASSERT(pos_buf + arg_offset <= buffer.size());
1033
1034 return pos_buf + arg_offset;
1035 }
1036
1037 NL_PARSER(buffer[0], "Input buffer empty for extract args macros %s (%d+%d)=%d!", term->toString().c_str(), (int) pos_buf, (int) arg_offset, (int) buffer.size());
1038}
1039
1041 ASSERT(macro);
1042 ASSERT(macro->m_right);
1043
1045
1046 BlockType seq = macro->m_right->m_macro_seq;
1047
1048 if (macro->m_right->getTermID() != TermID::MACRO_SEQ) {
1049 ASSERT(seq.empty());
1050 seq.push_back(macro->m_right);
1051 }
1052
1053 for (int i = 0; i < seq.size(); i++) {
1054
1055 if (seq[i]->getTermID() == TermID::MACRO_TOSTR) {
1056
1057 if (i + 1 >= seq.size()) {
1058 NL_PARSER(seq[i], "Next element to string not found!");
1059 }
1060 result.insert(result.end(), seq[i + 1]->Clone());
1061
1062 if ((*result.rbegin())->m_text.find("@$") == 0) {
1063 auto iter = args.find((*result.rbegin())->m_text);
1064 if (iter == args.end()) {
1065 LOG_RUNTIME("Argument name '%s' not found!", seq[i]->m_text.c_str());
1066 }
1067 std::string text;
1068 for (auto & elem : iter->second) {
1069 text += elem->m_text;
1070 }
1071 (*result.rbegin())->m_text = text;
1072 }
1073
1074 if (seq[i]->m_text.compare("@#\"") == 0) {
1075 (*result.rbegin())->m_id = TermID::STRWIDE;
1076 } else if (seq[i]->m_text.compare("@#'") == 0) {
1077 (*result.rbegin())->m_id = TermID::STRCHAR;
1078 } else {
1079 ASSERT(seq[i]->m_text.compare("@#") == 0);
1080 //@todo Set string type default by global settings
1081 (*result.rbegin())->m_id = TermID::STRWIDE;
1082 }
1083 i++;
1084
1085
1086 } else if (seq[i]->getTermID() == TermID::MACRO_CONCAT) {
1087 ASSERT(seq[i]->m_text.compare("@##") == 0);
1088
1089 if (result.empty() || i + 1 >= seq.size()) {
1090 NL_PARSER(seq[i], "Concat elements not exist!");
1091 }
1092 (*result.rbegin())->m_text.append(seq[i + 1]->m_text);
1093 i++;
1094
1095 } else if (seq[i]->m_text.find("@$") == 0) {
1096
1097 auto iter = args.find(seq[i]->m_text);
1098 if (iter == args.end()) {
1099 LOG_RUNTIME("Argument name '%s' not found!", seq[i]->m_text.c_str());
1100 }
1101
1102 if (seq[i]->m_text.compare("@$...") == 0) {
1103
1104 // Remove last comma if argument list is empty/
1105 if (iter->second.empty() && result.rbegin() != result.rend() && (*result.rbegin())->m_text.compare(",") == 0) {
1106 result.erase(std::prev(result.end()));
1107 }
1108 }
1109
1110 for (auto & elem : iter->second) {
1111 result.push_back(elem->Clone());
1112 }
1113
1114 } else {
1115
1116 result.insert(result.end(), seq[i]->Clone());
1117 }
1118 }
1119 return result;
1120}
1121
1122std::string ReplaceAll(std::string str, const std::string& from, const std::string & to) {
1123 size_t start_pos = 0;
1124 while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
1125
1126 str.replace(start_pos, from.length(), to);
1127 start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
1128 }
1129 return str;
1130}
1131
1132std::string Macro::ExpandString(const TermPtr &macro, MacroArgsType & args) {
1133 ASSERT(macro);
1134 ASSERT(macro->m_right);
1135 if (macro->m_right->m_id != TermID::MACRO_STR) {
1136 LOG_RUNTIME("Fail convert term type %s as macros string!", toString(macro->m_right->m_id));
1137 }
1138
1139 std::string body(macro->m_right->m_text);
1140
1141 for (auto &elem : args) {
1142
1143 std::string text;
1144 for (auto &lex : elem.second) {
1145
1146 text += lex->toString();
1147 text += " ";
1148 }
1149
1150 // LOG_DEBUG("Replace: '%s' -> '%s' in \"%s\"", elem.first.c_str(), text.c_str(), body.c_str());
1151 body = ReplaceAll(body, elem.first, text);
1152 }
1153
1154 return body;
1155}
1156
1158 std::vector<std::string> list;
1159 for (auto &elem : block) {
1160
1161 list.push_back(elem->m_text);
1162 }
1163 return GetMacro(list);
1164}
1165
1166TermPtr Macro::GetMacro(std::vector<std::string> list) {
1167 if (list.empty()) {
1168 return nullptr;
1169 }
1170 iterator found = map::find(toMacroHashName(list[0]));
1171
1172 if (found != end()) {
1173 for (BlockType::iterator iter = found->second.begin(); iter != found->second.end(); ++iter) {
1174
1175 BlockType names = GetMacroId(*iter);
1176
1177 // for (auto &elem : names) {
1178 // LOG_DEBUG("%s ", elem.c_str());
1179 // }
1180
1181
1182 if (names.size() != list.size()) {
1183 continue;
1184 }
1185
1186 for (int pos = 0; pos < list.size(); pos++) {
1187 if (!CompareMacroName(list[pos].c_str(), names[pos]->m_text.c_str())) {
1188
1189 goto skip_step;
1190 }
1191 }
1192 return *iter;
1193skip_step:
1194 ;
1195 }
1196 }
1197 return nullptr;
1198}
1199
1208//bool Named::RegisterTypeHierarchy(ObjType type, std::vector<std::string> parents) {
1209// // std::array < std::string, sizeof...(parents) > list = {parents...};
1210//
1211// std::string type_name(toString(type));
1212// auto base = m_types.find(type_name);
1213// if (base != m_types.end()) {
1214// return false;
1215// }
1216//
1217// ObjPtr result = Obj::CreateBaseType(type);
1218// ASSERT(result->m_var_type_fixed == type);
1219// ASSERT(result->m_var_type_current == ObjType::Type);
1220// ASSERT(!type_name.empty() && result->m_class_name.compare(type_name) == 0);
1221// ASSERT(result->m_class_parents.empty());
1222//
1223// for (auto &parent : parents) {
1224// auto iter = m_types.find(parent);
1225// if (iter == m_types.end()) {
1226// LOG_DEBUG("Parent type '%s' not found!", parent.c_str());
1227// return false;
1228// }
1229// for (auto &elem : result->m_class_parents) {
1230// ASSERT(elem);
1231// if (!elem->m_class_name.empty() && elem->m_class_name.compare(parent) == 0) {
1232// LOG_DEBUG("The type '%s' already exists in the parents of '%s'!", parent.c_str(), type_name.c_str());
1233// return false;
1234// }
1235// }
1236// ASSERT(iter->first.compare(parent) == 0);
1237// result->m_class_parents.push_back(iter->second);
1238// }
1239// m_types[type_name] = result;
1240// return true;
1241//}
1242//
1243//ObjType Named::BaseTypeFromString(const std::string & type, bool *has_error = nullptr) {
1244// ObjPtr obj_type = GetTypeFromString(type, has_error);
1245//
1246// if (obj_type == nullptr) {
1247// if (has_error) {
1248// *has_error = true;
1249// return ObjType::None;
1250// }
1251// LOG_RUNTIME("Type name '%s' not found!", type.c_str());
1252// }
1253// return obj_type->m_var_type_fixed;
1254//}
1255//
1256//ObjPtr Named::GetTypeFromString(const std::string & type, bool *has_error = nullptr) {
1257// if (type.empty()) {
1258// if (has_error) {
1259// *has_error = true;
1260// return Obj::CreateNone();
1261// }
1262// LOG_RUNTIME("Type name '%s' not found!", type.c_str());
1263// }
1264//
1265// auto result_types = m_types.find(type);
1266// if (result_types != m_types.end()) {
1267// return result_types->second;
1268// }
1269//
1270// auto result_terms = m_terms->find(type);
1271// if (result_terms != m_terms->end()) {
1272// return result_terms->second;
1273// }
1274//
1275// auto result_find = find(type);
1276// if (result_find != end()) {
1277// return result_find->second.lock();
1278// }
1279//
1280// if (has_error) {
1281// *has_error = true;
1282// return nullptr;
1283// }
1284// LOG_RUNTIME("Type name '%s' not found!", type.c_str());
1285//}
1286
1287TermPtr Macro::FindTerm(std::string_view name) {//, bool *has_error = nullptr) {
1288 if (name.empty()) {
1289 LOG_RUNTIME("Empty term name!");
1290 }
1291
1292 // auto found = map::find(name);
1293 // if (found == end()) {
1294 // return nullptr;
1295 // }
1296 //
1297 // return found->second
1298 //
1299 //
1300 //
1301 // auto result_types = m_types.find(type);
1302 // if (result_types != m_types.end()) {
1303 // return result_types->second;
1304 // }
1305 //
1306 // auto result_terms = m_terms->find(type);
1307 // if (result_terms != m_terms->end()) {
1308 // return result_terms->second;
1309 // }
1310 //
1311 // auto result_find = find(type);
1312 // if (result_find != end()) {
1313 // return result_find->second.lock();
1314 // }
1315 //
1316 // if (has_error) {
1317 // *has_error = true;
1318 // return nullptr;
1319 // }
1320 LOG_RUNTIME("Type name '%s' not found!", name.begin());
1321}
static const char * DIAG_MACRO_NOT_FOUND
Definition diag.h:74
static BlockType SymbolSeparateArg_(const BlockType &buffer, size_t pos, std::vector< std::string > name, std::string &error)
Definition macro.cpp:823
TermPtr GetMacroById(const BlockType block)
Definition macro.cpp:1157
static std::string ExpandString(const TermPtr &macro, MacroArgsType &args)
Definition macro.cpp:1132
static BlockType MakeMacroId(const BlockType &seq)
Definition macro.cpp:176
TermPtr FindTerm(std::string_view name)
Definition macro.cpp:1287
static void InsertArg_(MacroArgsType &args, std::string name, BlockType &buffer, size_t pos=static_cast< size_t >(-1))
Definition macro.cpp:802
static bool CompareMacroName(const std::string &term_name, const std::string &macro_name)
Definition macro.cpp:604
static BlockType ExpandMacros(const TermPtr &macro, MacroArgsType &args)
Definition macro.cpp:1040
std::map< std::string, BlockType > MacroArgsType
Definition macro.h:192
static size_t ExtractArgs(BlockType &buffer, TermPtr &term, MacroArgsType &args)
Definition macro.cpp:862
std::string Dump()
Definition macro.cpp:521
static const std::string deny_chars_from_macro
Definition macro.h:109
TermPtr GetMacro(std::vector< std::string > list)
Definition macro.cpp:1166
static std::string toMacroHashName(const std::string str)
Definition macro.h:113
bool CheckMacro(const TermPtr &term)
Definition macro.cpp:266
static std::string DumpText(const BlockType &arr)
Definition macro.cpp:590
static BlockType GetMacroId(TermPtr &term)
Definition macro.cpp:204
static bool IdentityMacro(const BlockType &buffer, TermPtr &term)
Definition macro.cpp:753
bool RemoveMacro(TermPtr &term)
Definition macro.cpp:472
std::string GetMacroMaping(const std::string str, const char *separator=", ")
Definition macro.cpp:248
static std::string toMacroHash(TermPtr &term)
Definition macro.cpp:16
TermPtr EvalOpMacros(TermPtr &term)
Definition macro.cpp:390
bool m_is_lexer_complete
Definition parser.h:140
static size_t SkipBrackets(const BlockType &buffer, size_t offset)
Definition parser.cpp:862
static size_t ParseTerm(TermPtr &term, const BlockType &buffer, const size_t skip=0, bool pragma_enable=true)
Definition parser.cpp:895
DiagPtr m_diag
Definition parser.h:138
class Scanner * lexer
Definition parser.h:83
MacroPtr m_macro
Definition parser.h:139
BlockType m_macro_analisys_buff
Последовательность лексем для анализа на наличие макросов
Definition parser.h:91
SourceType source_string
Definition lexer.h:49
std::istringstream * m_macro_iss
Definition lexer.h:61
parser::location_type m_macro_loc
Definition lexer.h:62
parser::location_type * m_loc
Definition lexer.h:50
static TermPtr Create(TermID id, const char *text, parser::token_type lex_type=parser::token_type::END, size_t len=std::string::npos, location *loc=nullptr, std::shared_ptr< std::string > source=nullptr)
Definition term.h:335
static TermPtr CreateSymbol(char sym)
Definition term.h:339
int result
Definition lexer.l:367
buffer clear()
#define LOG_RUNTIME(format,...)
Definition logger.h:26
#define ASSERT(condition)
Definition logger.h:60
#define LOG_WARNING(...)
Definition logger.h:121
std::string ReplaceAll(std::string str, const std::string &from, const std::string &to)
Definition macro.cpp:1122
Definition nlc.h:59
bool isLocalName(const std::string_view name)
Definition types.h:1074
ExpandMacroResult
Definition parser.h:19
std::shared_ptr< Term > TermPtr
Definition variable.h:33
int64_t parseInteger(const char *str)
Definition types.h:998
ExpandMacroResult ExpandTermMacro(Parser &parser)
Definition macro.cpp:45
bool isReservedName(const std::string_view name)
Definition types.h:1036
std::vector< TermPtr > BlockType
Definition types.h:239
bool isLocalAnyName(const std::string_view name)
Definition types.h:1107
bool isMacroName(const std::string_view name)
Definition types.h:1097
const char * toString(TermID type)
Definition term.h:126
TermPtr ProcessMacro(Parser &parser, TermPtr &term)
Definition macro.cpp:26
#define NL_PARSER(term, format,...)
Definition types.h:310