NewLang Project
Yet another programm language
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Loading...
Searching...
No Matches
term.h
Go to the documentation of this file.
1#pragma once
2#ifndef INCLUDED_NEWLANG_TERM_
3#define INCLUDED_NEWLANG_TERM_
4
5#include <cstring>
6
7#include "warning_push.h"
8#include "location.hh"
9#include "parser.h"
10#include "warning_pop.h"
11
12#include "dict.h"
13#include "version.h"
14
15namespace newlang {
16
17#define NL_TERMS(_) \
18 _(NONE) \
19 \
20 _(SPACE) \
21 _(INDENT) \
22 _(COMMENT) \
23 _(CRLF) \
24 \
25 _(DOC_BEFORE) \
26 _(DOC_AFTER) \
27 \
28 _(SEQUENCE) \
29 _(BLOCK) \
30 _(BLOCK_TRY) \
31 _(BLOCK_PLUS) \
32 _(BLOCK_MINUS) \
33 \
34 _(INT_PLUS) \
35 _(INT_MINUS) \
36 _(INT_REPEAT) \
37 \
38 _(NAME) \
39 _(LOCAL) \
40 _(STATIC) \
41 _(MACRO) \
42 _(MODULE) \
43 _(NATIVE) \
44 _(MANGLED) \
45 \
46 _(TYPE) \
47 _(INTEGER) \
48 _(NUMBER) \
49 _(COMPLEX) \
50 _(RATIONAL) \
51 \
52 _(STRWIDE) \
53 _(STRCHAR) \
54 _(TEMPLATE) \
55 _(EVAL) \
56 \
57 _(EMPTY) \
58 _(ARGS) \
59 _(ARGUMENT) \
60 _(NEWLANG) \
61 _(TYPENAME) \
62 _(TYPECAST) \
63 _(TYPEDUCK) \
64 _(UNKNOWN) \
65 _(SYMBOL) \
66 _(NAMESPACE) \
67 _(PARENT) \
68 _(ESCAPE) \
69 \
70 _(MACRO_SEQ) \
71 _(MACRO_STR) \
72 _(MACRO_DEL) \
73 _(MACRO_TOSTR) \
74 _(MACRO_CONCAT) \
75 _(MACRO_ARGUMENT) \
76 _(MACRO_ARGNAME) \
77 _(MACRO_ARGPOS) \
78 _(MACRO_ARGCOUNT) \
79 _(MACRO_ATTR) \
80 _(MACRO_EXPR) \
81 \
82 _(CREATE_NEW) \
83 _(CREATE_USE) \
84 _(ASSIGN) \
85 _(PURE_USE) \
86 _(PURE_NEW) \
87 _(APPEND) \
88 _(SWAP) \
89 _(SYM_RULE) \
90 \
91 _(FUNCTION) \
92 _(COROUTINE) \
93 _(ITERATOR) \
94 \
95 _(FOLLOW) \
96 _(WHILE) \
97 _(DOWHILE) \
98 _(MATCHING) \
99 _(WITH) \
100 _(TAKE) \
101 \
102 _(RANGE) \
103 _(ELLIPSIS) \
104 _(FILLING) \
105 \
106 _(INDEX) \
107 _(FIELD) \
108 \
109 _(TENSOR) \
110 _(SET) \
111 _(DICT) \
112 _(CLASS) \
113 _(OP_LOGICAL) \
114 _(OP_MATH) \
115 _(OP_COMPARE) \
116 _(OP_BITWISE) \
117 _(EMBED)
118
119 enum class TermID : uint8_t {
120 END = 0,
121#define DEFINE_ENUM(name) name,
123#undef DEFINE_ENUM
124 };
125
126 inline const char* toString(TermID type) {
127 switch (type) {
128 case TermID::END:
129 return "END";
130
131#define DEFINE_CASE(name) \
132 case TermID::name: \
133 return #name;
135#undef DEFINE_CASE
136
137 default:
138 LOG_ERROR("UNKNOWN TERM TYPE %d", static_cast<int> (type));
139 return "UNKNOWN TYPE ";
140 }
141 }
142
143 size_t IndexArg(TermPtr term);
144 std::string ParserMessage(std::string &buffer, int row, int col, const char *format, ...);
145
146 inline static bool IsAnyCreate(TermID id) {
147 return id == TermID::CREATE_NEW || id == TermID::CREATE_USE || id == TermID::ASSIGN || id == TermID::PURE_USE || id == TermID::PURE_NEW;
148 }
149
150 /*
151 *
152 *
153 */
154
155 /*
156 * Класс для хренения имен переменных в соответствии с их областью видимости.
157 * Имена внутренних областей могут перекрывать внешние, но в
158 * одной области видимости (блоке) имена переменных должны быть уникальны.
159 *
160 * Поиск простого имени происходит в соответствии с name lookup.
161 * При добавлении имени без сигила, оно преобразуются в локальную переменную (var -> $var)
162 * Статические переменные <дополнительно> регистрируются в root, если он задан.
163 * За счет этого к статическим переменным можно обратиться по их полному имени из любого места модуля.
164 */
165
166 class StorageTerm : public std::map<std::string, TermPtr> {
167 public:
168
169 static constexpr std::string MODULE_ROOT = "\\\\";
170 static constexpr std::string MODULE_MAIN = "\\\\";
171
172 typedef std::map<std::string, StorageTerm> ModuleMapType;
173
175 }
177
178 bool RegisterName(TermPtr term, const std::string_view syn = "");
179
180 std::string Dump() {
181 std::string result;
182#ifdef BUILD_UNITTEST
183 {
184 std::string list;
185 auto iter = this->begin();
186 while (iter != this->end()) {
187 if (!list.empty()) {
188 list += ", ";
189 }
190
191 list += iter->first;
192 iter++;
193 }
194
195 // result += "(";
196 result += list;
197 result += "\n";
198 }
199#endif
200 return result;
201 }
202 };
203
204 struct ScopeVars {
208 std::vector<std::string> ns_lookup;
209 };
210
234 class NameLookupStack : SCOPE(protected) std::deque< ScopeVars > { // use deque instead of vector as it preserves iterators when resizing
235 public:
238 size_t m_block_num;
239 public:
240
242
243 void clear();
244
246 }
247
248 static std::string EnumerateString(const StringArray &names) {
249 std::string fails;
250 for (auto &elem : names) {
251 if (!fails.empty()) {
252 fails += ", ";
253 }
254 fails += elem;
255 }
256 return fails;
257 }
258
259 /*
260 *
261 */
262 void PushScope(TermPtr ns, bool is_function = false);
263
264 void PopScope() {
265 ASSERT(size() > 1); // First level reserved for static objects
266 pop_back();
267 }
268
270
282 bool AddName(const TermPtr var, const char * alt_name = nullptr);
283
284 // bool FixTransaction();
285 // void RollbackNames_();
286 // void RemoveName_(const std::string_view int_name);
294 TermPtr FindInternalName(std::string_view int_name);
295
296
303 TermPtr LookupName(std::string name);
304 TermPtr LookupNameVars(const std::string_view name);
305 TermPtr LookupNameNamespace(const std::string_view ns, const std::string_view name);
306
307
308 std::string MakeInternalName(const TermPtr & term, bool is_static);
309 std::string MakeInternalName(const std::string_view name, bool is_static);
310 void ExpandNamespace(std::string & name);
311 std::string GetNamespace();
312 std::string GetFuntionName();
313
314 std::string MakeNamespace(int skip, bool is_global);
315 bool CheckInterrupt(std::string_view name);
316
317 std::string GetOffer() {
318 return "";
319 }
320
321 bool LookupBlock_(TermPtr &term);
322 std::string GetOfferBlock();
323
324 std::string Dump();
325
326 };
327
328 /*
329 *
330 *
331 */
332 class Term : public Dict<Term>, public std::enable_shared_from_this<Term> {
333 public:
334
335 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) {
336 return std::make_shared<Term>(id, text, lex_type, (len == std::string::npos ? strlen(text) : len), loc, source);
337 }
338
339 static TermPtr CreateSymbol(char sym) {
340 return Create(TermID::SYMBOL, std::string(1, sym).c_str(), static_cast<parser::token_type> (sym));
341 }
342
343
344 static TermPtr CreateNone();
345 static TermPtr CreateNil();
346 static TermPtr CreateDict();
347 static TermPtr CreateName(std::string name, TermID id = TermID::NAME);
348 static TermPtr CreateIntName(const std::string_view name, const std::string_view int_name, TermID id = TermID::NAME);
349
352 *result.get() = *this;
353 return result;
354 }
355
356 Term(TermID id, const char *text, parser::token_type lex_type, size_t len, location *loc, std::shared_ptr<std::string> source = nullptr) {
357 m_lexer_type = lex_type;
358 m_ref.reset();
359 if (text && len) {
360 m_text.assign(text, std::min(strlen(text), len));
361 }
362 if (loc) {
363 m_line = loc->end.line;
364 m_col = loc->end.column;
365 } else {
366 m_line = 0;
367 m_col = 0;
368 }
369 m_source = source;
370 m_is_call = false;
371 m_is_const = false;
372 m_bracket_depth = 0;
373 m_is_owner = false;
374 m_is_take = false;
375 // m_is_reference = false;
376 m_level = 0;
377
378 // m_ref_restrict = RefType::RefNone;
379 // m_ref_type = RefType::RefNone;
380
381 m_id = id;
382 }
383
384 virtual ~Term() {
385#if BUILD_UNTITEST
386 LOG_DUMP("DeleteVar %d \"%s\" (%p)", static_cast<int> (m_id), m_text.c_str(), (void *) this);
387#endif
388 clear_();
389 }
390
391 inline TermID getTermID() const {
392 return m_id;
393 }
394
395 inline const std::string & getName() const {
396 return m_name_or_class;
397 }
398
399 inline std::string & getName() {
400 return m_name_or_class;
401 }
402
403 inline void SetName(std::string & name) {
405 }
406
407 inline std::string & getText() {
408 return m_text;
409 }
410
411 inline const std::string & getText() const {
412 return m_text;
413 }
414
415 inline bool isRef() {
416 return !!m_ref;
417 }
418
419 inline bool isCall() const {
420 return m_is_call;
421 }
422
423 inline bool isInterrupt() const {
424 switch (m_id) {
425 case TermID::INT_PLUS:
428 return true;
429 default:
430 return false;
431 }
432 }
433
434 inline bool isCreateNew() const {
435 switch (m_id) {
437 case TermID::PURE_NEW:
438 return true;
439 }
440 return false;
441 }
442
443 inline bool isCreateUse() const {
444 switch (m_id) {
446 case TermID::PURE_USE:
447 return true;
448 }
449 return false;
450 }
451
452 inline bool isCreate() const {
453 switch (m_id) {
454 case TermID::APPEND:
457 case TermID::ASSIGN:
458 case TermID::PURE_NEW:
459 case TermID::PURE_USE:
460 case TermID::SWAP:
461 return true;
462 }
463 return false;
464 }
465
466 inline bool isPure() const {
467 switch (m_id) {
468 case TermID::PURE_NEW:
469 case TermID::PURE_USE:
470 return true;
471 }
472 return false;
473 }
474
475 inline bool isNone() const {
476 return m_id == TermID::NAME && m_text.compare("_") == 0;
477 }
478
479 inline bool isMacro() const {
480 return m_id == TermID::MACRO_DEL || (isCreate() && m_left && m_left->m_id == TermID::MACRO_SEQ);
481 }
482
483 inline bool isReturn() const {
485 }
486
487 inline const std::string GetFullName() const {
488 std::string result(m_text);
489 //result.insert(isType(result) ? 1 : 0, m_ns_block);
490 return result;
491 }
492
493 inline bool isFunction() const {
494 return m_id == TermID::FUNCTION;
495 }
496
497 inline bool isScalar() const {
498 switch (m_id) {
499 case TermID::INTEGER:
500 case TermID::NUMBER:
501 return true;
502 }
503 return false;
504 }
505
506 inline bool isString() const {
507 switch (m_id) {
508 case TermID::STRWIDE:
509 case TermID::STRCHAR:
510 return true;
511 }
512 return false;
513 }
514
515 inline bool isNamed() const {
516 switch (m_id) {
517 case TermID::NAME:
518 case TermID::TYPE:
519 case TermID::ARGS:
520 case TermID::ARGUMENT:
521 case TermID::LOCAL:
522 case TermID::STATIC:
523 case TermID::MODULE:
524 return true;
525 }
526 return false;
527 }
528
529 inline bool isLiteral() const {
530 switch (m_id) {
531 case TermID::INTEGER:
532 case TermID::NUMBER:
533 case TermID::STRWIDE:
534 case TermID::STRCHAR:
535 case TermID::RATIONAL:
536 case TermID::DICT:
537 case TermID::TENSOR:
538 case TermID::RANGE:
539 case TermID::END:
540 return true;
541 }
542 return false;
543 }
544
545 inline bool isCalculated() const {
546 switch (m_id) {
547 case TermID::ARGUMENT:
548 case TermID::ARGS:
549 case TermID::NAME:
551 case TermID::ASSIGN:
553 case TermID::RANGE:
554 case TermID::TENSOR:
555 case TermID::DICT:
557 case TermID::OP_MATH:
558 case TermID::EVAL:
559 return true;
560 default:
561 return isLiteral() || isCall(); // || IsFunction() || IsVariable()
562 }
563 }
564
565 inline static bool isExportName(const TermPtr &term) {
566 return term->m_is_call || !isLocalName(term->m_text);
567 }
568
569 inline bool isExport() const {
570 return m_id == TermID::MACRO_DEL || (isCreate() && (isExportName(m_left) || m_left->m_id == TermID::MACRO_SEQ));
571 }
572
573 inline bool isBlock() const {
574 switch (m_id) {
575 case TermID::SEQUENCE:
576 case TermID::BLOCK:
580 return true;
581 }
582 return false;
583 }
584
586 return size() && at(size() - 1).second && at(size() - 1).second->getTermID() == TermID::ELLIPSIS;
587 }
588
589 void dump_items_(std::string &str) const {
590 bool first = true;
591 for (auto elem : * this) {
592 if (first) {
593 first = false;
594 } else {
595 str.append(", ");
596 }
597 if (!elem.second->m_name_or_class.empty()) {
598 str.append(elem.second->m_name_or_class);
599
600 if (elem.second->GetType() && !isDefaultType(elem.second->GetType())) {
601 str += elem.second->GetType()->asTypeString();
602 }
603
604 str.append("=");
605 }
606 // LOG_DEBUG("%s %s", newlang::toString(elem.second->getTermID()), elem.second->m_text.c_str());
607 str.append(elem.second->toString(true));
608 }
609 }
610
611 std::string toString(bool nested = false) {
612 std::string result; //(m_ref ? m_ref->m_text : "");
614 if (m_left) {
615 if (!result.empty()) {
616 result += "=";
617 }
618 ASSERT(this != m_left.get());
619 result += m_left->toString();
620 }
621
622 TermPtr temp;
623 std::string str_text;
624 bool test;
625 switch (m_id) {
626 case TermID::END:// name=<END>
627 result += "<END>";
628 return result;
629
630 case TermID::SPACE:
631 case TermID::INDENT:
632 case TermID::COMMENT:
633 case TermID::CRLF:
634 case TermID::FIELD:
635 return m_text;
636
638 result = "@@@";
639 result += m_text;
640 result += "@@@";
641 return result;
642
643
644 case TermID::ARGS:
645 case TermID::ARGUMENT:
646 case TermID::ITERATOR:
647 result += m_text;
648 if (size()) {
649 result += "(";
651 result += ")";
652 }
653 return result;
654
655 case TermID::INT_PLUS:
657 if (m_namespace) {
658 result = m_namespace->m_text;
659 result += " ";
660 }
661 result += m_text;
662 if (m_right) {
663 result += " ";
664 result += m_right->toString();
665 }
666 return result;
667
668 case TermID::INDEX:
669 result = "";
670 if (size()) {
671 result += "[";
673 result += "]";
674 }
675 return result;
676
677
678 case TermID::NONE:
679 case TermID::PARENT:
680 case TermID::MODULE:
681 case TermID::NEWLANG:
682 case TermID::NATIVE:
683 case TermID::MANGLED:
684 case TermID::MACRO:
685 case TermID::LOCAL:
686 case TermID::STATIC:
687 case TermID::WITH:
688 case TermID::TAKE:
689 case TermID::NAME: // name=(1,second="two",3,<EMPTY>,5)
690 // result(m_is_ref ? "&" : "");
691 ASSERT(!(m_dims && m_dims->size()));
692
693 result = "";
694 temp = shared_from_this();
695 if (temp->m_left) {
696 result = temp->m_left->toString();
697 }
698 while (!nested && temp->m_right) {
699 if (this == temp->m_right.get()) {
700 ASSERT(this != temp->m_right.get());
701 }
702 if (temp->m_right->m_left) {
703 if (this == temp->m_right->m_left.get()) {
704 break;
705 }
706 ASSERT(this != temp->m_right->m_left.get());
707 }
708 result += temp->m_right->toString(true);
709 temp = temp->m_right;
710 }
711
712 if (!m_normalized.empty()) {
713 result.insert(0, m_normalized);
714 } else {
715 result.insert(0, m_text);
716 if (m_namespace) {
717 result.insert(0, m_namespace->m_text);
718 }
719 }
720
721 if (m_ref) {
722 result.insert(0, m_ref->m_text);
723 }
724 if (m_is_const) {
725 result += "^";
726 }
727 // if (!m_name.empty()) {
728 // if (GetType()) {
729 // result = m_name + GetType()->asTypeString() + "=" + result;
730 // // } else {
731 // // result = m_name + "=" + result;
732 // }
733 // }
734 // LOG_DEBUG("3 %s", result.c_str());
735 if (size()) {
736 result += "(";
738 result += ")";
739 } else if (m_is_call) {
740 result += "()";
741 }
742 if (m_name_or_class.empty() && GetType() && !isDefaultType(GetType())) {
743 result += GetType()->asTypeString();
744 }
745
746 // if (!m_follow.empty()) {
747 // ASSERT(m_follow.size() == 1);
748 // result += ",[...]-->";
749 // result += m_follow[0]->toString();
750 // }
751
752 return result;
753
754 case TermID::STRCHAR:// name:="string"
755 case TermID::STRWIDE:// name:="string"
756 // if (!result.empty()) {
757 // result += "=";
758 // }
759 result = m_id == TermID::STRWIDE ? "\"" : "'";
760 result += m_text;
761 result += m_id == TermID::STRWIDE ? "\"" : "'";
762 if (size()) {
763 result += "(";
765 result += ")";
766 }
767 return result;
768
769 case TermID::EVAL:
770 // if (!result.empty()) {
771 // result += "=";
772 // }
773 result = "`";
774 result += m_text;
775 result += "`";
776 return result;
777
778 case TermID::INTEGER:// name:=123
779 case TermID::NUMBER: // name:=123.0
780 // test = result.empty();
781 // if (GetType() && !m_name.empty()) {
782 // result += GetType()->asTypeString();
783 // }
784 // if (!test) {
785 // result += "=";
786 // }
787 result = m_text;
788 if (GetType() && !isDefaultType(GetType()) && m_name_or_class.empty()) {
789 result += GetType()->asTypeString();
790 }
791 return result;
792
793 case TermID::ASSIGN:
796 case TermID::PURE_NEW:
797 case TermID::PURE_USE:
798 // case TermID::APPEND:
799 if (m_id == TermID::ASSIGN) {
800 result += m_text;
801 } else {
802 result += " " + m_text + " ";
803 }
804 if (m_right) {
805 result += m_right->toString();
806 }
807 if (!nested) {
808 result += ";";
809 }
810 return result;
811
812 case TermID::APPEND:
813 result = m_left->toString();
814 // result += "[]";
815 if (!m_name_or_class.empty()) {
816 result += "." + m_name_or_class;
817 }
818 result += " " + m_text + " ";
819 result += m_right->toString();
820 if (!nested) {
821 result += ";";
822 }
823 return result;
824
825 case TermID::RANGE:
826 ASSERT(size() == 2 || size() == 3);
827 result = at(0).second->toString();
828 result += "..";
829 result += at(1).second->toString();
830 if (size() == 3) {
831 result += "..";
832 result += at(2).second->toString();
833 // result += ")";
834 }
835 return result;
836
837 case TermID::FUNCTION:
838
839 result += " " + m_text + " ";
840 // result.insert(0, m_namespace);
841 // result += "{";
842 if (m_right && this != m_right.get()) {
843 result += m_right->toString(true);
844 if (!result.empty() && result[result.size() - 1] != ';') {
845 result += ";";
846 }
847 for (int i = 0; i < m_right->size(); i++) {
848 result += m_right->at(i).second->toString();
849 }
850 }
851 // result += "};";
852 return result;
853
854 case TermID::TENSOR:
855 result += "[";
857 result += ",";
858 result += "]";
859 if (GetType() && !isDefaultType(GetType())) {
860 result += GetType()->asTypeString();
861 }
862 return result;
863
864 case TermID::DICT:
865 result += "(";
867 result += ",";
868 result += ")";
869 if (!m_name_or_class.empty()) {
871 }
872 if (GetType() && !isDefaultType(GetType())) {
873 result += GetType()->asTypeString();
874 }
875 return result;
876
877 case TermID::TYPEDUCK:
878 case TermID::TYPECAST:
879 case TermID::TYPE:
880 if (m_id == TermID::TYPEDUCK) {
881 result += ":~~";
882 result += m_text.substr(1);
883 } else if (m_id == TermID::TYPECAST) {
884 result += ":~";
885 result += m_text.substr(1);
886 } else {
887 result += ":";
888 if (m_ref) {
889 result += m_ref->m_text;
890 }
891 result += m_text.substr(1);
892 }
893 if (m_dims && m_dims->size()) {
894 result += "[";
895 for (int i = 0; i < m_dims->size(); i++) {
896 if (i) {
897 result += ",";
898 }
899 result += m_dims->at(i).second->toString();
900 }
901 result += "]";
902 }
903
904
905 if (m_is_call) {
906 result += "(";
908 result += ")";
909 }
910 return result;
911
912 case TermID::EMBED: // name:={% function code %}
913 result += "{%";
914 result += m_text;
915 result += "%}";
916 if (m_right) {
917 result += m_right->toString();
918 }
919 return result;
920
921 case TermID::WHILE: // [cond] <-> repeat;
922 result = "[" + result + "]";
923 result += m_text;
925 result += m_right->toString();
926 result += ";";
927 return result;
928
929 case TermID::DOWHILE:
930 result += m_text + "[";
932 result += m_right->toString();
933 result += "];";
934 return result;
935
936 case TermID::FOLLOW: // (cond) -> seq;
937
938 // if (m_follow.empty()) {
939 // result.insert(0, "[");
940 // result += "]-->{";
941 // ASSERT(m_right);
942 // result += m_right->toString();
943 // result += "}";
944 // if (m_right->m_right) {
945 // result += "-->";
946 // result += m_right->m_right->toString();
947 // }
948 // } else {
949 result.clear();
950 for (size_t i = 0; i < m_block.size(); i++) {
951 if (!result.empty()) {
952 result += ",\n ";
953 }
954 if (m_block[i]->m_left) {
955 result += "[";
956 result += m_block[i]->m_left->toString();
957 result += "]";
958 } else {
959 result += " ";
960 }
962 // if (m_follow[i]->m_right) {
963 result += "-->";
964 result += m_block[i]->m_right->toString();
965 if (!(m_block[i]->isBlock() || m_block[i]->getTermID() == TermID::EMBED)) {
966 result += ";";
967 }
968 // result += "}";
969 // } else {
970 // if (nested || (!nested && m_follow[i]->m_left)) {
971 // result += "-->";
972 // }
973 // result += m_follow[i]->toString(true);
974 // if (!(m_follow[i]->isBlock() || m_follow[i]->getTermID() == TermID::EMBED)) {
975 // result += ";";
976 // }
977 // if (nested || (!nested && m_follow[i]->m_left)) {
978 // // result += "}";
979 // }
980 // }
981 }
982 // if (!nested) {
983 // result += ";";
984 // }
985 // }
986
987 return result;
988 case TermID::SEQUENCE:
989 case TermID::BLOCK:
993 result = "";
994 if (m_namespace && !m_namespace->m_text.empty() && m_namespace->m_text[0] != '$') {
995 result += m_namespace->m_text;
996 result += " ";
997 }
998 // if (m_id == TermID::CALL_BLOCK || m_id == TermID::CALL_TRY) {
999 // result += "(";
1000 // dump_items_(result);
1001 // result += ")";
1002 // }
1003 if (m_id == TermID::SEQUENCE) {
1004 } else if (m_id == TermID::BLOCK) {
1005 result += "{";
1006 } else if (m_id == TermID::BLOCK_TRY) {
1007 result += "{*";
1008 } else if (m_id == TermID::BLOCK_PLUS) {
1009 result += "{+";
1010 } else if (m_id == TermID::BLOCK_MINUS) {
1011 result += "{-";
1012 } else {
1013 LOG_ABORT("Unknown block type %s (%d)", newlang::toString(m_id), static_cast<uint8_t> (m_id));
1014 }
1015
1016 if (!m_name_or_class.empty()) {
1017 result.insert(0, " ");
1018 result.insert(0, m_name_or_class);
1019 }
1020
1021 for (size_t i = 0; i < m_block.size(); i++) {
1022 if (i) {
1023 result += " ";
1024 }
1025 result += m_block[i]->toString(true);
1026 if (!result.empty() && result[result.size() - 1] != ';') {
1027 result += ";";
1028 }
1029 }
1030
1031 if (m_id == TermID::SEQUENCE) {
1032 } else if (m_id == TermID::BLOCK) {
1033 result += "}";
1034 } else if (m_id == TermID::BLOCK_TRY) {
1035 result += "*}";
1036 } else if (m_id == TermID::BLOCK_PLUS) {
1037 result += "+}";
1038 } else if (m_id == TermID::BLOCK_MINUS) {
1039 result += "-}";
1040 } else {
1041 LOG_ABORT("Unknown block type %s (%d)", newlang::toString(m_id), (int) m_id);
1042 }
1043
1045 return result;
1046
1047 case TermID::OP_MATH:
1048 case TermID::OP_BITWISE:
1049 case TermID::OP_COMPARE:
1050 case TermID::OP_LOGICAL:
1051 result += " ";
1052 result += m_text;
1053 result += " ";
1054 if (m_right) {
1055 result += m_right->toString();
1056 }
1057 return result;
1058
1059 case TermID::ELLIPSIS:
1060 if (m_left) {
1061 result = m_left->toString();
1062 result += " ";
1063 }
1064 result += m_text;
1065 if (m_right) {
1066 result += m_right->toString();
1067 }
1068 return result;
1069
1070 case TermID::FILLING:
1071 result += "...";
1072 if (m_right) {
1073 result += m_right->toString();
1074 }
1075 result += "...";
1076 return result;
1077
1078 case TermID::MACRO_DEL:
1079 case TermID::MACRO_SEQ:
1080 result = m_text;
1081 result += " ";
1082
1083 for (size_t i = 0; i < m_macro_seq.size(); i++) {
1084 if (i) {
1085 result += " ";
1086 }
1087 if (m_macro_seq[i]->getTermID() == TermID::NAME) {
1088 result += m_macro_seq[i]->toString();
1089 } else {
1090 result += m_macro_seq[i]->m_text;
1091 }
1092 }
1093 result += " ";
1094 result += m_text;
1095 return result;
1096
1097 case TermID::NAMESPACE:
1098 case TermID::SYMBOL:
1099 case TermID::UNKNOWN:
1100 case TermID::RATIONAL:
1101 case TermID::COMPLEX:
1107 return m_text;
1108
1109 case TermID::ESCAPE:
1110 result = "@\\";
1111 result += m_text;
1112 return result;
1113
1114 case TermID::EMPTY:
1115 return result + "=";
1116
1117
1118 case TermID::CLASS:
1119 result.clear();
1120
1121 bool comma = false;
1122 {
1123 TermPtr next = shared_from_this();
1124 while (next) {
1125 if (comma) {
1126 result += ", ";
1127 } else {
1128 comma = true;
1129 }
1130 result += next->GetFullName();
1131 result += "(";
1132 next->dump_items_(result);
1133 result += ")";
1134 next = next->m_right;
1135 }
1136 }
1137
1138 result += "{";
1139 for (size_t i = 0; i < m_block.size(); i++) {
1140 if (i) {
1141 result += " ";
1142 }
1143 result += m_block[i]->toString(true);
1144 // if (m_block[i]->getTermID() != TermID::EMBED) {
1145 // result += ";";
1146 // }
1147 }
1148 result += "}";
1149
1150 return result;
1151
1152 }
1153 LOG_RUNTIME("Fail toString() type %s, text:'%s'", newlang::toString(m_id), m_text.c_str());
1154 }
1155
1156 inline std::ostream & Print(std::ostream &out = std::cout, const char *delimiter = nullptr) {
1157 std::string str;
1158 out << toString();
1159 return out;
1160 }
1161
1162 inline TermPtr Begin() {
1163 if (m_left) {
1164 return m_left->Begin();
1165 }
1166 return shared_from_this();
1167 }
1168
1169 inline TermPtr End() {
1170 if (m_right) {
1171 return m_right->End();
1172 }
1173 return shared_from_this();
1174 }
1175
1176 void SetSource(std::shared_ptr<std::string> source) {
1177 if (m_source == source) {
1178 return;
1179 }
1180 m_source = source;
1181 // if (m_type && m_type.get() != this) {
1182 // m_type->SetSource(source);
1183 // }
1184 // for (int i = 0; i < size(); i++) {
1185 // at(i).second->SetSource(m_source);
1186 // }
1187 // for (auto &elem : m_block) {
1188 // if (elem.get() != this) {
1189 // elem->SetSource(m_source);
1190 // }
1191 // }
1192 //
1193 // TermPtr next = shared_from_this()->m_right;
1194 // while (next && !m_source) {
1195 // next->SetSource(m_source);
1196 // next = next->m_right;
1197 // }
1198 // next = shared_from_this()->m_left;
1199 // while (next && !m_source) {
1200 //
1201 // next->SetSource(m_source);
1202 // next = next->m_left;
1203 // }
1204 }
1205
1206 inline void AppendLeft(TermPtr item) {
1207 if (!item->m_source) {
1208 item->m_source = m_source;
1209 }
1210 TermPtr next = shared_from_this();
1211 while (next->m_left) {
1212 ASSERT(next != next->m_left);
1213 next = next->m_left;
1214 }
1215 ASSERT(next != item);
1216 next->m_left = item;
1217 }
1218
1219 inline void AppendRight(TermPtr item) {
1220 if (!item->m_source) {
1221 item->m_source = m_source;
1222 }
1223 TermPtr next = shared_from_this();
1224 if (next == item) {
1225 // ASSERT(next != item);
1226 }
1227 while (next->m_right) {
1228 ASSERT(next != next->m_right);
1229 next = next->m_right;
1230 }
1231 next->m_right = item;
1232 }
1233
1234 inline void AppendText(const std::string & s) {
1235 m_text.append(s);
1236 }
1237
1238 inline void AppendText(TermPtr txt) {
1239 m_text.append(txt->getText());
1240 }
1241
1242 void RightToBlock(std::vector<TermPtr> &vect, bool remove = true) {
1243 TermPtr next = shared_from_this();
1244 TermPtr prev;
1245
1246 vect.clear();
1247 while (next) {
1248 if (next->getTermID() != TermID::END) {
1249 vect.push_back(next);
1250 }
1251 prev = next;
1252 next = next->m_right;
1253 if (remove) {
1254 prev->m_right.reset();
1255 }
1256 }
1257 }
1258
1259 inline void SetArgs(TermPtr args) {
1260 m_is_call = true;
1261 for (auto &elem : args->m_block) {
1262 if (isSystemName(elem->getName())) {
1263 if (!m_sys_prop) {
1265 }
1266 m_sys_prop->push_back(elem, elem->getName());
1267 } else {
1268 if (m_sys_prop) {
1269 NL_PARSER(elem, "Cannot pass arguments after any system attributes!");
1270 }
1271 push_back(elem, elem->getName());
1272 }
1273 }
1274 args->m_block.clear();
1275 }
1276
1277 TermPtr AppendBlock(TermPtr &item, TermID id, bool force = false) {
1278
1279 if (force) {
1280 ASSERT(isBlock() && m_block.empty() && m_id == id);
1281 m_block.push_back(item);
1282 return shared_from_this();
1283 }
1284
1286 if (m_id == id || m_id == TermID::SEQUENCE) {
1287 if (m_id != id) {
1288 m_id = id;
1289 }
1290 result = shared_from_this();
1291 if (item->isBlock()) {
1292 if (this != item.get()) {
1293 result->m_block.insert(result->m_block.end(), item->m_block.begin(), item->m_block.end());
1294 } else {
1295 // result = Term::Create(id, "", parser::token_type::END, 0, &item->m_lexer_loc);
1296 // result->m_block.push_back(shared_from_this());
1297 }
1298 } else {
1299 result->m_block.push_back(item);
1300 }
1301 } else {
1302 ASSERT(!isBlock());
1303 result = Term::Create(id, "", parser::token_type::END, 0, &item->m_lexer_loc);
1304 result->m_block.push_back(shared_from_this());
1305 if (this != item.get()) {
1306 result->m_block.push_back(item);
1307 }
1308 if (item->m_id == TermID::SEQUENCE) {
1309 item->m_id = id;
1310 }
1311 }
1312 return result;
1313 }
1314
1315 void clear_() override {
1316 Clear(true);
1317 }
1318
1319 void Clear(bool clear_iterator_name) {
1320 if (m_left && m_right) {
1321 m_left->m_right = m_right;
1322 m_right->m_left = m_left;
1323 m_left.reset();
1324 m_right.reset();
1325 } else if (m_left) {
1326 m_left->m_right.reset();
1327 m_left.reset();
1328 } else if (m_right) {
1329
1330 m_right->m_left.reset();
1331 m_right.reset();
1332 }
1333 m_id = TermID::END;
1334 m_text.clear();
1335 m_line = 0;
1336 m_col = 0;
1337
1338 m_name_or_class.clear();
1339 m_text.clear();
1340 m_block.clear();
1341 m_block.clear();
1342 m_source.reset();
1343 m_docs.clear();
1344 m_macro_id.clear();
1345 m_macro_seq.clear();
1346 m_namespace.reset();
1347 }
1348
1349 inline TermPtr First() {
1350 if (m_left) {
1351
1352 return m_left->First();
1353 }
1354 return shared_from_this();
1355 }
1356
1357 inline TermPtr Last() {
1358 if (m_right) {
1359 return m_right->Last();
1360 }
1361 return shared_from_this();
1362 }
1363
1364 void MakeRef(TermPtr ref) {
1366 LOG_RUNTIME("Cannon make referens value for %s!", toString().c_str());
1367 }
1368 m_ref = ref;
1369 }
1370
1371 std::string asTypeString() const {
1372 std::string result = m_text;
1373 if (m_ref) {
1374 result.insert(1, m_ref->m_text);
1375 }
1376 if (size()) {
1377 result += "(";
1379 result += ")";
1380 }
1381 if (m_dims && m_dims->size()) {
1382 result += "[";
1383 bool first = true;
1384 for (size_t i = 0; i < m_dims->size(); i++) {
1385 if (!first) {
1386 result += ",";
1387 }
1388 result += m_dims->at(i).second->toString(true);
1389 first = false;
1390 }
1391 result += "]";
1392 }
1393 return result;
1394 }
1395
1396 void SetType(TermPtr type);
1397
1398 inline TermPtr GetType() {
1399 return m_type;
1400 }
1401
1402 inline bool TestConst() {
1403 if (isConstName(m_text)) {
1404 m_is_const = true;
1405 if (!isReservedName(m_text)) {
1406 m_text.resize(m_text.size() - 1);
1407 }
1408 }
1409 return m_is_const;
1410 }
1411
1417 static bool CheckTermEq(const TermPtr &term, const TermPtr &proto, bool type = false, RuntimePtr rt = nullptr);
1418
1422 int m_col;
1423
1426
1429
1430 std::string m_text;
1431 std::string m_name_or_class;
1435
1436 size_t m_level;
1442
1444 // bool m_is_reference;
1445
1447
1449
1450 public:
1452 parser::token_type m_lexer_type;
1453 parser::location_type m_lexer_loc;
1456
1457 SCOPE(private) :
1458 };
1459
1460 std::ostream & operator<<(std::ostream &out, newlang::TermPtr & var);
1461 std::ostream & operator<<(std::ostream &out, newlang::TermPtr var);
1462
1467 public:
1469
1470 ScopePush(NameLookupStack &scope, TermPtr ns, bool is_function = false) : m_scope(scope) {
1471 m_scope.PushScope(ns, is_function);
1472 }
1473
1475 // m_scope.RollbackNames_();
1476 m_scope.PopScope();
1477 }
1478 };
1479
1480}
1481#endif // INCLUDED_NEWLANG_TERM_
PairType & push_back(const PairType &p)
Definition dict.h:94
virtual const std::string & name(const int64_t index) const
Definition dict.h:145
virtual PairType & at(const int64_t index)
Definition dict.h:114
StorageTerm::ModuleMapType & m_modules
Use as a pre-declaration of (an "external") object.
Definition term.h:237
virtual ~NameLookupStack()
Definition term.h:245
NameLookupStack(GlobalObjects &glob, StorageTerm::ModuleMapType &modules)
Definition term.cpp:164
TermPtr LookupNameNamespace(const std::string_view ns, const std::string_view name)
Definition term.cpp:526
std::string Dump()
Definition term.cpp:691
void ExpandNamespace(std::string &name)
Definition term.cpp:223
GlobalObjects & m_glob
Buildin in Runtime.
Definition term.h:236
std::string MakeNamespace(int skip, bool is_global)
Definition term.cpp:250
size_t m_block_num
Нумератор безымянных блоков кода
Definition term.h:238
bool LookupBlock_(TermPtr &term)
Definition term.cpp:647
std::string GetOffer()
Definition term.h:317
bool CheckInterrupt(std::string_view name)
Definition term.cpp:234
TermPtr FindInternalName(std::string_view int_name)
Definition term.cpp:475
TermPtr LookupNameVars(const std::string_view name)
Definition term.cpp:494
std::string MakeInternalName(const TermPtr &term, bool is_static)
Definition term.cpp:309
void SetLookupNamespace(TermPtr ns)
Definition term.cpp:200
TermPtr LookupName(std::string name)
Definition term.cpp:541
std::string GetOfferBlock()
Definition term.cpp:670
static std::string EnumerateString(const StringArray &names)
Definition term.h:248
std::string GetFuntionName()
Definition term.cpp:277
std::string GetNamespace()
Definition term.cpp:289
bool AddName(const TermPtr var, const char *alt_name=nullptr)
Definition term.cpp:426
void PushScope(TermPtr ns, bool is_function=false)
Definition term.cpp:181
ScopePush(NameLookupStack &scope, TermPtr ns, bool is_function=false)
Definition term.h:1470
NameLookupStack & m_scope
Definition term.h:1468
std::string Dump()
Definition term.h:180
bool RegisterName(TermPtr term, const std::string_view syn="")
Definition term.cpp:734
static constexpr std::string MODULE_ROOT
Definition term.h:169
std::map< std::string, StorageTerm > ModuleMapType
Definition term.h:172
static constexpr std::string MODULE_MAIN
Definition term.h:170
TermPtr Clone()
Definition term.h:350
TermPtr Last()
Definition term.h:1357
bool isCall() const
Definition term.h:419
virtual ~Term()
Definition term.h:384
std::ostream & Print(std::ostream &out=std::cout, const char *delimiter=nullptr)
Definition term.h:1156
static bool isExportName(const TermPtr &term)
Definition term.h:565
size_t m_level
Dict nesting level (if applicable)
Definition term.h:1436
bool m_is_take
Object data capture flag.
Definition term.h:1438
void RightToBlock(std::vector< TermPtr > &vect, bool remove=true)
Definition term.h:1242
bool isCreateNew() const
Definition term.h:434
bool isFunction() const
Definition term.h:493
BlockType m_block
A list of terms separated by semicolons with in a block.
Definition term.h:1427
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
TermPtr Begin()
Definition term.h:1162
int m_bracket_depth
Internal data of the depth of brackets when processed in the lexer.
Definition term.h:1451
static TermPtr CreateNil()
Definition term.cpp:28
TermPtr m_ref
Type of reference before the variable (valid references or its creation operator)
Definition term.h:1441
TermPtr AppendBlock(TermPtr &item, TermID id, bool force=false)
Definition term.h:1277
void clear_() override
Definition term.h:1315
void SetType(TermPtr type)
Definition term.cpp:49
bool isNone() const
Definition term.h:475
void SetSource(std::shared_ptr< std::string > source)
Definition term.h:1176
void AppendText(TermPtr txt)
Definition term.h:1238
static TermPtr CreateIntName(const std::string_view name, const std::string_view int_name, TermID id=TermID::NAME)
Definition term.cpp:38
bool TestConst()
Definition term.h:1402
const std::string GetFullName() const
Definition term.h:487
const std::string & getText() const
Definition term.h:411
static bool CheckTermEq(const TermPtr &term, const TermPtr &proto, bool type=false, RuntimePtr rt=nullptr)
Definition term.cpp:112
parser::location_type m_lexer_loc
Internal data for macroprocessor.
Definition term.h:1453
TermPtr m_namespace
The current namespace in the source file when this term is used.
Definition term.h:1432
TermID getTermID() const
Definition term.h:391
TermID m_id
Term id (name, block, operator, string etc.)
Definition term.h:1419
bool m_is_owner
The flag of the object's owner (if applicable)
Definition term.h:1437
TermPtr m_type
Term type if specified.
Definition term.h:1428
std::string m_name_or_class
The name or class of the term, if the term has a name or class.
Definition term.h:1431
void dump_items_(std::string &str) const
Definition term.h:589
BlockType m_macro_id
Internal data for macroprocessor.
Definition term.h:1454
bool isMacro() const
Definition term.h:479
std::string toString(bool nested=false)
Definition term.h:611
bool isString() const
Definition term.h:506
int m_line
Line num this term in the source code.
Definition term.h:1421
int m_col
Col num this term in the source code.
Definition term.h:1422
const std::string & getName() const
Definition term.h:395
InternalName m_normalized
Internal name of the object. Must be filled in after AST parsing.
Definition term.h:1448
bool isNamed() const
Definition term.h:515
void AppendLeft(TermPtr item)
Definition term.h:1206
Term(TermID id, const char *text, parser::token_type lex_type, size_t len, location *loc, std::shared_ptr< std::string > source=nullptr)
Definition term.h:356
TermPtr m_sys_prop
System parameters are not included in the argument list when called and are stored separately.
Definition term.h:1446
TermPtr m_dims
Dimension of a tensor.
Definition term.h:1433
std::string m_text
Text of the term.
Definition term.h:1430
void SetArgs(TermPtr args)
Definition term.h:1259
std::string & getText()
Definition term.h:407
bool isScalar() const
Definition term.h:497
bool isPure() const
Definition term.h:466
bool isRef()
Definition term.h:415
bool isBlock() const
Definition term.h:573
bool isReturn() const
Definition term.h:483
BlockType m_docs
Inline documentation for a term or block.
Definition term.h:1434
bool m_is_const
Immutability (non changeability) feature.
Definition term.h:1439
static TermPtr CreateName(std::string name, TermID id=TermID::NAME)
Definition term.cpp:44
static TermPtr CreateSymbol(char sym)
Definition term.h:339
bool isInterrupt() const
Definition term.h:423
TermPtr GetType()
Definition term.h:1398
TermPtr m_left
Left node of a linked list.
Definition term.h:1424
bool isCreateUse() const
Definition term.h:443
std::string & getName()
Definition term.h:399
SourceType m_source
Shared ptr source code.
Definition term.h:1420
bool is_variable_args()
Definition term.h:585
void AppendText(const std::string &s)
Definition term.h:1234
TermPtr End()
Definition term.h:1169
static TermPtr CreateDict()
Definition term.cpp:33
std::string asTypeString() const
Definition term.h:1371
bool isCalculated() const
Definition term.h:545
parser::token_type m_lexer_type
Internal data for macroprocessor.
Definition term.h:1452
bool isExport() const
Definition term.h:569
static TermPtr CreateNone()
Definition term.cpp:23
void Clear(bool clear_iterator_name)
Definition term.h:1319
BlockType m_macro_seq
Internal data for macroprocessor.
Definition term.h:1455
void SetName(std::string &name)
Definition term.h:403
void MakeRef(TermPtr ref)
Definition term.h:1364
BlockType m_attr
List of term attributes.
Definition term.h:1443
bool isLiteral() const
Definition term.h:529
bool isCreate() const
Definition term.h:452
TermPtr m_right
Right node of a linked list.
Definition term.h:1425
TermPtr First()
Definition term.h:1349
bool m_is_call
Call as function flag (brackets used )
Definition term.h:1440
void AppendRight(TermPtr item)
Definition term.h:1219
#define DEFINE_CASE(name)
int result
Definition lexer.l:367
#define LOG_RUNTIME(format,...)
Definition logger.h:26
#define SCOPE(scope)
Definition logger.h:38
#define LOG_DUMP(...)
Definition logger.h:118
#define ASSERT(condition)
Definition logger.h:60
#define LOG_ERROR(...)
Definition logger.h:122
#define LOG_ABORT(...)
Definition logger.h:124
Definition nlc.h:59
bool isConstName(const std::string_view name)
Definition types.h:1148
std::ostream & operator<<(std::ostream &out, newlang::TermPtr &var)
TermID
Definition term.h:119
std::string ParserMessage(std::string &buffer, int row, int col, const char *format,...)
Definition parser.cpp:525
std::shared_ptr< std::string > SourceType
Definition types.h:254
bool isLocalName(const std::string_view name)
Definition types.h:1074
newlang::ObjPtr clone(newlang::Context *ctx, newlang::Obj &in)
Definition builtin.cpp:39
std::shared_ptr< Term > TermPtr
Definition variable.h:33
size_t IndexArg(TermPtr term)
Definition term.cpp:6
bool isSystemName(const std::string_view name)
Definition types.h:1118
std::shared_ptr< RunTime > RuntimePtr
Definition types.h:242
std::vector< std::string > StringArray
Definition types.h:148
static bool IsAnyCreate(TermID id)
Definition term.h:146
bool isReservedName(const std::string_view name)
Definition types.h:1036
std::vector< TermPtr > BlockType
Definition types.h:239
const char * toString(TermID type)
Definition term.h:126
bool isDefaultType(const TermPtr &term)
Definition parser.cpp:1060
StorageTerm vars
Список имен переменных определеных для текущего уровня вложенности (блока кода)
Definition term.h:206
std::vector< std::string > ns_lookup
Список namespace для поиска простых имен
Definition term.h:208
TermPtr scope_name
Имя блока кода
Definition term.h:205
bool function_name
Имя блока кода, если это функция
Definition term.h:207
#define NL_TERMS(_)
Definition term.h:17
#define NL_PARSER(term, format,...)
Definition types.h:310