NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
macro.h
Go to the documentation of this file.
1#ifndef NEWLANG_MACRO_H_
2#define NEWLANG_MACRO_H_
3
4#include "term.h"
5
6#include "warning_push.h"
7#include "parser.yy.h"
8#include "warning_pop.h"
9
10namespace newlang {
11
12 class Macro : SCOPE(public) std::map<std::string, BlockType>, public std::enable_shared_from_this<Macro> {
13 public:
14
15 /*
16 * Макрос - в общем случае, это один или несколько терминов с префиксом макроса '\' или без префикса.
17 * Определение макроса - синтаксическая конструкция, которая содержит идентификатор макроса и его тело.
18 * Тело макроса - это последовательность произвольных лексических единиц или текстовая строка без разбивки на лексемы.
19 * Идентификатору макроса - один или несколько терминов подряд (терминами могут быть имя, макрос или шаблон подстановки).
20 * Макросы могут быть параметризированными за счет шаблонов подстановки и аргументов.
21 * Щаблоны подстановки и аргументы в идентификаторе макроса должны записываться с префиксом $ как имена локальных переменных.
22 * Щаблоны подстановки и аргументы в теле мароса должны записываться с префиксом \$.
23 * В идентификаторе макроса ургументы в скобках могут быть только у одного термина или шаблона подстановки.
24 *
25 * Сопоставление макросов просиходит по точному соотвествию идентификатора имени термина, а возможные аргументы скобках игнорируются.
26 * Идентификаторы макросов, состоящие только из шаблонов подстановок не допускаются.
27 * Идентификаторы макроса с аргументами и без аргументов считаются разными идентификаторами,
28 * поэтому для переименования всех возможных варинатов использования одного термина нужно определять
29 * сразу два макроса со скобкамии и без скобок.
30 * @ old @ new @; @ old(...) @ new(\$*) @;
31 * @replace($old, $new)@\ @ \$old @ \$new @; @ \$old(...)@ \$new(\$*)@ @\;
32 *
33 * Параметры макроса могут быль любыми последовательности терминов между скобками, которые разделяются запятыми.
34 * Вложенность скобок анализируется, и в качестве параметров макросов используется только верхний уровень вложенности.
35 *
36 * Контроль типов аргументов у макросов пока не реализован, т.к. перегрузка функция по типам аргументов
37 * в языке отсуствует и контроль типов аргументов выполняется интерпретатором (компилятором).
38 *
39 *
40 *
41 *
42
43 *
44 * Сложность парсинга макросов с такими начальными условиями заключается в том, что параметризированны макросы
45 * могут быть произвольной длинны, и их завершение можно определить по двум критериям:
46 * 1. Конец исходных данных (лексер вернул END)
47 * 2. Очередной термин не соответствует термину в идентификаторе макроса
48 *
49 * Из-за этого алгоритм анализа маросов выполняется следующим образом:
50 * - термины считываются из лексера пока не появится имя или макрос.
51 * - цикл по всем зарегистрированным макросам
52 * - чтение новых терминов из лексера, пока сопсотавление с идентификатором макроса не вернет равно/ложь/END
53 * - Если термин '(', то считываются термины до получения термина ')' с учетом их вложенности -> в начало.
54 * 4.
55 *
56 * 3. Ошибка в аргументах шаблона термина.
57 *
58 * Ошибка в аргументах шаблона термина могут быть следующего вида:
59 * - У входного термина есть й термин соотвестетствует шаблону и оба являются вызовами функций, но аргументы , а у
60 *
61 *
62 * Макросы раскрываются после лексера до передачи термина в парсер.
63 *
64 *
65 * Распознавание и раскрытие макросов происходит до
66 *
67 * Нужно ли различать термин с вызвовм и без вызова???? Скорее всего различать не требуется (все равно, есть скобки или нет),
68 * но если они нужны при раскрытии (например именованные аргументы, которые отсуствуют), то при раскрытии будет ошибка.
69 *
70 *
71 * \term name\ term_name\
72 * \term name()\ term_name\ # Ошибка, Два одинаковых имени макроса!
73 *
74 * \term($arg1) name($arg2)\ term_name($arg1)\
75 * term name("name") # Ошибка, $arg1 не определен?
76 *
77 *
78 * \term(...) name(...)\ term_name($term...)\
79 * term name("name") # Ошибка, $arg1 не определен?
80 */
81
82 /*
83 * Для быстрого отбора макросов для сравнения нужно учитывать индексацию доступа к элементам,
84 * но у multimap может быть несколько элементов, каждый из которых необходимо сравнивать индивидуально.
85 * А так как длина имен у макрососв может состоять сразу из нескольких терминов,
86 * то есть следующие варинаты поиска:
87 * 1. перебирать все существующие макросы и сравнивать последние термины в буфере
88 * (отступ от конца буфера будет зависеть от количества имен в идентификаторе макроса).
89 * Кол-во шагов перебора для поиска будет равно кол-ву определенных макросов,
90 * а сам поиск должен выполняться при добавлении каждого нового термина в буфер!!!!
91 * 2. Последовательность терминов в имени мароса сохнаять в обратном порядке (последний, предпоследний и т.д.),
92 * а поиск выполнять в multimap определнных буферов для каждого нового термина (при добавлении он становится последним).
93 * Поиск будет по индексу multimap, но с последнего термина имени (это нужно учитывать при возможных оптимизациях и вероятных ошибках)
94 * 3. Второй вариант лучше черм первый, но все равно может оказаться не очень удачным, так как человеку более привычно
95 * использовать ключевое слове первым, а при подобной индексации оно будет анализироваться последним.
96 * Возможно придется реализовывать какой нибудь вариант хеширования, чтобы индексировать поиск терминов.
97 *
98 * Какой бы алгоритм поиска не был выбран, пока это преждевременная оптимизация.
99 * Поэтому сейчас делаю полный перебор, а оптимизировать нужно будет потом.
100 *
101 */
102
103
104 Macro();
105
106 virtual ~Macro() {
107 }
108
109 static const std::string deny_chars_from_macro;
110
111 static std::string toMacroHash(TermPtr &term);
112
113 inline static std::string toMacroHashName(const std::string str) {
114 if (isLocalName(str)) {
115 return "$"; // Template
116 } else if (isMacroName(str)) {
117 return str.substr(1); // without macro prefix
118 }
119 return str;
120 }
121
122 std::string GetMacroMaping(const std::string str, const char *separator = ", ");
123
124 static BlockType GetMacroId(TermPtr &term);
125
126 // SCOPE(protected) :
127 static BlockType MakeMacroId(const BlockType &seq);
128
129
130 // void Push(const TermPtr term);
131 // void Pop(const TermPtr term);
132
133 // parser::token_type ExpandPredefMacro(TermPtr &term, Parser * parser);
134 //
135 // static int m_counter;
136 // std::map<std::string, std::string> m_predef_macro;
137 // bool RegisterPredefMacro(const char * name, const char * desc);
138
139
140
141
147 // static bool CheckOpMacros(const TermPtr & term);
148 //
149 // static TermPtr CreateMacroFromOp(const TermPtr & term);
150
151 // static bool CheckAndConvertMacros(TermPtr &term);
157 bool CheckMacro(const TermPtr & term);
158 bool RemoveMacro(TermPtr & term);
159
160 size_t GetCount() {
161 size_t count = 0;
162 auto iter = begin();
163 while (iter != end()) {
164 count += iter->second.size();
165 iter++;
166 }
167 return count;
168 }
169
170 // void Clear(size_t level);
171
172 TermPtr GetMacroById(const BlockType block);
173 TermPtr GetMacro(std::vector<std::string> list);
174 // bool isExist(const TermPtr & term);
175
185 // static bool IdentityAlias(BlockType &buffer, const TermPtr & term);
186 static bool IdentityMacro(const BlockType &buffer, TermPtr & term);
187 static bool CompareMacroName(const std::string & term_name, const std::string & macro_name);
188
192 typedef std::map<std::string, BlockType> MacroArgsType;
201 static size_t ExtractArgs(BlockType &buffer, TermPtr &term, MacroArgsType & args);
202 static void InsertArg_(MacroArgsType & args, std::string name, BlockType &buffer, size_t pos = static_cast<size_t> (-1));
203 static BlockType SymbolSeparateArg_(const BlockType &buffer, size_t pos, std::vector<std::string> name, std::string & error);
204
205 /*
206 * Раскрывает макрос в последовательность терминов лексера с заменой аргументов
207 */
208 static BlockType ExpandMacros(const TermPtr &macro, MacroArgsType & args);
209 /*
210 * Раскрывает макрос в текстовую строку с заменой аргументов
211 */
212 static std::string ExpandString(const TermPtr &macro, MacroArgsType & args);
213
214
215 std::string Dump();
216 static std::string Dump(const MacroArgsType & var);
217 static std::string Dump(const BlockType & arr);
218 static std::string DumpText(const BlockType & arr);
219
220
221 bool TestName(std::string_view name);
222
223 std::string CreateFullName(std::string_view name);
224 // std::string CreateFullName(TermPtr term) {
225 // ASSERT(term);
226 //
227 // return CreateFullName(term->m_text);
228 // }
229
239 bool RegisterProto(TermPtr term, bool gen_exception = true);
258 bool RegisterObj(TermPtr term, ObjPtr obj);
259
260 void ApplyDiags(DiagPtr diag) {
261 }
262
264
265
266 TermPtr FindTerm(std::string_view name);
267
268 inline TermPtr GetTerm(std::string_view name) {
269 TermPtr term = FindTerm(name);
270 if (!term) {
271
272 LOG_RUNTIME("Term '%s' not found!", name.begin());
273 }
274 return term;
275 }
276
277 ObjPtr FindObj(std::string_view name);
278
279 inline ObjPtr GetObj(std::string_view name) {
280 ObjPtr obj = FindObj(name);
281 if (!obj) {
282
283 LOG_RUNTIME("Object '%s' not found!", name.begin());
284 }
285 return obj;
286 }
287
288
289 // SCOPE(private) :
290 // MacroTokenType m_store;
291 };
292
293} // namespace example
294
295#endif // NEWLANG_MACRO_H_
DiagPtr m_diag
Definition macro.h:263
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
std::string CreateFullName(std::string_view name)
static void InsertArg_(MacroArgsType &args, std::string name, BlockType &buffer, size_t pos=static_cast< size_t >(-1))
Definition macro.cpp:802
ObjPtr GetObj(std::string_view name)
Definition macro.h:279
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
bool RegisterTerm(TermPtr term)
static const std::string deny_chars_from_macro
Definition macro.h:109
TermPtr GetMacro(std::vector< std::string > list)
Definition macro.cpp:1166
ObjPtr FindObj(std::string_view name)
static std::string toMacroHashName(const std::string str)
Definition macro.h:113
bool CheckMacro(const TermPtr &term)
Definition macro.cpp:266
TermPtr GetTerm(std::string_view name)
Definition macro.h:268
static std::string DumpText(const BlockType &arr)
Definition macro.cpp:590
bool RegisterObj(TermPtr term, ObjPtr obj)
size_t GetCount()
Definition macro.h:160
bool RegisterProto(TermPtr term, bool gen_exception=true)
virtual ~Macro()
Definition macro.h:106
static BlockType GetMacroId(TermPtr &term)
Definition macro.cpp:204
static bool IdentityMacro(const BlockType &buffer, TermPtr &term)
Definition macro.cpp:753
void ApplyDiags(DiagPtr diag)
Definition macro.h:260
bool TestName(std::string_view name)
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
#define LOG_RUNTIME(format,...)
Definition logger.h:26
#define SCOPE(scope)
Definition logger.h:38
Definition nlc.h:59
bool isLocalName(const std::string_view name)
Definition types.h:1074
std::shared_ptr< Term > TermPtr
Definition variable.h:33
std::shared_ptr< Obj > ObjPtr
Definition variable.h:28
std::vector< TermPtr > BlockType
Definition types.h:239
std::shared_ptr< Diag > DiagPtr
Definition types.h:243
bool isMacroName(const std::string_view name)
Definition types.h:1097