NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
ast_test.cpp
Go to the documentation of this file.
1#ifdef BUILD_UNITTEST
2
3#include "warning_push.h"
4#include <gtest/gtest.h>
5#include "warning_pop.h"
6
7
8#include "builtin.h"
9#include "runtime.h"
10#include "analysis.h"
11#include "jit.h"
12
13using namespace newlang;
14
15/* Проблема совместного использования namespace и декораторов имен.
16 *
17 * Дектораторы имен ($ и @) импользуютсядля указания области видимости и времени жизни объектов.
18 * $ - локальные объекты, размещаемые "условно" на стеке. Удаляются по мере выхода из текущей области видимости.
19 * Локальный объект скрывает другие локальные и глобальные объекты с таким же именем.
20 * @ - глобальные объекты, размещаемые "условно" в куче и их время жизни не зависит от текущей области видимости.
21 * Глобальный объект заменяет другой глобальный объект с таким же именем.
22 *
23 * Namespace позволяют использовать одинаковые имена объектов разделяя для них области видимости,
24 * но можно ли совместить и использовтаь namespace и дектораторы одновременно?
25 *
26 * $local; @global;
27 * $name::local; \\name::global;
28 * но ns {
29 * $name::local; # Будет $ns::name::local
30 * \\name::global; # Все равно \\name::global или тоже \\ns::name::global ????
31 * }
32 * тогда без указания области видимости (без начального символа "::", т.е. name::var - объект выбирается автоматически,
33 * т.е. сперва ищется локальный объект с таким именем, потом глобальный)
34 * Какая разница между ::name::var и name::var?
35 * Первый в глобальной области видимости, второй в текущей?
36 *
37 * $var := 0; # ::var или $var
38 * @func() := {0}; # ::func или @func - 0
39 * name {
40 * $var := 1; # ::name::var
41 * $func() := {11}; # локальная с именем - ::name::func
42 * @func() := {111}; # глобальная с именем - @func
43 * \\name::func() := {1111}; # глобальная \\name::func и тоже самое, что и локальная $func() !!!
44 * name {
45 * var := 2; # ::name::name::var или $var или \\name::name::var
46 * @var := 2; # ::var
47 * \\name::name::var := 2; # ::name::name::var или \\name::name::var
48 * func() := {2}; # ::name::name::func или \\name::name::func - 2
49 * name3 {
50 * var := 3; # ::name::name::name3::var или $name::name::name3::var - 3
51 * func() := {3}; # ::name::name::name3::func или \\name::name::name3::func() - 3
52 *
53 * var??; # name::name::name3::var или $name::name::name3::var - 3
54 * name::var??; # name::name::var или \\name::name::var - 2
55 * name::name::var??; # name::var или \\name::name::var - 2
56 * ::name::var??; # name::var или $name::var - 1
57 * ::var??; # ::var или $var - 0
58 * }
59 * }
60 * }
61 * Предположим, что: <<<<<<<<<<<<<<< НЕ АКТУАЛЬНО после изменения ситаксиса мароксов !!!!!!!!!!!!!!!!!!!!!!!!!! >>>>>>>>>>>
62 * :: - глобальный корень. Может быть заменен на @ или $
63 * @@ — родительская функция после её переопределния
64 * $$ — родительский объект
65 * тогда:
66 * $$.field - поле родительского класса
67 * @@() - вызов переопределенной функции текущего класса или области видимости
68 * @func() []= {@@() + 10}; # @func - 10
69 * ::name::name@func
70 * \\name::name::func - такая запись ненравится, но будет самой правильной и логичной, так как все остальные еще хуже для понимания и разбора
71 * @::name::name::func
72 * @::name::name@func
73 * ::name::name::func@@
74 *
75 * <<<<<<<<<<<<<<<<<< НОВАЯ КОНЦЕПЦИЯ >>>>>>>>>>>>>>>>>>
76 *
77 * Все объекты физически размещаюится в куче, но время их жизни определяется областью видимости.
78 * Объекты с декораторами $ обозначают локальные объекты (аналог "на стеке") и они удаляются по мере выхода из текущей области видимости.
79 * Объекты с декораторами @ являются модулями или его объектами, доступны из других частй программы и сохраняют состояние при выходе из текущей области видимости.
80 *
81 * Указание модуля (имя файла) @file или @dir.file или @dir1.dir2.file
82 * Указание объекта в модуле @file::var или @dir.file::ns::func() или @dir.file::ns::obj.field; @file::ns:type @file::ns$local ???
83 *
84 * Файл модуля загружается однократно при первом обращении и не выгружается до явной команды???
85 * @module <*>;
86 * @dir.module2 <*>; # Импорт всех функций модуля (кроме начинающихся на подчерк)
87 * @dir.module2 <ns::name::*>; # Импорт всех функций из указанной области имен (кроме начинающихся на подчерк)
88 * @dir.module2 <map=ns::name::*>; # Импорт всех функций из указанной области имен с переименованием (кроме начинающихся на подчерк)
89 * @dir.module2 <func1, func2=::module2::ns::name::func2>; # Импорт только конкретных функций + переименование
90 * @dir.module2 <_>; # Выгрузить модуль?????
91 *
92 * \\ns ::name::space::long@\
93 * \ns::name;
94 *
95 * @dsl{}; # Загрузка модуля с определниями макросов для DSL в самом начале любой программы?
96 *
97 * @@ - главный модуль
98 * @$ - текущий модуль
99 * $$ - родительский объект (базовый объект или переопределяемая функция)
100 * $0 - текущий объект (this)
101 *
102 * [@$.__main__] --> { # 1 или 0
103 *
104 * }
105 * @$.__@@__ := {}; # Деструктор модуля
106 * __@@__ := {}; # Деструктор модуля
107 *
108 * \destructor() { // _____ ::=
109 * }
110 *
111 *
112 * Дектораторы имен ($ и @) импользуютсядля указания области видимости и времени жизни объектов.
113 * $ - локальные объекты, размещаемые "условно" на стеке. Удаляются по мере выхода из текущей области видимости.
114 * Локальный объект скрывает другие локальные и глобальные объекты с таким же именем.
115 * @ - глобальные объекты, размещаемые "условно" в куче и их время жизни не зависит от текущей области видимости.
116 * Глобальный объект заменяет другой глобальный объект с таким же именем.
117 *
118 * Namespace позволяют использовать одинаковые имена объектов разделяя для них области видимости,
119 * но можно ли совместить и использовтаь namespace и дектораторы одновременно?
120 *
121 *
122 * Наследование
123 * Часто композиция класса более подходяща, чем наследование. Когда используйте наследование, делайте его открытым (public).
124 * Когда дочерний класс наследуется от базового, он включает определения всех данных и операций от базового. "Наследование интерфейса" - это наследование от чистого абстрактного базового класса (в нём не определены состояние или методы). Всё остальное - это "наследование реализации".
125 * Наследование реализации уменьшает размер кода благодаря повторному использованию частей базового класса (который становится частью нового класса). Т.к. наследование является декларацией времени компиляции, это позволяет компилятору понимать структуру и находить ошибки. Наследование интерфейса может быть использовано чтобы класс поддерживал требуемый API. И также, компилятор может находить ошибки, если класс не определяет требуемый метод наследуемого API.
126 * В случае наследования реализации, код начинает размазываться между базовым и дочерним классом и это может усложнить понимание кода. Также, дочерний класс не может переопределять код невиртуальных функций (не может менять их реализацию).
127 * Множественное наследование ещё более проблемное, а также иногда приводит к уменьшению производительности. Часто просадка производительности при переходе от одиночного наследования к множественному может быть больше, чем переход от обычных функций к виртуальным. Также от множественного наследования один шаг до ромбического, а это уже ведёт к неопределённости, путанице и, конечно же, багам.
128 * Любое наследование должно быть открытым (public). Если хочется сделать закрытое (private), то лучше добавить новый член с экземпляром базового класса.
129 * Не злоупотребляйте наследованием реализации. Композиция классов часто более предпочтительна. Попытайтесь ограничить использование наследования семантикой "Является": Bar можно наследовать от Foo, если можно сказать, что Bar "Является" Foo (т.е. там, где используется Foo, можно также использовать и Bar).
130 * Защищёнными (protected) делайте лишь те функции, которые должны быть доступны для дочерних классов. Заметьте, что данные должны быть закрытыми (private).
131 * Явно декларируйте переопределение виртуальных функций/деструктора с помошью спецификаторов: либо override, либо (если требуется) final. Не используйте спецификатор virtual при переопределении функций. Объяснение: функция или деструктор, помеченные override или final, но не являющиеся виртуальными просто не скомпилируются (что помогает обнаружить общие ошибки). Также спецификаторы работают как документация; а если спецификаторов нет, то программист будет вынужден проверить всю иерархию, чтобы уточнить виртуальность функции.
132 * Множественное наследование <интерфейсов> допустимо, однако множественное наследование реализации не рекомендуется от слова совсем.
133 *
134 * Для замены множественного наследования можно исопльзовать оператор утиной типизации (сравнения интерфейсов)
135 *
136 * Конструкторы и деструкторы классов
137 *
138 * Конструктор у класса может быть только один - и это обычная функция с именем класса.
139 * Конструктор должен вернуть созданный экземпляр класса, который ему передается в $0 аргументе.
140 * Другие аргументы соотетствуют передаваемым при вызове конструктора.
141 * Конструктор по умолчанию принимает произвольное количество аргументов (для переопределения значения у
142 * свойств по время вызова конструтокра) и возвращает аргумент $0, т.е. constructor(...) :- {$0($*)};
143 * Пользователський конструтор лучше переопреелять в теле класса через оператор присвоения значения,
144 * аналог override, т.е. constructor(...) **=** {...}; (чтобы исключить ошибки в написании имени функции).
145 * Конструторы базовых классов автоматически не вызываются, и если это требуется по логике работы,
146 * то вызовы конструторов базовых классов необходимо выполнять вручную, например так: $0 = $$.base_constructor();
147 *
148 * Деструктор класса определяется в теле класса анонимной функицей (имя функци подчерк),
149 * т.е. _() :- {} и по умолчанию отсутствует. Деструткоры базовых классов вызываются автоматически?????
150 *
151
152 - Расширен список имен базовых типов данных для более точного указания нативной функций С++ при её импорте.
153- Добавлен признак константности объекта (символ карет в конце имени), причем идентификатор константы частью имени не является.
154- Оператор добавления элемента в словарь или тензор "[]="
155- С помощью операторов добавления "[]=" и обращения к родительскому обекту "$$" реализована возможность перегрузки и отката перегрузки функции
156- Документирование свойств и методов ?????
157
158 *
159 */
160
161static TermPtr ParseString(const std::string str, MacroPtr macro = nullptr, PostLexerType *postlex = nullptr, DiagPtr diag = nullptr, RuntimePtr rt = nullptr) {
162 Parser p(macro, postlex, diag, true, rt.get());
163 return p.Parse(str);
164}
165
166TEST(Ast, Mangling) {
167 ASSERT_STREQ("name", ExtractName("name").c_str());
168 ASSERT_STREQ("name", ExtractName("::name").c_str());
169 ASSERT_STREQ("name", ExtractName("ns::name").c_str());
170 ASSERT_STREQ("", ExtractName("\\file").c_str());
171 ASSERT_STREQ("", ExtractName("\\\\dir.file").c_str());
172 ASSERT_STREQ("var", ExtractName("\\dir.file::var").c_str());
173 ASSERT_STREQ("var.field", ExtractName("\\\\dir.file::var.field").c_str());
174
175
176 ASSERT_STREQ("\\file", ExtractModuleName("\\file").c_str());
177 ASSERT_STREQ("\\\\dir.file", ExtractModuleName("\\\\dir.file").c_str());
178 ASSERT_STREQ("\\dir.file", ExtractModuleName("\\dir.file::var").c_str());
179 ASSERT_STREQ("\\\\dir.file", ExtractModuleName("\\\\dir.file::var.field").c_str());
180
181 ASSERT_STREQ("", ExtractModuleName("").c_str());
182 ASSERT_STREQ("", ExtractModuleName("_$$_").c_str());
183 ASSERT_STREQ("\\\\file", ExtractModuleName("_$file$_").c_str());
184 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file$dir$_").c_str());
185 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file$dir$_var$").c_str());
186 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file$dir$_var$$").c_str());
187 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file$dir$_var$$$").c_str());
188
189 ASSERT_STREQ("\\\\file_name\\dir", ExtractModuleName("_$file_name$dir$_").c_str());
190 ASSERT_STREQ("\\\\file_name\\dir", ExtractModuleName("_$file_name$dir$_var$").c_str());
191 ASSERT_STREQ("\\\\file_name\\dir", ExtractModuleName("_$file_name$dir$_var$$").c_str());
192 ASSERT_STREQ("\\\\file_name\\dir", ExtractModuleName("_$file_name$dir$_var$$$").c_str());
193}
194
195TEST(Ast, NameLookupStack) {
196
197 RunTime rt;
198
199 StorageTerm::ModuleMapType ext_storage;
200 NameLookupStack stack(rt, ext_storage);
201 ASSERT_EQ(0, stack.m_modules.size());
202 size_t glob_count = stack.m_glob.size();
203 ASSERT_TRUE(glob_count);
204
205 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", false).c_str());
206 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", true).c_str());
207 ASSERT_STREQ("name$", stack.MakeInternalName("name", false).c_str());
208 ASSERT_STREQ("name::", stack.MakeInternalName("name", true).c_str());
209 ASSERT_STREQ("name$", stack.MakeInternalName("$name", false).c_str());
210 ASSERT_STREQ("name$", stack.MakeInternalName("$name", true).c_str());
211 ASSERT_STREQ("name:::", stack.MakeInternalName(":name", false).c_str());
212 ASSERT_STREQ("name:::", stack.MakeInternalName(":name", true).c_str());
213 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", false).c_str());
214 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", true).c_str());
215 ASSERT_STREQ("name:::", stack.MakeInternalName("@:::name", false).c_str());
216 ASSERT_STREQ("name:::", stack.MakeInternalName("@:::name", true).c_str());
217
218 ASSERT_STREQ("Stack []: \n", stack.Dump().c_str());
219 stack.PushScope(nullptr);
220
221 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", false).c_str());
222 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", true).c_str());
223 ASSERT_STREQ("name$", stack.MakeInternalName("name", false).c_str());
224 ASSERT_STREQ("name::", stack.MakeInternalName("name", true).c_str());
225 ASSERT_STREQ("name$", stack.MakeInternalName("$name", false).c_str());
226 ASSERT_STREQ("name$", stack.MakeInternalName("$name", true).c_str());
227 ASSERT_STREQ("name:::", stack.MakeInternalName(":name", false).c_str());
228 ASSERT_STREQ("name:::", stack.MakeInternalName(":name", true).c_str());
229 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", false).c_str());
230 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", true).c_str());
231 ASSERT_STREQ("name:::", stack.MakeInternalName("@:::name", false).c_str());
232 ASSERT_STREQ("name:::", stack.MakeInternalName("@:::name", true).c_str());
233
234 stack.back().vars.insert({"name1", Term::Create(TermID::NAME, "term_name1", parser::token_type::NAME)});
235 stack.back().vars.insert({"name2", Term::Create(TermID::NAME, "term_name2", parser::token_type::NAME)});
236
237 stack.PushScope(Term::Create(TermID::NAME, "ns", parser::token_type::NAME));
238 stack.back().vars.insert({"name3", Term::Create(TermID::NAME, "term_name3", parser::token_type::NAME)});
239
240 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", false).c_str());
241 ASSERT_STREQ("::name::", stack.MakeInternalName("::name", true).c_str());
242 ASSERT_STREQ("name$", stack.MakeInternalName("name", false).c_str());
243 ASSERT_STREQ("ns::name::", stack.MakeInternalName("name", true).c_str());
244 ASSERT_STREQ("name$", stack.MakeInternalName("$name", false).c_str());
245 ASSERT_STREQ("ns::name$", stack.MakeInternalName("$name", true).c_str());
246 ASSERT_STREQ("ns::name:::", stack.MakeInternalName(":name", false).c_str());
247 ASSERT_STREQ("ns::name:::", stack.MakeInternalName(":name", true).c_str());
248 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", false).c_str());
249 ASSERT_STREQ("::name:::", stack.MakeInternalName(":::name", true).c_str());
250 ASSERT_STREQ("ns::name:::", stack.MakeInternalName("@:::name", false).c_str());
251 ASSERT_STREQ("ns::name:::", stack.MakeInternalName("@:::name", true).c_str());
252
253
254 // ext_storage.insert({"name4", Term::Create(TermID::NAME, "term_name4", parser::token_type::NAME)});
255 // ext_storage.insert({"name5", Term::Create(TermID::NAME, "term_name5", parser::token_type::NAME)});
256
257 ASSERT_STREQ("Stack []: \nStack [1::]: name1, name2\nStack [ns::]: name3\n", stack.Dump().c_str());
258 ext_storage.clear();
259 stack.clear();
260
261 // ...
262 ASSERT_EQ(1, stack.size());
263 ASSERT_STREQ("", stack.GetNamespace().c_str());
264
265 ASSERT_FALSE(stack.LookupName("name1"));
266 ASSERT_FALSE(stack.LookupName("$name1"));
267 ASSERT_FALSE(stack.LookupName("::name1"));
268
269 TermPtr name1 = Term::Create(TermID::NAME, "name1", parser::token_type::NAME);
270 TermPtr name1_orig = name1;
271 ASSERT_EQ(0, stack.front().vars.size()) << stack.Dump();
272 // ASSERT_TRUE(stack.front().vars.find("$name1") == stack.front().vars.end()) << stack.Dump();
273
274 name1->m_normalized = stack.MakeInternalName(name1->m_text, false);
275 ASSERT_STREQ("name1$", name1->m_normalized.c_str());
276
277 ASSERT_TRUE(stack.size()) << stack.Dump();
278 ASSERT_TRUE(!stack.empty()) << stack.Dump();
279 ASSERT_TRUE(stack.AddName(name1)) << stack.Dump();
280
281 ASSERT_EQ(1, stack.size()) << stack.Dump();
282 ASSERT_EQ(1, stack.front().vars.size()) << stack.Dump();
283 // ASSERT_TRUE(stack.front().vars.find("name1$") != stack.front().vars.end()) << stack.Dump();
284
285 ASSERT_STREQ("name1$", name1->m_normalized.c_str());
286 TermPtr temp1;
287 ASSERT_TRUE(temp1 = stack.LookupName("name1")) << stack.Dump();
288 ASSERT_EQ(temp1.get(), name1.get());
289 ASSERT_TRUE(temp1 = stack.LookupName("$name1")) << stack.Dump();
290 ASSERT_EQ(temp1.get(), name1.get());
291 ASSERT_FALSE(stack.LookupName("::name1")) << stack.Dump();
292
293 // name { ... }
294 stack.PushScope(Term::Create(TermID::NAMESPACE, "name", parser::token_type::NAMESPACE));
295 ASSERT_EQ(2, stack.size());
296 ASSERT_STREQ("name::", stack.GetNamespace().c_str());
297
298
299 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
300 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
301 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
302 ASSERT_STREQ("name::name1:::", stack.MakeInternalName(":name1", false).c_str());
303
304
305 TermPtr name2 = Term::Create(TermID::NAME, "name2", parser::token_type::NAME);
306 ASSERT_EQ(2, stack.size()) << stack.Dump();
307 ASSERT_EQ(0, ext_storage.size()) << stack.Dump();
308 ASSERT_EQ(0, stack[1].vars.size()) << stack.Dump();
309
310 name2->m_normalized = stack.MakeInternalName(name2->m_text, false);
311 ASSERT_FALSE(stack.LookupName("name2")) << stack.Dump();
312 ASSERT_TRUE(stack.AddName(name2)) << stack.Dump();
313
314 ASSERT_EQ(1, stack[1].vars.size()) << stack.Dump();
315 ASSERT_TRUE(stack.LookupName("name2")) << stack.Dump();
316
317 ASSERT_STREQ("name2", name2->m_text.c_str());
318 TermPtr temp2;
319 ASSERT_TRUE(temp2 = stack.LookupName("name2")) << stack.Dump();
320 ASSERT_EQ(temp2.get(), name2.get());
321 ASSERT_TRUE(temp2 = stack.LookupName("$name2")) << stack.Dump();
322 ASSERT_EQ(temp2.get(), name2.get());
323 ASSERT_FALSE(stack.LookupName("::name2")) << stack.Dump();
324
325 TermPtr temp;
326 ASSERT_TRUE(temp = stack.LookupName("name1")) << stack.Dump();
327 ASSERT_EQ(temp.get(), name1.get());
328 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
329 ASSERT_EQ(temp.get(), name1.get());
330
331
332 // name { {...} }
333 stack.PushScope(nullptr);
334 ASSERT_EQ(3, stack.size());
335
336 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
337 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
338 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
339 ASSERT_STREQ("name::name1:::", stack.MakeInternalName(":name1", false).c_str());
340
341 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", true).c_str());
342 ASSERT_STREQ("name::name1::", stack.MakeInternalName("name1", true).c_str());
343 ASSERT_STREQ("name::name1$", stack.MakeInternalName("$name1", true).c_str());
344 ASSERT_STREQ("name::name1:::", stack.MakeInternalName(":name1", true).c_str());
345
346 TermPtr name3 = Term::Create(TermID::NAME, "$name3", parser::token_type::NAME);
347 ASSERT_EQ(3, stack.size()) << stack.Dump();
348 ASSERT_EQ(0, ext_storage.size()) << stack.Dump();
349 ASSERT_EQ(0, stack[2].vars.size()) << stack.Dump();
350
351 name3->m_normalized = stack.MakeInternalName(name3->m_text, false);
352 ASSERT_TRUE(stack.AddName(name3)) << stack.Dump();
353
354 ASSERT_EQ(1, stack[2].vars.size()) << stack.Dump();
355 ASSERT_STREQ("$name3", name3->m_text.c_str());
356
357 TermPtr temp3;
358 ASSERT_TRUE(temp3 = stack.LookupName("name3")) << stack.Dump();
359 ASSERT_EQ(temp3.get(), name3.get());
360 ASSERT_TRUE(temp3 = stack.LookupName("$name3")) << stack.Dump();
361 ASSERT_EQ(temp3.get(), name3.get());
362 ASSERT_FALSE(stack.LookupName("::name3")) << stack.Dump();
363
364 ASSERT_EQ(name1.get(), name1_orig.get());
365 ASSERT_TRUE(temp = stack.LookupName("name1")) << stack.Dump();
366 ASSERT_EQ(temp.get(), name1.get());
367 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
368 ASSERT_EQ(temp.get(), name1.get());
369
370 ASSERT_TRUE(temp = stack.LookupName("name2")) << stack.Dump();
371 ASSERT_EQ(temp.get(), name2.get());
372 ASSERT_TRUE(temp = stack.LookupName("$name2")) << stack.Dump();
373 ASSERT_EQ(temp.get(), name2.get());
374
375
376 // name { { name2 {...} } }
377 stack.PushScope(Term::Create(TermID::NAMESPACE, "name2", parser::token_type::NAMESPACE));
378 ASSERT_EQ(4, stack.size());
379 ASSERT_STREQ("name::name2::", stack.GetNamespace().c_str());
380
381 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
382 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
383 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
384 ASSERT_STREQ("name::name2::name1:::", stack.MakeInternalName(":name1", false).c_str());
385
386 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", true).c_str());
387 ASSERT_STREQ("name::name2::name1::", stack.MakeInternalName("name1", true).c_str());
388 ASSERT_STREQ("name::name2::name1$", stack.MakeInternalName("$name1", true).c_str());
389 ASSERT_STREQ("name::name2::name1:::", stack.MakeInternalName(":name1", true).c_str());
390
391
392 TermPtr name4 = Term::Create(TermID::NAME, "name4", parser::token_type::NAME);
393 ASSERT_EQ(4, stack.size()) << stack.Dump();
394 ASSERT_EQ(0, stack[3].vars.size()) << stack.Dump();
395 ASSERT_TRUE(stack[3].vars.find("$name4") == stack[3].vars.end()) << stack.Dump();
396 ASSERT_EQ(0, ext_storage.size()) << stack.Dump();
397
398 name4->m_normalized = stack.MakeInternalName(name4->m_text, false);
399 ASSERT_STREQ("name4$", name4->m_normalized.c_str());
400 ASSERT_TRUE(stack.AddName(name4)) << stack.Dump();
401
402 ASSERT_EQ(1, stack[3].vars.size()) << stack.Dump();
403
404 ASSERT_TRUE(temp = stack.LookupName("name4")) << stack.Dump();
405 ASSERT_EQ(temp.get(), name4.get()) << stack.Dump();
406 ASSERT_TRUE(temp = stack.LookupName("$name4")) << stack.Dump();
407 ASSERT_EQ(temp.get(), name4.get()) << stack.Dump();
408
409 ASSERT_EQ(name1.get(), name1_orig.get());
410 ASSERT_TRUE(temp = stack.LookupName("name1")) << stack.Dump();
411 ASSERT_EQ(temp.get(), name1.get()) << stack.Dump();
412 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
413 ASSERT_EQ(temp.get(), name1.get()) << stack.Dump();
414
415 ASSERT_TRUE(temp = stack.LookupName("name2")) << stack.Dump();
416 ASSERT_EQ(temp.get(), name2.get()) << temp->toString() << " " << name2->toString() << " " << stack.Dump();
417 ASSERT_TRUE(temp = stack.LookupName("$name2")) << stack.Dump();
418 ASSERT_EQ(temp.get(), name2.get()) << stack.Dump();
419
420 ASSERT_TRUE(temp = stack.LookupName("name3")) << stack.Dump();
421 ASSERT_EQ(temp.get(), name3.get()) << stack.Dump();
422 ASSERT_TRUE(temp = stack.LookupName("$name3")) << stack.Dump();
423 ASSERT_EQ(temp.get(), name3.get()) << stack.Dump();
424
425 ASSERT_EQ(name1.get(), name1_orig.get());
426 ASSERT_TRUE(temp = stack.LookupName("name1")) << stack.Dump();
427 ASSERT_EQ(temp.get(), name1.get()) << temp->toString();
428 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
429 ASSERT_EQ(temp.get(), name1.get()) << temp->toString();
430
431
432 // name { { name2 { name3::name4 {...} } } }
433 stack.PushScope(Term::Create(TermID::NAMESPACE, "name3::name4", parser::token_type::NAMESPACE));
434 ASSERT_EQ(5, stack.size());
435 ASSERT_STREQ("name::name2::name3::name4::", stack.GetNamespace().c_str());
436
437 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
438 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
439 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
440 ASSERT_STREQ("name::name2::name3::name4::name1:::", stack.MakeInternalName(":name1", false).c_str());
441
442 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", true).c_str());
443 ASSERT_STREQ("name::name2::name3::name4::name1::", stack.MakeInternalName("name1", true).c_str());
444 ASSERT_STREQ("name::name2::name3::name4::name1$", stack.MakeInternalName("$name1", true).c_str());
445 ASSERT_STREQ("name::name2::name3::name4::name1:::", stack.MakeInternalName(":name1", true).c_str());
446
447 // name { { name2 { name3::name4 { ::{...} } } } }
448 stack.PushScope(Term::Create(TermID::NAMESPACE, "::", parser::token_type::NAMESPACE));
449 ASSERT_EQ(6, stack.size());
450 ASSERT_STREQ("::", stack.GetNamespace().c_str());
451 // ASSERT_STREQ("::name", ns_stack.GetFullName("name").c_str());
452
453 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
454 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
455 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
456 ASSERT_STREQ("::name1:::", stack.MakeInternalName(":name1", false).c_str());
457
458 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", true).c_str());
459 ASSERT_STREQ("::name1::", stack.MakeInternalName("name1", true).c_str());
460 ASSERT_STREQ("::name1$", stack.MakeInternalName("$name1", true).c_str());
461 ASSERT_STREQ("::name1:::", stack.MakeInternalName(":name1", true).c_str());
462
463 // name { { name2 { name3::name4 { ::{ {...} } } } } }
464 stack.PushScope(nullptr);
465 ASSERT_EQ(7, stack.size());
466
467 ASSERT_STREQ("::", stack.GetNamespace().c_str());
468
469 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", false).c_str());
470 ASSERT_STREQ("name1$", stack.MakeInternalName("name1", false).c_str());
471 ASSERT_STREQ("name1$", stack.MakeInternalName("$name1", false).c_str());
472 ASSERT_STREQ("::name1:::", stack.MakeInternalName(":name1", false).c_str());
473
474 ASSERT_STREQ("::name1::", stack.MakeInternalName("::name1", true).c_str());
475 ASSERT_STREQ("::name1::", stack.MakeInternalName("name1", true).c_str());
476 ASSERT_STREQ("::name1$", stack.MakeInternalName("$name1", true).c_str());
477 ASSERT_STREQ("::name1:::", stack.MakeInternalName(":name1", true).c_str());
478
479 ASSERT_EQ(name1.get(), name1_orig.get());
480 ASSERT_TRUE((temp = stack.LookupName("name1"))) << stack.Dump();
481 ASSERT_EQ(name1.get(), name1_orig.get()) << name1->toString() << " " << name1_orig->toString();
482 EXPECT_EQ(temp.get(), name1.get()) << temp->toString() << " " << name1->toString();
483 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
484 EXPECT_EQ(temp.get(), name1.get()) << temp->toString() << " " << name1->toString();
485
486
487 TermPtr name_g = Term::Create(TermID::NAME, "@::name_g", parser::token_type::NAME);
488 ASSERT_EQ(7, stack.size()) << stack.Dump();
489 ASSERT_EQ(0, ext_storage.size()) << stack.Dump();
490
491 name_g->m_normalized = stack.MakeInternalName(name_g->m_text, false);
492 ASSERT_TRUE(stack.AddName(name_g)) << stack.Dump();
493
494 ASSERT_TRUE(temp = stack.LookupName("name_g")) << stack.Dump();
495 ASSERT_EQ(temp.get(), name_g.get()) << temp->toString();
496 ASSERT_FALSE(temp = stack.LookupName("$name_g")) << stack.Dump();
497 ASSERT_TRUE(stack.LookupName("::name_g")) << stack.Dump();
498 ASSERT_TRUE(temp = stack.LookupName("@::name_g")) << stack.Dump();
499 ASSERT_EQ(temp.get(), name_g.get()) << temp->toString();
500
501 ASSERT_EQ(name1.get(), name1_orig.get());
502 ASSERT_TRUE(temp = stack.LookupName("name1")) << stack.Dump();
503 EXPECT_EQ(temp.get(), name1.get()) << temp->toString() << " " << name1->toString();
504 ASSERT_TRUE(temp = stack.LookupName("$name1")) << stack.Dump();
505 EXPECT_EQ(temp.get(), name1.get()) << temp->toString() << " " << name1->toString();
506
507 ASSERT_TRUE(temp = stack.LookupName("name2")) << stack.Dump();
508 EXPECT_EQ(temp.get(), name2.get()) << temp->toString() << " " << name2->toString();
509 ASSERT_TRUE(temp = stack.LookupName("$name2")) << stack.Dump();
510 EXPECT_EQ(temp.get(), name2.get()) << temp->toString() << " " << name2->toString();
511
512 ASSERT_TRUE(temp = stack.LookupName("name3")) << stack.Dump();
513 EXPECT_EQ(temp.get(), name3.get()) << temp->toString() << " " << name3->toString();
514 ASSERT_TRUE(temp = stack.LookupName("$name3")) << stack.Dump();
515 EXPECT_EQ(temp.get(), name3.get()) << temp->toString() << " " << name3->toString();
516
517 ASSERT_TRUE(temp = stack.LookupName("name_g")) << stack.Dump();
518 ASSERT_EQ(temp.get(), name_g.get()) << temp->toString();
519 ASSERT_FALSE(temp = stack.LookupName("$name_g")) << stack.Dump();
520 ASSERT_TRUE(temp = stack.LookupName("::name_g")) << stack.Dump();
521 ASSERT_TRUE(temp = stack.LookupName("@::name_g")) << stack.Dump();
522 ASSERT_EQ(temp.get(), name_g.get()) << temp->toString();
523
524
525
526
527
528 // name { { name2 { name3::name4 { ::{ { ::name5::name6 {...} } } } } } }
529 stack.PushScope(Term::Create(TermID::NAMESPACE, "::name5::name6", parser::token_type::NAMESPACE));
530 ASSERT_EQ(8, stack.size()) << stack.Dump();
531 ASSERT_STREQ("::name5::name6::", stack.GetNamespace().c_str());
532
533 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ::{ ... } } } } } } } }
534 stack.PushScope(Term::Create(TermID::NAMESPACE, "::", parser::token_type::NAMESPACE));
535 ASSERT_STREQ("::", stack.GetNamespace().c_str());
536
537 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ::{ name7 {...} } } } } } } } }
538 stack.PushScope(Term::Create(TermID::NAMESPACE, "name7", parser::token_type::NAMESPACE));
539 ASSERT_EQ(10, stack.size()) << stack.Dump();
540 ASSERT_STREQ("::name7::", stack.GetNamespace().c_str());
541
542 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ... } } } } } } }
543 stack.PopScope();
544 stack.PopScope();
545 ASSERT_EQ(8, stack.size()) << stack.Dump();
546 ASSERT_STREQ("::name5::name6::", stack.GetNamespace().c_str());
547
548 // name { { name2 { name3::name4 { ::{ { ... } } } } } }
549 stack.PopScope();
550 ASSERT_EQ(7, stack.size()) << stack.Dump();
551 ASSERT_STREQ("::", stack.GetNamespace().c_str()) << stack.Dump();
552
553 // name { { name2 { name3::name4 { ::{ ... } } } } }
554 stack.PopScope();
555 ASSERT_EQ(6, stack.size()) << stack.Dump();
556 ASSERT_STREQ("::", stack.GetNamespace().c_str()) << stack.Dump();
557
558 // name { { name2 { name3::name4 { ... } } } }
559 stack.PopScope();
560 ASSERT_EQ(5, stack.size()) << stack.Dump();
561 ASSERT_STREQ("name::name2::name3::name4::", stack.GetNamespace().c_str());
562
563 // name { { name2 { ... } } }
564 stack.PopScope();
565 ASSERT_EQ(4, stack.size()) << stack.Dump();
566 ASSERT_STREQ("name::name2::", stack.GetNamespace().c_str());
567
568 // name { { ... } }
569 stack.PopScope();
570 ASSERT_EQ(3, stack.size()) << stack.Dump();
571 ASSERT_STREQ("name::", stack.GetNamespace().c_str());
572
573
574 // name { ... }
575 stack.PopScope();
576 ASSERT_EQ(2, stack.size()) << stack.Dump();
577 ASSERT_STREQ("name::", stack.GetNamespace().c_str());
578
579 // -
580 stack.PopScope();
581 ASSERT_EQ(1, stack.size()) << stack.Dump();
582 ASSERT_STREQ("", stack.GetNamespace().c_str());
583
584 // ns::name { ... }
585 stack.PushScope(Term::Create(TermID::NAMESPACE, "ns::name", parser::token_type::NAMESPACE));
586 ASSERT_EQ(2, stack.size()) << stack.Dump();
587 ASSERT_STREQ("ns::name::", stack.GetNamespace().c_str());
588
589
590 // ns::name { ::{ ... } }
591 stack.PushScope(Term::Create(TermID::NAMESPACE, "::", parser::token_type::NAMESPACE));
592 ASSERT_EQ(3, stack.size()) << stack.Dump();
593 ASSERT_STREQ("::", stack.GetNamespace().c_str());
594
595 // ns::name { ... }
596 stack.PopScope();
597 // ...
598 stack.PopScope();
599 ASSERT_EQ(1, stack.size()) << stack.Dump();
600
601}
602
603TEST(Ast, AstAnalyze) {
604
605 JIT * jit = JIT::ReCreate();
606
608 NameLookupStack stack(*jit, external);
609
610 AstAnalysis analysis(*jit, jit->m_diag.get());
611
612 TermPtr ast = jit->GetParser()->Parse("var1 ::= '1';");
613
614 ASSERT_EQ(1, stack.size());
615 ASSERT_EQ(0, stack[0].vars.size());
616 ASSERT_TRUE(ast);
617 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
618 ASSERT_EQ(1, stack.size());
619 ASSERT_EQ(1, stack[0].vars.size()) << stack.Dump();
620 ASSERT_TRUE(stack.LookupName("var1$")) << stack.Dump();
621 ASSERT_STREQ("var1", stack.LookupName("var1$")->m_text.c_str());
622 ASSERT_STREQ("var1$", stack.LookupName("var1$")->m_normalized.c_str());
623
624 ast = jit->GetParser()->Parse("$var2 ::= '1';$var3 ::= '1';");
625
626 ASSERT_TRUE(ast);
627 ASSERT_TRUE(analysis.Analyze(ast, &stack));
628 ASSERT_EQ(1, stack.size());
629 ASSERT_EQ(3, stack[0].vars.size()) << stack.Dump();
630 ASSERT_TRUE(stack.LookupName("var2$")) << stack.Dump();
631 ASSERT_TRUE(stack.LookupName("var3$")) << stack.Dump();
632 ASSERT_STREQ("$var2", stack.LookupName("var2$")->m_text.c_str());
633 ASSERT_STREQ("$var3", stack.LookupName("var3$")->m_text.c_str());
634 ASSERT_STREQ("var2$", stack.LookupName("var2$")->m_normalized.c_str());
635 ASSERT_STREQ("var3$", stack.LookupName("var3$")->m_normalized.c_str());
636
637 ast = jit->GetParser()->Parse("$var ::= '1'; $var = '2';");
638
639 ASSERT_TRUE(ast);
640 ASSERT_TRUE(analysis.Analyze(ast, &stack));
641 ASSERT_EQ(1, stack.size());
642 ASSERT_EQ(4, stack[0].vars.size()) << stack.Dump();
643 ASSERT_TRUE(stack.LookupName("var$")) << stack.Dump();
644 ASSERT_STREQ("$var", stack.LookupName("var$")->m_text.c_str());
645 ASSERT_STREQ("var$", stack.LookupName("var$")->m_normalized.c_str());
646
647
648 ast = jit->GetParser()->Parse("$fail = '1'");
649 ASSERT_TRUE(ast);
650 ASSERT_FALSE(analysis.Analyze(ast, &stack)); // Local name '$fail' not found!
651
652 ast = jit->GetParser()->Parse("$var ::= '1'"); // A new variable is always created
653 ASSERT_TRUE(ast);
654 ASSERT_FALSE(analysis.Analyze(ast, &stack)); // Local name '$var' already exist!
655
656 ast = jit->GetParser()->Parse("$var := '1'"); // Create new or use exist variable
657 ASSERT_TRUE(ast);
658 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump("*var*");
659
660
661 ast = jit->GetParser()->Parse("$var = 'строка'; $var = 2;");
662 ASSERT_TRUE(ast);
663 ASSERT_EQ(2, ast->m_block.size());
664 ASSERT_STREQ("=", ast->m_block[0]->m_text.c_str());
665 ASSERT_TRUE(ast->m_block[0]->m_left);
666 ASSERT_STREQ("$var", ast->m_block[0]->m_left->m_text.c_str());
667 ASSERT_FALSE(ast->m_block[0]->m_left->m_type);
668 ASSERT_TRUE(ast->m_block[0]->m_right);
669 ASSERT_STREQ("строка", ast->m_block[0]->m_right->m_text.c_str());
670 ASSERT_TRUE(ast->m_block[0]->m_right->m_type);
671 ASSERT_STREQ(":StrChar", ast->m_block[0]->m_right->m_type->asTypeString().c_str());
672
673 ASSERT_STREQ("=", ast->m_block[1]->m_text.c_str());
674 ASSERT_TRUE(ast->m_block[1]->m_left);
675 ASSERT_STREQ("$var", ast->m_block[1]->m_left->m_text.c_str());
676 ASSERT_FALSE(ast->m_block[1]->m_left->m_type);
677 ASSERT_TRUE(ast->m_block[1]->m_right);
678 ASSERT_STREQ("2", ast->m_block[1]->m_right->m_text.c_str());
679 ASSERT_TRUE(ast->m_block[1]->m_right->m_type);
680 ASSERT_STREQ(":Int8", ast->m_block[1]->m_right->m_type->asTypeString().c_str());
681
682 ASSERT_FALSE(analysis.Analyze(ast, &stack));
683
684 ast = jit->GetParser()->Parse("$int ::= 2; $int = '';");
685 ASSERT_TRUE(ast);
686 ASSERT_FALSE(analysis.Analyze(ast, &stack));
687
688 ast = jit->GetParser()->Parse("$var4 ::= 2; $var4 = 2222;");
689 ASSERT_TRUE(ast);
690 ASSERT_TRUE(analysis.Analyze(ast, &stack));
691 ASSERT_TRUE(stack.LookupName("var4$")) << stack.Dump();
692 ASSERT_STREQ(":Int16", stack.LookupName("var4$")->GetType()->asTypeString().c_str());
693
694 ast = jit->GetParser()->Parse("$var5:Int8 := 2; $var5 = 2222;");
695 ASSERT_TRUE(ast);
696 ASSERT_FALSE(analysis.Analyze(ast, &stack));
697
698
699 ast = jit->GetParser()->Parse("$var32 := 2; $var32 = 22222222;");
700 ASSERT_TRUE(ast);
701 ASSERT_TRUE(analysis.Analyze(ast, &stack));
702 ASSERT_TRUE(stack.LookupName("var32$")) << stack.Dump();
703 ASSERT_STREQ(":Int32", stack.LookupName("var32$")->GetType()->asTypeString().c_str());
704
705 ast = jit->GetParser()->Parse("$var64 := 2; $var64 = 2222222222222;");
706 ASSERT_TRUE(ast);
707 ASSERT_TRUE(analysis.Analyze(ast, &stack));
708 ASSERT_TRUE(stack.LookupName("var64$")) << stack.Dump();
709 ASSERT_STREQ(":Int64", stack.LookupName("var64$")->GetType()->asTypeString().c_str());
710
711 ast = jit->GetParser()->Parse("varf := 2; varf = 2.0;");
712 ASSERT_TRUE(ast);
713 ASSERT_TRUE(analysis.Analyze(ast, &stack));
714 ASSERT_TRUE(stack.LookupName("varf$")) << stack.Dump();
715 ASSERT_STREQ(":Float32", stack.LookupName("varf$")->GetType()->asTypeString().c_str());
716
717}
718
719TEST(Ast, AstArgs) {
720
721 JIT * jit = JIT::ReCreate();
722
723 AstAnalysis analysis(*jit, jit->m_diag.get());
724
726 NameLookupStack stack(*jit, external);
727
728 TermPtr ast = jit->GetParser()->Parse("dict := (1,2,); dict[1];");
729
730 ASSERT_TRUE(ast);
731 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
732 ASSERT_EQ(1, stack.size());
733 ASSERT_TRUE(stack.LookupName("dict$")) << stack.Dump();
734 ASSERT_STREQ("dict", stack.LookupName("dict$")->m_text.c_str());
735 ASSERT_STREQ("dict$", stack.LookupName("dict$")->m_normalized.c_str());
736
737 ast = jit->GetParser()->Parse("dict = (1,2,); (dict[1], dict[2],);");
738
739 ASSERT_TRUE(ast);
740 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
741 ASSERT_EQ(1, stack.size());
742 ASSERT_TRUE(stack.LookupName("dict$")) << stack.Dump();
743 ASSERT_STREQ("dict", stack.LookupName("dict$")->m_text.c_str());
744 ASSERT_STREQ("dict$", stack.LookupName("dict$")->m_normalized.c_str());
745
746
747 ast = jit->GetParser()->Parse("recursive(arg^) ::= { recursive(arg) };");
748
749 ASSERT_TRUE(ast);
750 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
751 ASSERT_EQ(1, stack.size());
752 ASSERT_TRUE(stack.LookupName("recursive::")) << stack.Dump();
753 ASSERT_STREQ("recursive::", stack.LookupName("recursive")->m_text.c_str());
754 ASSERT_STREQ("recursive::", stack.LookupName("recursive")->m_normalized.c_str());
755 // std::cout << ast->toString() << "\n";
756
757 ast = jit->GetParser()->Parse("recursive2(&arg) ::= { recursive2(arg) };");
758
759 ASSERT_TRUE(ast);
760 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
761 ASSERT_EQ(1, stack.size());
762 ASSERT_TRUE(stack.LookupName("recursive2::")) << stack.Dump();
763 ASSERT_STREQ("recursive2::", stack.LookupName("recursive2")->m_text.c_str());
764 ASSERT_STREQ("recursive2::", stack.LookupName("recursive2::")->m_normalized.c_str());
765 // std::cout << ast->toString() << "\n";
766
767}
768
769TEST(Ast, Reference) {
770
771 JIT * jit = JIT::ReCreate();
772
773 AstAnalysis analysis(*jit, jit->m_diag.get());
774
776 NameLookupStack stack(*jit, external);
777
778 TermPtr ast = jit->GetParser()->Parse("{noref ::= 1;}");
779
780 ASSERT_TRUE(ast);
781 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
782
783
784 // Нельзя создавать ссылки
785 ast = jit->GetParser()->Parse("{noref ::= 1; ref := &noref;}");
786 ASSERT_TRUE(ast);
787 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
788
789 ast = jit->GetParser()->Parse("{noref ::= 1; ref := &&noref;}");
790 ASSERT_TRUE(ast);
791 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
792
793 ast = jit->GetParser()->Parse("{noref ::= 1; ref := &*noref;}");
794 ASSERT_TRUE(ast);
795 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
796
797
798 // Нельзя копировать владельцев на одном уровне
799 ast = jit->GetParser()->Parse(" { val ::= 1; $local := val; } ");
800 ASSERT_TRUE(ast);
801 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
802
803
804 // Можно копировать в локальные на уровень ниже
805 ast = jit->GetParser()->Parse("{ val ::= 1; { $local := val; } }");
806 ASSERT_TRUE(ast);
807 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
808
809 ast = jit->GetParser()->Parse("{ $val ::= 1; { $local := val; } }");
810 ASSERT_TRUE(ast);
811 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
812
813 // Нельзя копировать владельцев в статические переменные
814 ast = jit->GetParser()->Parse("{val ::= 1; { ::local := val; } }");
815 ASSERT_TRUE(ast);
816 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
817
818 // Можно скопировать значение
819 ast = jit->GetParser()->Parse("{val ::= 1; ::val2 := *val;}");
820 ASSERT_TRUE(ast);
821 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
822
823
824 // Можно создавать только правильные ссылки
825 ast = jit->GetParser()->Parse("{&ref ::= 1; test := &ref;}");
826 ASSERT_TRUE(ast);
827 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
828
829 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref;}");
830 ASSERT_TRUE(ast);
831 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
832
833 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &ref;}");
834 ASSERT_TRUE(ast);
835 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
836
837 ast = jit->GetParser()->Parse("{&?ref ::= 1; test := &?ref;}");
838 ASSERT_TRUE(ast);
839 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
840 ast = jit->GetParser()->Parse("{&&ref ::= 1; test := &&ref;}");
841 ASSERT_TRUE(ast);
842 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
843 ast = jit->GetParser()->Parse("{&*ref ::= 1; test := &*ref;}");
844 ASSERT_TRUE(ast);
845 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
846
847
848 // Контроль типа
849 ast = jit->GetParser()->Parse("{&ref ::= 1; test := &ref; test := 1}");
850 ASSERT_TRUE(ast);
851 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
852
853 ast = jit->GetParser()->Parse("{&ref ::= 1; test := &ref; *test = 1}");
854 ASSERT_TRUE(ast);
855 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
856
857 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref; test = 1}");
858 ASSERT_TRUE(ast);
859 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
860
861 // Const ref
862 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref; *test = 1}");
863 ASSERT_TRUE(ast);
864 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
865
866
867 ast = jit->GetParser()->Parse("{&?ref ::= 1; test := &?ref; test = 1}");
868 ASSERT_TRUE(ast);
869 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
870
871 //with requered!
872 ast = jit->GetParser()->Parse("{&?ref ::= 1; test := &?ref; *test = 1}");
873 ASSERT_TRUE(ast);
874 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
875
876 ast = jit->GetParser()->Parse("{&&ref ::= 1; test := &&ref; test = 1}");
877 ASSERT_TRUE(ast);
878 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
879
880 // Cost ref
881 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref; *test = 1}");
882 ASSERT_TRUE(ast);
883 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
884
885 ast = jit->GetParser()->Parse("{&*ref ::= 1; test := &*ref; test = 1}");
886 ASSERT_TRUE(ast);
887 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
888
889 ast = jit->GetParser()->Parse("{&*ref ::= 1; test := &*ref; *test = 1}");
890 ASSERT_TRUE(ast);
891 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
892
893
894
895 // Контроль типа 2
896 ast = jit->GetParser()->Parse("{&ref ::= 1; test := &ref; test = ref}");
897 ASSERT_TRUE(ast);
898 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
899
900 ast = jit->GetParser()->Parse("{&ref ::= 1; test := &ref; *test = ref}");
901 ASSERT_TRUE(ast);
902 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
903
904 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref; test = ref}");
905 ASSERT_TRUE(ast);
906 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
907
908 ast = jit->GetParser()->Parse("{&^ref ::= 1; test := &^ref; *test = ref}");
909 ASSERT_TRUE(ast);
910 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
911
912
913 ast = jit->GetParser()->Parse("{&?ref ::= 1; test := &?ref; test = ref}");
914 ASSERT_TRUE(ast);
915 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
916
917 ast = jit->GetParser()->Parse("{&?ref ::= 1; test := &?ref; *test = ref}");
918 ASSERT_TRUE(ast);
919 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
920
921 ast = jit->GetParser()->Parse("{&&ref ::= 1; test := &&ref; test = ref}");
922 ASSERT_TRUE(ast);
923 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
924
925 ast = jit->GetParser()->Parse("{&&ref ::= 1; test := &&ref; *test = ref}");
926 ASSERT_TRUE(ast);
927 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
928
929
930 ast = jit->GetParser()->Parse("{&*ref ::= 1; test := &*ref; test = ref}");
931 ASSERT_TRUE(ast);
932 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
933
934 ast = jit->GetParser()->Parse("{&*ref ::= 1; test := &*ref; *test = ref}");
935 ASSERT_TRUE(ast);
936 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
937
938
939 // Контроль типа 3
940 ast = jit->GetParser()->Parse("{&val ::= 1; ref := &val; ref = *val}");
941 ASSERT_TRUE(ast);
942 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
943
944 ast = jit->GetParser()->Parse("{&val ::= 1; ref := &val; *ref = *val}");
945 ASSERT_TRUE(ast);
946 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
947
948 ast = jit->GetParser()->Parse("{&^val ::= 1; ref := &^val; ref = *val}");
949 ASSERT_TRUE(ast);
950 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
951
952 // Read only
953 ast = jit->GetParser()->Parse("{&^val ::= 1; ref := &^val; *ref = *val}");
954 ASSERT_TRUE(ast);
955 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
956
957
958 ast = jit->GetParser()->Parse("{&?val ::= 1; ref := &?val; ref = *val}");
959 ASSERT_TRUE(ast);
960 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
961
962
963 ast = jit->GetParser()->Parse("{&?val ::= 1; ref := &?val; *ref = *val}");
964 ASSERT_TRUE(ast);
965 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
966
967 ast = jit->GetParser()->Parse("{&&val ::= 1; ref := &&val; ref = *val}");
968 ASSERT_TRUE(ast);
969 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
970
971 ast = jit->GetParser()->Parse("{&&val ::= 1; ref := &&val; *ref = *val}");
972 ASSERT_TRUE(ast);
973 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
974
975
976 ast = jit->GetParser()->Parse("{&*val ::= 1; ref := &*val; ref = *val}");
977 ASSERT_TRUE(ast);
978 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << stack.Dump();
979
980 ast = jit->GetParser()->Parse("{&*val ::= 1; ref := &*val; *ref = *val}");
981 ASSERT_TRUE(ast);
982 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
983
984
985 ast = jit->GetParser()->Parse("{& lite ::= 2; &^ lite_ro ::= 22;}");
986 ASSERT_TRUE(ast);
987 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
988 // ASSERT_EQ(2, stack.size()) << stack.Dump();
989
990 ast = jit->GetParser()->Parse("{&? thread ::= 3; &?^ thread_ro ::= 33;}");
991 ASSERT_TRUE(ast);
992 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
993 // ASSERT_EQ(2, stack.size()) << stack.Dump();
994
995 ast = jit->GetParser()->Parse("{&& mono ::= 4; &&^ mono_ro ::= 44; &?(mono) thread := 123; &?^(mono_ro, __timeout__=1000) thread2 := 123;}");
996 ASSERT_TRUE(ast);
997 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
998 // ASSERT_EQ(4, stack.size()) << stack.Dump();
999
1000 ast = jit->GetParser()->Parse("{&* multi ::= 5; &*^ multi_ro ::= 55; &?(multi) other := 123; &?^(multi_ro, __timeout__=1000) other2 := 123;}");
1001 ASSERT_TRUE(ast);
1002 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << stack.Dump();
1003 // ASSERT_EQ(4, stack.size()) << stack.Dump();
1004}
1005
1006/*
1007 *
1008 */
1009
1010TEST(Ast, Namespace) {
1011
1012 JIT * jit = JIT::ReCreate();
1013 AstAnalysis analysis(*jit, jit->m_diag.get());
1015 NameLookupStack stack(*jit, external);
1016
1017 ASSERT_TRUE(stack.LookupName("Bool"));
1018 ASSERT_TRUE(stack.LookupName(":Bool"));
1019 // ASSERT_TRUE(stack.LookupName("::Bool"));
1020
1021 TermPtr ast;
1022
1023 ast = jit->GetParser()->Parse("Bool(1)");
1024 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1025
1026 ast = jit->GetParser()->Parse(":Bool(1)");
1027 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1028
1029 // ast = jit->GetParser()->Parse("::Bool(1)");
1030 // ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1031
1032
1033 ASSERT_EQ(0, external[StorageTerm::MODULE_MAIN].size());
1034 ast = jit->GetParser()->Parse("ns_test::func() ::= {};");
1035 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1036 ASSERT_EQ(1, external[StorageTerm::MODULE_MAIN].size()) << external[StorageTerm::MODULE_MAIN].Dump();
1037
1038 ast = jit->GetParser()->Parse("test { ns_test::func() }");
1039 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump() << "Static:\n" << external[StorageTerm::MODULE_MAIN].Dump();
1040
1041 ast = jit->GetParser()->Parse("test { func() }");
1042 ASSERT_FALSE(analysis.Analyze(ast, &stack)) << jit->Dump();
1043
1044 ast = jit->GetParser()->Parse("test { ... = ns_test; func() }");
1045 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1046
1047 stack.clear();
1048
1049
1050 ast = jit->GetParser()->Parse("$var := 1;");
1051 ASSERT_TRUE(ast);
1052 ASSERT_EQ(1, stack.size()) << stack.Dump();
1053 ASSERT_EQ(0, stack[0].vars.size()) << stack.Dump();
1054 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1055 ASSERT_EQ(1, stack.size());
1056 ASSERT_EQ(1, stack[0].vars.size());
1057 ASSERT_TRUE(stack.LookupName("var$")) << stack.Dump();
1058 ASSERT_STREQ("$var", stack.LookupName("var$")->m_text.c_str());
1059 ASSERT_STREQ("var$", stack.LookupName("var$")->m_normalized.c_str());
1060
1061 ast = jit->GetParser()->Parse("var = 1;");
1062 ASSERT_TRUE(ast);
1063 ASSERT_EQ(1, stack.size()) << stack.Dump();
1064 ASSERT_EQ(1, stack[0].vars.size()) << stack.Dump();
1065 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1066 ASSERT_TRUE(stack.LookupName("var$")) << stack.Dump();
1067 ASSERT_STREQ("$var", stack.LookupName("var$")->m_text.c_str());
1068 ASSERT_STREQ("var$", stack.LookupName("var$")->m_normalized.c_str());
1069
1070
1071 ASSERT_EQ(0, external[StorageTerm::MODULE_MAIN].size()) << external[StorageTerm::MODULE_MAIN].Dump();
1072
1073 ast = jit->GetParser()->Parse("::ns::var := 1;");
1074 ASSERT_TRUE(ast);
1075 ASSERT_EQ(1, stack.size()) << stack.Dump();
1076 ASSERT_EQ(1, stack[0].vars.size()) << stack.Dump();
1077 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1078 ASSERT_TRUE(stack.LookupName("::ns::var::")) << stack.Dump();
1079 ASSERT_STREQ("::ns::var", stack.LookupName("::ns::var::")->m_text.c_str());
1080 ASSERT_STREQ("::ns::var::", stack.LookupName("::ns::var::")->m_normalized.c_str());
1081
1082 ASSERT_EQ(1, external[StorageTerm::MODULE_MAIN].size()) << external[StorageTerm::MODULE_MAIN].Dump();
1083
1084 ast = jit->GetParser()->Parse("ns::var = 1;");
1085 ASSERT_TRUE(ast);
1086 ASSERT_EQ(1, stack.size()) << stack.Dump();
1087 ASSERT_EQ(1, stack[0].vars.size()) << stack.Dump();
1088 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump("*ns::var*") << "Static:\n" << external[StorageTerm::MODULE_MAIN].Dump();
1089 ASSERT_TRUE(stack.LookupName("ns::var::")) << stack.Dump();
1090 ASSERT_STREQ("::ns::var", stack.LookupName("ns::var::")->m_text.c_str());
1091 ASSERT_STREQ("::ns::var::", stack.LookupName("ns::var::")->m_normalized.c_str());
1092
1093
1094 ast = jit->GetParser()->Parse("name { var = 1; }");
1095 ASSERT_TRUE(ast);
1096 ASSERT_EQ(1, stack.size());
1097 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1098 // ASSERT_TRUE(stack.LookupName("var$")) << stack.Dump();
1099 // ASSERT_STREQ("$var", stack.LookupName("var$")->m_text.c_str());
1100 // ASSERT_STREQ("var$", stack.LookupName("var$")->m_normalized.c_str());
1101 //
1102 //
1103 // ASSERT_EQ(1, ast->m_block.size());
1104 // ASSERT_STREQ(":=", ast->m_block[0]->m_text.c_str());
1105 // ASSERT_TRUE(ast->m_block[0]->m_left);
1106 // ASSERT_STREQ("var$", ast->m_block[0]->m_left->m_normalized.c_str());
1107 // ASSERT_TRUE(ast->m_block[0]->m_right);
1108 // ASSERT_STREQ("1", ast->m_block[0]->m_right->m_text.c_str());
1109 //
1110 // ast = jit->GetParser()->Parse("name:: { var = 1; }");
1111 // ASSERT_TRUE(ast);
1112 // ASSERT_EQ(1, stack.size());
1113 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1114 // ASSERT_TRUE(stack.LookupName("name::var$")) << stack.Dump();
1115 // ASSERT_STREQ("var", stack.LookupName("var$")->m_text.c_str());
1116 // ASSERT_STREQ("var$", stack.LookupName("var$")->m_normalized.c_str());
1117 //
1118 // ast = jit->GetParser()->Parse("ns::name:: { var = 1; }");
1119 // ASSERT_TRUE(ast);
1120 // ASSERT_EQ(1, stack.size());
1121 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1122 // ASSERT_TRUE(stack.LookupName("ns::name::var$")) << stack.Dump();
1123 // ASSERT_STREQ("var", stack.LookupName("ns::name::var$")->m_text.c_str());
1124 // ASSERT_STREQ("var$", stack.LookupName("ns::name::var$")->m_normalized.c_str());
1125
1126 ast = jit->GetParser()->Parse("name:: { ::var := 1; }");
1127 ASSERT_TRUE(ast);
1128 ASSERT_EQ(1, stack.size());
1129 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1130 ASSERT_TRUE(stack.LookupName("::var::")) << stack.Dump();
1131 ASSERT_STREQ("::var", stack.LookupName("::var::")->m_text.c_str());
1132 ASSERT_STREQ("::var::", stack.LookupName("::var::")->m_normalized.c_str());
1133
1134 ast = jit->GetParser()->Parse("::name:: { ::ns2::var := 1; }");
1135 ASSERT_TRUE(ast);
1136 ASSERT_EQ(1, stack.size());
1137 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1138 ASSERT_TRUE(stack.LookupName("::ns2::var::")) << stack.Dump();
1139 ASSERT_STREQ("::ns2::var", stack.LookupName("::ns2::var::")->m_text.c_str());
1140 ASSERT_STREQ("::ns2::var::", stack.LookupName("::ns2::var::")->m_normalized.c_str());
1141
1142 // ast = jit->GetParser()->Parse("name { $var := 1; }");
1143 // ASSERT_TRUE(ast);
1144 // ASSERT_EQ(0, stack.size());
1145 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1146 // ASSERT_TRUE(stack.LookupName("name::var$")) << stack.Dump();
1147 // ASSERT_STREQ("$var", stack.LookupName("name::var$")->m_text.c_str());
1148 // ASSERT_STREQ("name::var$", stack.LookupName("name::var$")->m_normalized.c_str());
1149 //
1150 // ast = jit->GetParser()->Parse("name { { $var := 1; } }");
1151 // ASSERT_TRUE(ast);
1152 // ASSERT_EQ(0, stack.size());
1153 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1154 // ASSERT_TRUE(stack.LookupName("name::2::var$")) << stack.Dump();
1155 // ASSERT_STREQ("$var", stack.LookupName("name::2::var$")->m_text.c_str());
1156 // ASSERT_STREQ("name::2::var$", stack.LookupName("name::2::var$")->m_normalized.c_str());
1157 //
1158 // ast = jit->GetParser()->Parse("ns{ name { { $var := 1; } } }");
1159 // ASSERT_TRUE(ast);
1160 // ASSERT_EQ(0, stack.size());
1161 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1162 // ASSERT_TRUE(stack.LookupName("ns::name::2::var$")) << stack.Dump();
1163 // ASSERT_STREQ("$var", stack.LookupName("ns::name::2::var$")->m_text.c_str());
1164 // ASSERT_STREQ("ns::name::2::var$", stack.LookupName("ns::name::2::var$")->m_normalized.c_str());
1165
1166}
1167
1168TEST(Ast, Interruption) {
1169
1170 JIT * jit = JIT::ReCreate();
1171
1172 AstAnalysis analysis(*jit, jit->m_diag.get());
1174 NameLookupStack stack(*jit, external);
1175
1176 TermPtr ast;
1177
1178 ast = jit->GetParser()->Parse("{ --; ++ }");
1179 ASSERT_TRUE(ast);
1180 ASSERT_EQ(1, ast->m_block.size());
1181 ASSERT_EQ(2, ast->m_block[0]->m_block.size());
1182
1183 ast = jit->GetParser()->Parse("{ { --; ++ } }");
1184 ASSERT_TRUE(ast);
1185 ASSERT_EQ(1, ast->m_block.size());
1186 ASSERT_EQ(1, ast->m_block[0]->m_block.size());
1187 ASSERT_EQ(2, ast->m_block[0]->m_block[0]->m_block.size());
1188
1189 ast = jit->GetParser()->Parse("ns { name { -- } }");
1190 ASSERT_TRUE(ast);
1191 ASSERT_EQ(1, ast->m_block.size());
1192 ASSERT_STREQ("ns", ast->m_namespace->m_text.c_str());
1193 ASSERT_EQ(1, ast->m_block[0]->m_block.size());
1194 ASSERT_TRUE(ast->m_block[0]->m_namespace);
1195 ASSERT_STREQ("name", ast->m_block[0]->m_namespace->m_text.c_str());
1196
1197
1198 ast = jit->GetParser()->Parse(":: --;");
1199 ASSERT_TRUE(ast);
1200 ASSERT_STREQ("::", ast->m_namespace->m_text.c_str());
1201 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1202 ASSERT_TRUE(ast->m_namespace);
1203 ASSERT_STREQ("::", ast->m_namespace->m_text.c_str());
1204
1205 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("name { name -- };"));
1206 ASSERT_TRUE(ast);
1207 ASSERT_TRUE(ast->isBlock());
1208 ASSERT_EQ(1, ast->m_block.size());
1209 ASSERT_STREQ("--", ast->m_block[0]->m_text.c_str());
1210 ASSERT_TRUE(ast->m_block[0]->isInterrupt());
1211 ASSERT_TRUE(ast->m_block[0]->m_namespace);
1212 ASSERT_STREQ("name::", ast->m_block[0]->m_namespace->m_text.c_str());
1213 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1214 ASSERT_STREQ("name::", ast->m_block[0]->m_namespace->m_text.c_str());
1215
1216 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns::name { ns::name -+ };"));
1217 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1218 ASSERT_TRUE(ast);
1219
1220 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { name { ns +- } };"));
1221 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1222 ASSERT_TRUE(ast);
1223
1224 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { { ns:: ++ } } } };"));
1225 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1226 ASSERT_TRUE(ast);
1227
1228 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("{ ns::name { name:: { name:: +- } } };"));
1229 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1230 ASSERT_TRUE(ast);
1231
1232 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns::name { { name { local:: { ns::name ++ } } } };"));
1233 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1234 ASSERT_TRUE(ast);
1235
1236 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local { local ++ } } } };"));
1237 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1238 ASSERT_TRUE(ast);
1239
1240 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { ns ++ } } } };"));
1241 ASSERT_TRUE(analysis.Analyze(ast, &stack));
1242 ASSERT_TRUE(ast);
1243
1244
1245 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { bad_name ++ } } } };"));
1246 ASSERT_FALSE(analysis.Analyze(ast, &stack));
1247
1248 // ast = jit->GetParser()->Parse("name { bad_name -- };");
1249 // ASSERT_TRUE(ast);
1250 // ASSERT_FALSE(analysis.Analyze(ast, &stack));
1251 //
1252 // ast = jit->GetParser()->Parse("name { bad_name:: -- };");
1253 // ASSERT_TRUE(ast);
1254 // ASSERT_FALSE(analysis.Analyze(ast, &stack));
1255 //
1256 // ast = jit->GetParser()->Parse("name1 { name2 { name3 { ::bad_name -- }}};");
1257 // ASSERT_TRUE(ast);
1258 // ASSERT_FALSE(analysis.Analyze(ast, &stack));
1259 //
1260 // ast = jit->GetParser()->Parse("name { name2::name3 { ::bad_name::name -- }};");
1261 // ASSERT_TRUE(ast);
1262 // ASSERT_FALSE(analysis.Analyze(ast, &stack));
1263 //
1264 // ast = jit->GetParser()->Parse("name { name::bad -- };");
1265 // ASSERT_TRUE(ast);
1266 // ASSERT_FALSE(analysis.Analyze(ast, &stack));
1267 //
1268 // // ast = jit->GetParser()->Parse("@$$ --;");
1269 // // ASSERT_TRUE(ast);
1270 // // ASSERT_STREQ("@$$", ast->m_namespace->m_text.c_str());
1271 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1272 // // ASSERT_STREQ("", ast->m_namespace->m_text.c_str());
1273 //
1274 // // ast = jit->GetParser()->Parse("name { @$$ -- };");
1275 // // ASSERT_TRUE(ast);
1276 // // ASSERT_EQ(1, ast->m_block.size());
1277 // // ASSERT_STREQ("--", ast->m_block[0]->m_text.c_str());
1278 // // ASSERT_TRUE(ast->m_block[0]->m_namespace);
1279 // // ASSERT_STREQ("@$$", ast->m_block[0]->m_namespace->m_text.c_str());
1280 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1281 // // ASSERT_STREQ("name", ast->m_block[0]->m_namespace->m_text.c_str());
1282 //
1283 // ast = jit->GetParser()->Parse("@::var := 1");
1284 // ASSERT_TRUE(ast);
1285 // ASSERT_EQ(0, ast->m_variables.size());
1286 // ASSERT_EQ(3, rt->size() - buildin_count);
1287 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1288 // ASSERT_EQ(3, rt->size() - buildin_count);
1289 // ASSERT_EQ(1, ast->m_variables.size());
1290 // ASSERT_STREQ("$$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1291 //
1292 // ast = jit->GetParser()->Parse("@::var ::= 1");
1293 // ASSERT_TRUE(ast);
1294 // ASSERT_EQ(0, ast->m_variables.size());
1295 // ASSERT_EQ(3, rt->size() - buildin_count);
1296 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1297 // ASSERT_EQ(3, rt->size() - buildin_count);
1298 // ASSERT_EQ(1, ast->m_variables.size());
1299 // ASSERT_STREQ("$$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1300 //
1301 // ast = jit->GetParser()->Parse("ns { name { @::var := 1 } };");
1302 // ASSERT_TRUE(ast);
1303 // ASSERT_EQ(0, ast->m_variables.size());
1304 // ASSERT_EQ(3, rt->size() - buildin_count);
1305 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1306 // ASSERT_EQ(3, rt->size() - buildin_count);
1307 // ASSERT_EQ(1, ast->m_variables.size());
1308 // ASSERT_STREQ("ns::name::var", ast->m_variables.begin()->second.proto->m_text.c_str());
1309 //
1310 //
1311 // // ast = jit->GetParser()->Parse("ns { name { { var7 := @:: } } };");
1312 // // ASSERT_TRUE(ast);
1313 // // ASSERT_EQ(0, ast->m_variables.size());
1314 // // ASSERT_EQ(3, rt->size() - buildin_count);
1315 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1316 // // ASSERT_EQ(3, rt->size() - buildin_count);
1317 // // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
1318 // // ASSERT_STREQ("ns::name$var7", ast->m_variables.begin()->second.proto->m_text.c_str());
1319 //
1320 // // // В каком модуле ::$var_glob ???
1321 // // ast = jit->GetParser()->Parse(":: { var_glob := 1 };");
1322 // // ASSERT_TRUE(ast);
1323 // // ASSERT_EQ(0, ast->m_variables.size());
1324 // // ASSERT_EQ(3, rt->size() - buildin_count);
1325 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1326 // // ASSERT_EQ(0, ast->m_variables.size()) << ast->m_variables.begin()->second.proto->m_text.c_str();
1327 // // ASSERT_EQ(4, rt->size() - buildin_count);
1328 // // ASSERT_STREQ("::$var_glob", ast->m_variables.begin()->second.proto->m_text.c_str());
1329 //
1330 //
1331 // /*
1332 // * Функции
1333 // */
1334 //
1335 // buildin_count = rt->size();
1336 // ast = jit->GetParser()->Parse("func() ::= {};");
1337 // ASSERT_TRUE(ast);
1338 // ASSERT_EQ(0, rt->size() - buildin_count);
1339 // ASSERT_EQ(0, ast->m_variables.size());
1340 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1341 // ASSERT_EQ(0, rt->size() - buildin_count);
1342 // ASSERT_EQ(1, ast->m_variables.size());
1343 // ASSERT_STREQ("$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
1344 //
1345 // ast = jit->GetParser()->Parse("@::func() ::= {};");
1346 // ASSERT_TRUE(ast);
1347 //
1348 // ASSERT_TRUE(ast->m_left);
1349 // ASSERT_TRUE(ast->m_left->isCall()) << ast->toString();
1350 // ASSERT_STREQ("@::func", ast->m_left->m_text.c_str());
1351 //
1352 // ASSERT_EQ(0, rt->size() - buildin_count);
1353 // ASSERT_EQ(0, ast->m_variables.size());
1354 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1355 // ASSERT_EQ(0, rt->size() - buildin_count);
1356 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
1357 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
1358 // ASSERT_STREQ("$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
1359 //
1360 //
1361 // ast = jit->GetParser()->Parse("name { func() ::= {} };");
1362 // ASSERT_TRUE(ast);
1363 //
1364 // ASSERT_EQ(1, ast->m_block.size());
1365 // ASSERT_TRUE(ast->m_block[0]->m_left);
1366 // ASSERT_TRUE(ast->m_block[0]->m_left->isCall()) << ast->m_block[0]->toString();
1367 // ASSERT_STREQ("func", ast->m_block[0]->m_left->m_text.c_str());
1368 //
1369 // ASSERT_EQ(0, rt->size() - buildin_count);
1370 // ASSERT_EQ(0, ast->m_variables.size());
1371 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1372 // ASSERT_EQ(0, rt->size() - buildin_count);
1373 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
1374 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
1375 // ASSERT_STREQ("name$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
1376 // ASSERT_STREQ("name$$func", ast->m_block[0]->m_left->m_text.c_str());
1377 //
1378 // ast = jit->GetParser()->Parse("ns { name { func() ::= {} } };");
1379 // ASSERT_TRUE(ast);
1380 //
1381 // ASSERT_EQ(1, ast->m_block.size());
1382 // ASSERT_TRUE(ast->m_block[0]->m_left);
1383 // ASSERT_TRUE(ast->m_block[0]->m_left->isCall()) << ast->m_block[0]->toString();
1384 // ASSERT_STREQ("func", ast->m_block[0]->m_left->m_text.c_str());
1385 //
1386 // ASSERT_EQ(0, rt->size() - buildin_count);
1387 // ASSERT_EQ(0, ast->m_variables.size());
1388 // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1389 // ASSERT_EQ(0, rt->size() - buildin_count);
1390 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
1391 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
1392 // ASSERT_STREQ("ns::name$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
1393 // ASSERT_STREQ("ns::name$$func", ast->m_block[0]->m_left->m_text.c_str());
1394 //
1395 // // ast = jit->GetParser()->Parse("var := 1;");
1396 // // ASSERT_TRUE(ast);
1397 // // ASSERT_EQ(0, ast->m_variables.size());
1398 // // ASSERT_EQ(0, rt->size() - buildin_count);
1399 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1400 // // ASSERT_EQ(0, rt->size() - buildin_count);
1401 // // ASSERT_EQ(1, ast->m_variables.size());
1402 // // ASSERT_STREQ("$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1403 // //
1404 // //
1405 // // ast = jit->GetParser()->Parse("ns::var := 1;");
1406 // // ASSERT_TRUE(ast);
1407 // // ASSERT_EQ(0, ast->m_variables.size());
1408 // // ASSERT_EQ(0, rt->size() - buildin_count);
1409 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1410 // // ASSERT_EQ(0, rt->size() - buildin_count);
1411 // // ASSERT_EQ(1, ast->m_variables.size());
1412 // // ASSERT_STREQ("ns::var", ast->m_variables.begin()->second.proto->m_text.c_str());
1413 // //
1414 // //
1415 // // ast = jit->GetParser()->Parse("::ns::var := 1;");
1416 // // ASSERT_TRUE(ast);
1417 // // ASSERT_EQ(0, ast->m_variables.size());
1418 // // ASSERT_EQ(0, rt->size() - buildin_count);
1419 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1420 // // ASSERT_EQ(1, rt->size() - buildin_count);
1421 // // ASSERT_EQ(0, ast->m_variables.size());
1422 // // ASSERT_STREQ("::ns::var", (*rt)["::ns::var"].proto->m_text.c_str());
1423 // //
1424 // //
1425 // // ast = jit->GetParser()->Parse("name { var := 1 };");
1426 // // ASSERT_TRUE(ast);
1427 // // ASSERT_EQ(0, ast->m_variables.size());
1428 // // ASSERT_EQ(1, rt->size() - buildin_count);
1429 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1430 // // ASSERT_EQ(1, rt->size() - buildin_count);
1431 // // ASSERT_EQ(1, ast->m_variables.size());
1432 // //
1433 // // ASSERT_EQ(1, ast->m_block.size());
1434 // // ASSERT_STREQ(":=", ast->m_block[0]->m_text.c_str());
1435 // // ASSERT_TRUE(ast->m_block[0]->m_left);
1436 // // ASSERT_STREQ("name$var", ast->m_block[0]->m_left->m_text.c_str());
1437 // // ASSERT_TRUE(ast->m_block[0]->m_right);
1438 // // ASSERT_STREQ("1", ast->m_block[0]->m_right->m_text.c_str());
1439 // //
1440 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1441 // //
1442 // // ast = jit->GetParser()->Parse("name:: { var := 1 };");
1443 // // ASSERT_TRUE(ast);
1444 // // ASSERT_EQ(0, ast->m_variables.size());
1445 // // ASSERT_EQ(1, rt->size() - buildin_count);
1446 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1447 // // ASSERT_EQ(1, rt->size() - buildin_count);
1448 // // ASSERT_EQ(1, ast->m_variables.size());
1449 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1450 // //
1451 // //
1452 // // ast = jit->GetParser()->Parse("ns::name:: { var := 1 };");
1453 // // ASSERT_TRUE(ast);
1454 // // ASSERT_EQ(0, ast->m_variables.size());
1455 // // ASSERT_EQ(1, rt->size() - buildin_count);
1456 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1457 // // ASSERT_EQ(1, rt->size() - buildin_count);
1458 // // ASSERT_EQ(1, ast->m_variables.size());
1459 // // ASSERT_STREQ("ns::name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1460 // //
1461 // // ast = jit->GetParser()->Parse("name:: { ::var := 1 };");
1462 // // ASSERT_TRUE(ast);
1463 // // ASSERT_EQ(0, ast->m_variables.size());
1464 // // ASSERT_EQ(1, rt->size() - buildin_count);
1465 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1466 // // ASSERT_EQ(2, rt->size() - buildin_count);
1467 // // ASSERT_EQ(0, ast->m_variables.size());
1468 // // ASSERT_STREQ("::var", (*rt)["::var"].proto->m_text.c_str());
1469 // //
1470 // // ast = jit->GetParser()->Parse("::name:: { ::ns2::var := 1 };");
1471 // // ASSERT_TRUE(ast);
1472 // // ASSERT_EQ(0, ast->m_variables.size());
1473 // // ASSERT_EQ(2, rt->size() - buildin_count);
1474 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1475 // // ASSERT_EQ(3, rt->size() - buildin_count);
1476 // // ASSERT_EQ(0, ast->m_variables.size());
1477 // // ASSERT_STREQ("::ns2::var", (*rt)["::ns2::var"].proto->m_text.c_str());
1478 // //
1479 // //
1480 // // ast = jit->GetParser()->Parse("name { $var := 1 };");
1481 // // ASSERT_TRUE(ast);
1482 // // ASSERT_EQ(0, ast->m_variables.size());
1483 // // ASSERT_EQ(3, rt->size() - buildin_count);
1484 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1485 // // ASSERT_EQ(3, rt->size() - buildin_count);
1486 // // ASSERT_EQ(1, ast->m_variables.size());
1487 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1488 // //
1489 // // ast = jit->GetParser()->Parse("name { { $var := 1 } };");
1490 // // ASSERT_TRUE(ast);
1491 // // ASSERT_EQ(0, ast->m_variables.size());
1492 // // ASSERT_EQ(3, rt->size() - buildin_count);
1493 // // ASSERT_TRUE(analysis.Analyze(ast, &stack));
1494 // // ASSERT_EQ(3, rt->size() - buildin_count);
1495 // // ASSERT_EQ(1, ast->m_variables.size());
1496 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1497}
1498
1499TEST(Ast, Dims) {
1500 // :Bool[...]() - OK
1501 // :Bool[0]() - Error !!!!!!!!!!!!!!!!!
1502 // :Bool() - Ok
1503 // :Bool[..., ...]() - Error !!!!!!!!!!!!!!!!!
1504
1505 JIT * jit = JIT::ReCreate();
1506 AstAnalysis analysis(*jit, jit->m_diag.get());
1508 NameLookupStack stack(*jit, external);
1509
1510 TermPtr ast;
1511
1512 ast = jit->GetParser()->Parse("Bool(1)");
1513 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1514
1515 ast = jit->GetParser()->Parse(":Bool(1)");
1516 ASSERT_TRUE(analysis.Analyze(ast, &stack)) << jit->Dump();
1517
1518 ASSERT_ANY_THROW(ast = jit->GetParser()->Parse(":Bool[](1)"));
1519
1520 AstAnalysis analysis2(*jit, jit->m_diag.get());
1521 ast = jit->GetParser()->Parse(":Bool[...](1)");
1522 ASSERT_TRUE(analysis2.Analyze(ast));
1523
1524 AstAnalysis analysis3(*jit, jit->m_diag.get());
1525 ast = jit->GetParser()->Parse(":Bool[ ..., ...](1)");
1526 ASSERT_FALSE(analysis3.Analyze(ast));
1527
1528 AstAnalysis analysis4(*jit, jit->m_diag.get());
1529 ast = jit->GetParser()->Parse(":Bool[0](1)");
1530 ASSERT_TRUE(analysis4.Analyze(ast));
1531
1532 AstAnalysis analysis5(*jit, jit->m_diag.get());
1533 ast = jit->GetParser()->Parse(":Bool[_](1)");
1534 ASSERT_TRUE(analysis5.Analyze(ast));
1535
1536 AstAnalysis analysis6(*jit, jit->m_diag.get());
1537 ast = jit->GetParser()->Parse(":Bool[0..1..2](1)");
1538 ASSERT_TRUE(analysis6.Analyze(ast));
1539
1540 AstAnalysis analysis7(*jit, jit->m_diag.get());
1541 ast = jit->GetParser()->Parse("0.._..2");
1542 ASSERT_TRUE(analysis7.Analyze(ast));
1543}
1544
1545
1546//TEST(Ast, ClassFunc) {
1547//
1548// Context::Reset();
1549// Context ctx(RunTime::Init());
1550//
1551// size_t buildin_count = ctx.m_runtime->size();
1552//
1553// ASSERT_EQ(0, ctx.m_runtime->m_macro->m_ns_stack.size());
1554// ASSERT_EQ(0, ctx.size());
1555//
1556// ASSERT_EQ(0, ctx.size());
1557//
1558// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { func1() := {1}; }");
1559// ASSERT_TRUE(class1);
1560// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1561// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1562// ASSERT_STREQ(":class1", class1->getName().c_str());
1563//
1564// // ASSERT_TRUE(ctx.size() > 0) << ctx.Dump("; ").c_str();
1565// // ASSERT_STREQ(":class1", ctx.at(0).first.c_str()) << ctx.Dump("; ").c_str();
1566// // ASSERT_TRUE(ctx.find(":class1") != ctx.end()) << ctx.Dump("; ").c_str();
1567// // ASSERT_STREQ("classfunc1", ctx.at(1).first.c_str()) << ctx.Dump("; ").c_str();
1568// ASSERT_EQ(2, ctx.m_runtime->size()-buildin_count);
1569// ASSERT_STREQ("classclass1", ctx.m_terms->at(0).first.c_str());
1570// ASSERT_STREQ("classfunc1", ctx.m_terms->at(1).first.c_str());
1571// ObjPtr func1 = ctx.ExecStr("classfunc1");
1572// ASSERT_EQ(1, func1->Call(&ctx)->GetValueAsInteger());
1573//
1574// ASSERT_STREQ("class::class", MakeConstructorName(":class").c_str());
1575// ASSERT_STREQ("ns::class::class", MakeConstructorName(":ns::class").c_str());
1576// ASSERT_STREQ("ns::class::class::class", MakeConstructorName(":ns::class::class").c_str());
1577//
1578// EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_func1 := :class1 { func1() ::= {11}; }"));
1579// EXPECT_ANY_THROW(ctx.ExecStr(":class_func_not_found := :class1 { func_not_found() = {0}; }"));
1580//
1581// ObjPtr class2 = ctx.ExecStr(":class2 := :class1() { func2() := {2}; }");
1582// ASSERT_TRUE(class2);
1583// ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1584// ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1585// ASSERT_STREQ(":class2", class2->getName().c_str());
1586//
1587// ASSERT_TRUE(ctx.size() > 2) << ctx.Dump("; ").c_str();
1588// // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1589//
1590// std::string dump;
1591// for (int i = 0; i < ctx.m_terms->size(); i++) {
1592// dump += ctx.m_terms->at(i).first;
1593// dump += "; ";
1594// }
1595// ASSERT_EQ(5, ctx.m_terms->size()) << dump;
1596// ASSERT_STREQ("class2::class2", ctx.m_terms->at(2).first.c_str());
1597// ASSERT_STREQ("class2::func1", ctx.m_terms->at(3).first.c_str());
1598// ASSERT_STREQ("class2::func2", ctx.m_terms->at(4).first.c_str());
1599// ObjPtr func2_1 = ctx.ExecStr("class2::func1");
1600// ASSERT_EQ(1, func2_1->Call(&ctx)->GetValueAsInteger());
1601// ObjPtr func2_2 = ctx.ExecStr("class2::func2");
1602// ASSERT_EQ(2, func2_2->Call(&ctx)->GetValueAsInteger());
1603//
1604//
1605//
1606// ObjPtr func_name = ctx.ExecStr("class2 { func_name() := {'func_name'}; }");
1607// ASSERT_TRUE(func_name);
1608// ASSERT_EQ(ObjType::EVAL_FUNCTION, func_name->m_var_type_current) << toString(func_name->m_var_type_current);
1609// ASSERT_STREQ("class2::func_name", func_name->getName().c_str());
1610//
1611// dump = "";
1612// for (int i = 0; i < ctx.m_terms->size(); i++) {
1613// dump += ctx.m_terms->at(i).first;
1614// dump += "; ";
1615// }
1616// ASSERT_EQ(6, ctx.m_terms->size()) << dump;
1617// ASSERT_STREQ("class2::func_name", ctx.m_terms->at(5).first.c_str());
1618// ASSERT_STREQ("func_name", func_name->Call(&ctx)->GetValueAsString().c_str());
1619//
1620//
1621// ObjPtr class3 = ctx.ExecStr(":class3 := :class1, :class2 { func3() := {33}; func4() := {4}; }");
1622// ASSERT_TRUE(class3);
1623// ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class3->m_var_type_current);
1624// ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class3->m_var_type_fixed);
1625// ASSERT_STREQ(":class3", class3->getName().c_str());
1626//
1627// ASSERT_TRUE(ctx.size() > 4) << ctx.Dump("; ").c_str();
1628//
1629// dump = "";
1630// for (int i = 0; i < ctx.m_terms->size(); i++) {
1631// dump += ctx.m_terms->at(i).first;
1632// dump += "; ";
1633// }
1634// ASSERT_EQ(12, ctx.m_terms->size()) << dump;
1635// ASSERT_STREQ("class3::class3", ctx.m_terms->at(6).first.c_str());
1636// ASSERT_STREQ("class3::func1", ctx.m_terms->at(7).first.c_str());
1637// ASSERT_STREQ("class3::func3", ctx.m_terms->at(8).first.c_str());
1638// ASSERT_STREQ("class3::func4", ctx.m_terms->at(9).first.c_str());
1639// ASSERT_STREQ("class3::func2", ctx.m_terms->at(10).first.c_str());
1640// ASSERT_STREQ("class3::func_name", ctx.m_terms->at(11).first.c_str());
1641// ObjPtr func3_1 = ctx.ExecStr("class3::func1");
1642// ASSERT_EQ(1, func3_1->Call(&ctx)->GetValueAsInteger());
1643// ObjPtr func3_2 = ctx.ExecStr("class3::func2");
1644// ASSERT_EQ(2, func3_2->Call(&ctx)->GetValueAsInteger());
1645// ObjPtr func3_3 = ctx.ExecStr("class3::func3");
1646// ASSERT_EQ(33, func3_3->Call(&ctx)->GetValueAsInteger());
1647// ObjPtr func3_4 = ctx.ExecStr("class3::func4");
1648// ASSERT_EQ(4, func3_4->Call(&ctx)->GetValueAsInteger());
1649// ObjPtr result = ctx.ExecStr("class3::func_name()");
1650// ASSERT_TRUE(result);
1651// ASSERT_STREQ("func_name", result->GetValueAsString().c_str());
1652//
1653//
1654//
1655//
1656// ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1657// ASSERT_TRUE(var1);
1658// ObjPtr var1_1 = ctx.ExecStr("var1.func1()");
1659// ASSERT_TRUE(var1_1);
1660// ASSERT_EQ(1, var1_1->GetValueAsInteger());
1661//
1662//
1663// ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1664// ASSERT_TRUE(var2);
1665// ObjPtr var2_1 = ctx.ExecStr("var2.func1()");
1666// ASSERT_TRUE(var2_1);
1667// ASSERT_EQ(1, var2_1->GetValueAsInteger());
1668// ObjPtr var2_2 = ctx.ExecStr("var2.func2()");
1669// ASSERT_TRUE(var2_2);
1670// ASSERT_EQ(2, var2_2->GetValueAsInteger());
1671//
1672//
1673// ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1674// ASSERT_TRUE(var3);
1675// ObjPtr var3_1 = ctx.ExecStr("var3.func1()");
1676// ASSERT_TRUE(var3_1);
1677// ASSERT_EQ(1, var3_1->GetValueAsInteger());
1678// ObjPtr var3_2 = ctx.ExecStr("var3.func2()");
1679// ASSERT_TRUE(var3_2);
1680// ASSERT_EQ(2, var3_2->GetValueAsInteger());
1681// ObjPtr var3_3 = ctx.ExecStr("var3.func3()");
1682// ASSERT_TRUE(var3_3);
1683// ASSERT_EQ(33, var3_3->GetValueAsInteger());
1684// ObjPtr var3_4 = ctx.ExecStr("var3.func4()");
1685// ASSERT_TRUE(var3_4);
1686// ASSERT_EQ(4, var3_4->GetValueAsInteger());
1687//
1688//}
1689//
1690//TEST(Ast, ClassProp) {
1691//
1692// Context::Reset();
1693// Context ctx(RunTime::Init());
1694//
1695// ASSERT_EQ(0, ctx.m_runtime->m_macro->m_ns_stack.size());
1696// ASSERT_EQ(0, ctx.size());
1697// ASSERT_EQ(0, ctx.m_terms->size());
1698//
1699// ASSERT_EQ(0, ctx.size());
1700//
1701// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { prop1 := 1; }");
1702// ASSERT_TRUE(class1);
1703// ASSERT_TRUE(class1->is_init());
1704// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1705// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1706// ASSERT_STREQ(":class1", class1->getName().c_str());
1707// ASSERT_EQ(1, class1->size());
1708// ASSERT_TRUE(class1->at("prop1").second);
1709// ASSERT_STREQ("1", class1->at("prop1").second->toString().c_str());
1710//
1711// ObjPtr class2 = ctx.ExecStr(":class2 := :class1 { prop2 := 2; }");
1712// ASSERT_TRUE(class2);
1713// ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1714// ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1715// ASSERT_STREQ(":class2", class2->getName().c_str());
1716// ASSERT_EQ(2, class2->size());
1717// ASSERT_STREQ("1", class2->at("prop1").second->toString().c_str());
1718// ASSERT_STREQ("2", class2->at("prop2").second->toString().c_str());
1719//
1720//
1721// ObjPtr class3 = ctx.ExecStr(":class3 := :class2 { prop1 = 10; }");
1722// ASSERT_TRUE(class3);
1723// ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class2->m_var_type_current);
1724// ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1725// ASSERT_STREQ(":class3", class3->getName().c_str());
1726// ASSERT_EQ(2, class3->size());
1727// ASSERT_STREQ("10", class3->at("prop1").second->toString().c_str());
1728// ASSERT_STREQ("2", class3->at("prop2").second->toString().c_str());
1729//
1730//
1731// EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_prop2 := :class2 { prop2 ::= 1; }"));
1732// EXPECT_ANY_THROW(ctx.ExecStr(":class_prop_not_found := :class2 { prop_not_found = 1; }"));
1733//
1734//
1735// ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1736// ASSERT_TRUE(var1);
1737// ObjPtr var1_1;
1738//
1739// ASSERT_NO_THROW(var1_1 = ctx.ExecStr("var1.prop1")) << ctx.Dump() << " (" << var1->toString() << ")";
1740//
1741// ASSERT_TRUE(var1_1);
1742// ASSERT_EQ(1, var1_1->GetValueAsInteger());
1743//
1744//
1745// ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1746// ASSERT_TRUE(var2);
1747// ObjPtr var2_1 = ctx.ExecStr("var2.prop1");
1748// ASSERT_TRUE(var2_1);
1749// ASSERT_EQ(1, var2_1->GetValueAsInteger());
1750// ObjPtr var2_2 = ctx.ExecStr("var2.prop2");
1751// ASSERT_TRUE(var2_2);
1752// ASSERT_EQ(2, var2_2->GetValueAsInteger());
1753//
1754// ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1755// ASSERT_TRUE(var3);
1756// ObjPtr var3_1 = ctx.ExecStr("var3.prop1");
1757// ASSERT_TRUE(var3_1);
1758// ASSERT_EQ(10, var3_1->GetValueAsInteger());
1759// ObjPtr var3_2 = ctx.ExecStr("var3.prop2");
1760// ASSERT_TRUE(var3_2);
1761// ASSERT_EQ(2, var3_2->GetValueAsInteger());
1762//
1763//
1764// ObjPtr var4 = ctx.ExecStr("var4 := :class3(prop2=100, prop1=99)");
1765// ASSERT_TRUE(var4);
1766// ObjPtr var4_1 = ctx.ExecStr("var4.prop1");
1767// ASSERT_TRUE(var4_1);
1768// ASSERT_EQ(99, var4_1->GetValueAsInteger());
1769// ObjPtr var4_2 = ctx.ExecStr("var4.prop2");
1770// ASSERT_TRUE(var4_2);
1771// ASSERT_EQ(100, var4_2->GetValueAsInteger());
1772//
1773//
1774// EXPECT_ANY_THROW(ctx.ExecStr("var_not_found := :class3(prop_not_found=100)"));
1775// EXPECT_ANY_THROW(ctx.ExecStr("var_bad_type := :class3(prop1='BAD TYPE')"));
1776//}
1777
1778
1779
1780
1781//TEST(Ast, ClassConstruct) {
1782//
1783//
1784// ASSERT_STREQ("class::class", MakeConstructorName(":class").c_str());
1785// ASSERT_STREQ("ns::class::class", MakeConstructorName(":ns::class").c_str());
1786// ASSERT_STREQ("ns::class::class::class", MakeConstructorName(":ns::class::class").c_str());
1787//
1788//
1789// Context::Reset();
1790// Context ctx(RunTime::Init());
1791//
1792// ASSERT_EQ(0, ctx.m_ns_stack.size());
1793// ASSERT_EQ(0, ctx.size());
1794// ASSERT_EQ(0, ctx.m_terms->size());
1795//
1796// ASSERT_EQ(0, ctx.size());
1797//
1798// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { func1() := {1}; prop1 := 1; class1() = {$0.prop1 = 99; $0}; }");
1799// ASSERT_TRUE(class1);
1800// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1801// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1802// ASSERT_STREQ(":class1", class1->getName().c_str());
1803//
1804// ASSERT_EQ(3, ctx.m_terms->size());
1805// ASSERT_STREQ(":classclass1", ctx.m_terms->at(0).first.c_str());
1806// ASSERT_STREQ("classfunc1", ctx.m_terms->at(1).first.c_str());
1807// ObjPtr func1 = ctx.ExecStr("classfunc1");
1808// ASSERT_EQ(1, func1->Call(&ctx)->GetValueAsInteger());
1809//
1810// ASSERT_ANY_THROW(ctx.ExecStr("classclass1()")); // Object not found
1811//
1812// ObjPtr obj1 = ctx.ExecStr("var1 := :class1()");
1813// ASSERT_TRUE(obj1);
1814// ObjPtr var1_1 = ctx.ExecStr("var1.prop1");
1815// ASSERT_TRUE(var1_1);
1816// ASSERT_EQ(99, var1_1->GetValueAsInteger());
1817//
1818// //
1819// // ASSERT_ANY_THROW(ctx.ExecStr(":class_dup_func1 := :class1 { func1() ::= {11}; }"));
1820// // ASSERT_ANY_THROW(ctx.ExecStr(":class_func_not_found := :class1 { func_not_found() = {0}; }"));
1821// //
1822// // ObjPtr class2 = ctx.ExecStr(":class2 := :class1() { func2() := {2}; }");
1823// // ASSERT_TRUE(class2);
1824// // ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1825// // ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1826// // ASSERT_STREQ(":class2", class2->getName().c_str());
1827// //
1828// // ASSERT_TRUE(ctx.size() > 2) << ctx.Dump("; ").c_str();
1829// // // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1830// // ASSERT_EQ(3, ctx.m_terms->size());
1831// // ASSERT_STREQ("class2::func1", ctx.m_terms->at(1).first.c_str());
1832// // ASSERT_STREQ("class2::func2", ctx.m_terms->at(2).first.c_str());
1833// // ObjPtr func2_1 = ctx.ExecStr("class2::func1");
1834// // ASSERT_EQ(1, func2_1->Call(&ctx)->GetValueAsInteger());
1835// // ObjPtr func2_2 = ctx.ExecStr("class2::func2");
1836// // ASSERT_EQ(2, func2_2->Call(&ctx)->GetValueAsInteger());
1837// //
1838// //
1839// //
1840// // ObjPtr func_name = ctx.ExecStr("class2 { func_name() := {'func_name'}; }");
1841// // ASSERT_TRUE(func_name);
1842// // ASSERT_EQ(ObjType::EVAL_FUNCTION, func_name->m_var_type_current) << toString(func_name->m_var_type_current);
1843// // ASSERT_STREQ("class2::func_name", func_name->getName().c_str());
1844// //
1845// // ASSERT_EQ(4, ctx.m_terms->size());
1846// // ASSERT_STREQ("class2::func_name", ctx.m_terms->at(3).first.c_str());
1847// // ASSERT_STREQ("func_name", func_name->Call(&ctx)->GetValueAsString().c_str());
1848// //
1849// //
1850// // ObjPtr class3 = ctx.ExecStr(":class3 := :class1, :class2 { func3() := {33}; func4() := {4}; }");
1851// // ASSERT_TRUE(class3);
1852// // ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class3->m_var_type_current);
1853// // ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class3->m_var_type_fixed);
1854// // ASSERT_STREQ(":class3", class3->getName().c_str());
1855// //
1856// // ASSERT_TRUE(ctx.size() > 4) << ctx.Dump("; ").c_str();
1857// // // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1858// // ASSERT_EQ(9, ctx.m_terms->size());
1859// // ASSERT_STREQ("class3::func1", ctx.m_terms->at(4).first.c_str());
1860// // ASSERT_STREQ("class3::func2", ctx.m_terms->at(5).first.c_str());
1861// // ASSERT_STREQ("class3::func_name", ctx.m_terms->at(6).first.c_str());
1862// // ASSERT_STREQ("class3::func3", ctx.m_terms->at(7).first.c_str());
1863// // ASSERT_STREQ("class3::func4", ctx.m_terms->at(8).first.c_str());
1864// // ObjPtr func3_1 = ctx.ExecStr("class3::func1");
1865// // ASSERT_EQ(1, func3_1->Call(&ctx)->GetValueAsInteger());
1866// // ObjPtr func3_2 = ctx.ExecStr("class3::func2");
1867// // ASSERT_EQ(2, func3_2->Call(&ctx)->GetValueAsInteger());
1868// // ObjPtr func3_3 = ctx.ExecStr("class3::func3");
1869// // ASSERT_EQ(33, func3_3->Call(&ctx)->GetValueAsInteger());
1870// // ObjPtr func3_4 = ctx.ExecStr("class3::func4");
1871// // ASSERT_EQ(4, func3_4->Call(&ctx)->GetValueAsInteger());
1872// // ObjPtr result = ctx.ExecStr("class3::func_name()");
1873// // ASSERT_TRUE(result);
1874// // ASSERT_STREQ("func_name", result->GetValueAsString().c_str());
1875// //
1876// //
1877// //
1878// //
1879// // ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1880// // ASSERT_TRUE(var1);
1881// // ObjPtr var1_1 = ctx.ExecStr("var1.func1()");
1882// // ASSERT_TRUE(var1_1);
1883// // ASSERT_EQ(1, var1_1->GetValueAsInteger());
1884// //
1885// //
1886// // ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1887// // ASSERT_TRUE(var2);
1888// // ObjPtr var2_1 = ctx.ExecStr("var2.func1()");
1889// // ASSERT_TRUE(var2_1);
1890// // ASSERT_EQ(1, var2_1->GetValueAsInteger());
1891// // ObjPtr var2_2 = ctx.ExecStr("var2.func2()");
1892// // ASSERT_TRUE(var2_2);
1893// // ASSERT_EQ(2, var2_2->GetValueAsInteger());
1894// //
1895// //
1896// // ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1897// // ASSERT_TRUE(var3);
1898// // ObjPtr var3_1 = ctx.ExecStr("var3.func1()");
1899// // ASSERT_TRUE(var3_1);
1900// // ASSERT_EQ(1, var3_1->GetValueAsInteger());
1901// // ObjPtr var3_2 = ctx.ExecStr("var3.func2()");
1902// // ASSERT_TRUE(var3_2);
1903// // ASSERT_EQ(2, var3_2->GetValueAsInteger());
1904// // ObjPtr var3_3 = ctx.ExecStr("var3.func3()");
1905// // ASSERT_TRUE(var3_3);
1906// // ASSERT_EQ(33, var3_3->GetValueAsInteger());
1907// // ObjPtr var3_4 = ctx.ExecStr("var3.func4()");
1908// // ASSERT_TRUE(var3_4);
1909// // ASSERT_EQ(4, var3_4->GetValueAsInteger());
1910// //
1911// //}
1912// //
1913// //TEST(Oop, ClassProp) {
1914// //
1915// // Context::Reset();
1916// // Context ctx(RunTime::Init());
1917// //
1918// // ASSERT_EQ(0, ctx.m_ns_stack.size());
1919// // ASSERT_EQ(0, ctx.size());
1920// // ASSERT_EQ(0, ctx.m_terms->size());
1921// //
1922// // ASSERT_EQ(0, ctx.size());
1923// //
1924// // ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { prop1 := 1; }");
1925// // ASSERT_TRUE(class1);
1926// // ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1927// // ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1928// // ASSERT_STREQ(":class1", class1->getName().c_str());
1929// // ASSERT_EQ(1, class1->size());
1930// // ASSERT_STREQ("1", class1->at("prop1").second->toString().c_str());
1931// //
1932// // ObjPtr class2 = ctx.ExecStr(":class2 := :class1 { prop2 := 2; }");
1933// // ASSERT_TRUE(class2);
1934// // ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1935// // ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1936// // ASSERT_STREQ(":class2", class2->getName().c_str());
1937// // ASSERT_EQ(2, class2->size());
1938// // ASSERT_STREQ("1", class2->at("prop1").second->toString().c_str());
1939// // ASSERT_STREQ("2", class2->at("prop2").second->toString().c_str());
1940// //
1941// //
1942// // ObjPtr class3 = ctx.ExecStr(":class3 := :class2 { prop1 = 10; }");
1943// // ASSERT_TRUE(class3);
1944// // ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class2->m_var_type_current);
1945// // ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1946// // ASSERT_STREQ(":class3", class3->getName().c_str());
1947// // ASSERT_EQ(2, class3->size());
1948// // ASSERT_STREQ("10", class3->at("prop1").second->toString().c_str());
1949// // ASSERT_STREQ("2", class3->at("prop2").second->toString().c_str());
1950// //
1951// //
1952// // EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_prop2 := :class2 { prop2 ::= 1; }"));
1953// // EXPECT_ANY_THROW(ctx.ExecStr(":class_prop_not_found := :class2 { prop_not_found = 1; }"));
1954// //
1955// //
1956// // ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1957// // ASSERT_TRUE(var1);
1958// // ObjPtr var1_1;
1959// //
1960// // ASSERT_NO_THROW(var1_1 = ctx.ExecStr("var1.prop1")) << ctx.Dump() << " (" << var1->toString() << ")";
1961// //
1962// // ASSERT_TRUE(var1_1);
1963// // ASSERT_EQ(1, var1_1->GetValueAsInteger());
1964// //
1965// //
1966// // ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1967// // ASSERT_TRUE(var2);
1968// // ObjPtr var2_1 = ctx.ExecStr("var2.prop1");
1969// // ASSERT_TRUE(var2_1);
1970// // ASSERT_EQ(1, var2_1->GetValueAsInteger());
1971// // ObjPtr var2_2 = ctx.ExecStr("var2.prop2");
1972// // ASSERT_TRUE(var2_2);
1973// // ASSERT_EQ(2, var2_2->GetValueAsInteger());
1974// //
1975// // ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1976// // ASSERT_TRUE(var3);
1977// // ObjPtr var3_1 = ctx.ExecStr("var3.prop1");
1978// // ASSERT_TRUE(var3_1);
1979// // ASSERT_EQ(10, var3_1->GetValueAsInteger());
1980// // ObjPtr var3_2 = ctx.ExecStr("var3.prop2");
1981// // ASSERT_TRUE(var3_2);
1982// // ASSERT_EQ(2, var3_2->GetValueAsInteger());
1983// //
1984// //
1985// // ObjPtr var4 = ctx.ExecStr("var4 := :class3(prop2=100, prop1=99)");
1986// // ASSERT_TRUE(var4);
1987// // ObjPtr var4_1 = ctx.ExecStr("var4.prop1");
1988// // ASSERT_TRUE(var4_1);
1989// // ASSERT_EQ(99, var4_1->GetValueAsInteger());
1990// // ObjPtr var4_2 = ctx.ExecStr("var4.prop2");
1991// // ASSERT_TRUE(var4_2);
1992// // ASSERT_EQ(100, var4_2->GetValueAsInteger());
1993// //
1994// //
1995// // EXPECT_ANY_THROW(ctx.ExecStr("var_not_found := :class3(prop_not_found=100)"));
1996// // EXPECT_ANY_THROW(ctx.ExecStr("var_bad_type := :class3(prop1='BAD TYPE')"));
1997//
1998//}
1999
2000TEST(Ast, CheckStrPrintf) {
2001
2002 TermPtr args = Term::CreateDict();
2003
2004 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("", args, 0));
2005 args->push_back(Term::CreateName(""));
2006 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("", args, 0));
2007 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("", args, 1));
2008
2009 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s", args, 0));
2010 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s", args, 1));
2011 args->push_back(Term::CreateName(""));
2012 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s", args, 1));
2013 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s", args, 2));
2014
2015 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d", args, 0));
2016 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d", args, 1));
2017 args->push_back(Term::CreateName("1"));
2018 args->back().second->m_type = getDefaultType(ObjType::Int8);
2019 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d", args, 1));
2020 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d", args, 2));
2021
2022 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 0));
2023 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 1));
2024 args->push_back(Term::CreateName("1"));
2025 args->back().second->m_type = getDefaultType(ObjType::Int64);
2026 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 1));
2027 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 1));
2028 args->back().second->m_type = getDefaultType(ObjType::Int32);
2029 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 1));
2030 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 2));
2031
2032 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 0));
2033 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 1));
2034 args->push_back(Term::CreateName("0"));
2035 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 1));
2036 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 2));
2037
2038 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 0));
2039 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 1));
2040 args->push_back(Term::CreateName(""));
2041 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 1));
2042 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 2));
2043
2044
2045 // JIT * jit = JIT::ReCreate();
2046 // ASSERT_TRUE(jit);
2047 //
2048 // ASSERT_ANY_THROW(jit->MakeAst("print()"));
2049 // ASSERT_ANY_THROW(jit->MakeAst("print(123)"));
2050 // ASSERT_ANY_THROW(jit->MakeAst("print('%s - %s', 1, 'test')"));
2051 // ASSERT_ANY_THROW(jit->MakeAst("print('%d - %d', 1, 'test')"));
2052 //
2053 // ASSERT_NO_THROW(jit->MakeAst("print(format='')"));
2054 // ASSERT_NO_THROW(jit->MakeAst("print(format='%d', 1)"));
2055 //
2056 // ASSERT_ANY_THROW(jit->MakeAst("print(format='', 1)"));
2057 // ASSERT_ANY_THROW(jit->MakeAst("print(format='%d', named=1)"));
2058 // ASSERT_ANY_THROW(jit->MakeAst("print(format='%d', __sys__=1)"));
2059 //
2060 // ObjPtr print;
2061 // ASSERT_NO_THROW(print = jit->Run("print(format='\\n')"));
2062 // ASSERT_NO_THROW(print = jit->Run("print('%d - %s\\n', 1, 'test')"));
2063}
2064
2065TEST(Ast, CheckStrFormat) {
2066
2067 TermPtr args = Term::CreateDict();
2068
2069 // ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("", nullptr));
2070 ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("{", *args));
2071
2072 ASSERT_STREQ("", AstAnalysis::ConvertToVFormat_("", *args).c_str());
2073 ASSERT_STREQ("{{", AstAnalysis::ConvertToVFormat_("{{", *args).c_str());
2074 ASSERT_STREQ("format", AstAnalysis::ConvertToVFormat_("format", *args).c_str());
2075 ASSERT_STREQ("{}", AstAnalysis::ConvertToVFormat_("{}", *args).c_str());
2076 ASSERT_STREQ("{1}", AstAnalysis::ConvertToVFormat_("{1}", *args).c_str());
2077 ASSERT_STREQ("{1:}", AstAnalysis::ConvertToVFormat_("{1:}", *args).c_str());
2078 ASSERT_STREQ("{:0}", AstAnalysis::ConvertToVFormat_("{:0}", *args).c_str());
2079 ASSERT_STREQ("{:0}{:0}", AstAnalysis::ConvertToVFormat_("{:0}{:0}", *args).c_str());
2080 ASSERT_STREQ("{1:1}{1:1}", AstAnalysis::ConvertToVFormat_("{1:1}{1:1}", *args).c_str());
2081
2082 ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1", *args));
2083 ASSERT_STREQ("{{{1:1}{1:1}", AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1}", *args).c_str());
2084 ASSERT_STREQ("{{{1:1}{1:1}}}", AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1}}}", *args).c_str());
2085
2086 args->push_back(Term::CreateNone(), "name");
2087 ASSERT_STREQ("{0}", AstAnalysis::ConvertToVFormat_("{name}", *args).c_str());
2088 ASSERT_STREQ("{0}{0}", AstAnalysis::ConvertToVFormat_("{name}{name}", *args).c_str());
2089 ASSERT_STREQ("{0:0}{0:123}{0:0.0}", AstAnalysis::ConvertToVFormat_("{name:0}{0:123}{name:0.0}", *args).c_str());
2090 ASSERT_STREQ("{0}{0}", AstAnalysis::ConvertToVFormat_("{0}{name}", *args).c_str());
2091
2092 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{0}}}", *args).c_str());
2093 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{name}}}", *args).c_str());
2094
2095 ASSERT_STREQ("{{0}{0}}", AstAnalysis::ConvertToVFormat_("{{0}{name}}", *args).c_str());
2096 ASSERT_STREQ("{{{0}{0}}", AstAnalysis::ConvertToVFormat_("{{{0}{name}}", *args).c_str());
2097
2098
2099 args->push_back(Term::CreateNone(), "name2");
2100 ASSERT_STREQ("{0}{1}", AstAnalysis::ConvertToVFormat_("{name}{name2}", *args).c_str());
2101 ASSERT_STREQ("{1}", AstAnalysis::ConvertToVFormat_("{name2}", *args).c_str());
2102 ASSERT_STREQ("{1:0}{1:.0}{0:0.0}", AstAnalysis::ConvertToVFormat_("{name2:0}{1:.0}{name:0.0}", *args).c_str());
2103 ASSERT_STREQ("{1}{0}", AstAnalysis::ConvertToVFormat_("{name2}{name}", *args).c_str());
2104
2105 ASSERT_STREQ("{{name2}{0}}", AstAnalysis::ConvertToVFormat_("{{name2}{name}}", *args).c_str());
2106 ASSERT_STREQ("{{{1}{0}}", AstAnalysis::ConvertToVFormat_("{{{name2}{name}}", *args).c_str());
2107 ASSERT_STREQ("{{{1}}}", AstAnalysis::ConvertToVFormat_("{{{name2}}}", *args).c_str());
2108
2109 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{name}}}", *args).c_str());
2110
2111 args->clear();
2112 ASSERT_TRUE(!args->size());
2113
2114 ASSERT_STREQ("", AstAnalysis::MakeFormat("", args, nullptr). c_str());
2115 ASSERT_ANY_THROW(AstAnalysis::MakeFormat("{", args, nullptr));
2116 ASSERT_STREQ("{", AstAnalysis::MakeFormat("{{", args, nullptr). c_str());
2117
2118 ASSERT_NO_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{}}", args, nullptr). c_str()));
2119 ASSERT_ANY_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{{}}}", args, nullptr). c_str()));
2120
2121 args->push_back(Term::CreateNone(), "none");
2122 ASSERT_NO_THROW(ASSERT_STREQ("{_}", AstAnalysis::MakeFormat("{{{}}}", args, nullptr). c_str()));
2123 ASSERT_NO_THROW(ASSERT_STREQ("{_}", AstAnalysis::MakeFormat("{{{none}}}", args, nullptr). c_str()));
2124
2125
2126 ASSERT_NO_THROW(ASSERT_STREQ("_", AstAnalysis::MakeFormat("{none}", args, nullptr). c_str()));
2127
2128 args->push_back(Term::CreateName("string", TermID::STRCHAR), "str");
2129 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{str}", args, nullptr). c_str()));
2130
2131 args->push_back(Term::CreateName("123", TermID::STRCHAR), "int");
2132 ASSERT_NO_THROW(ASSERT_STREQ("'123'", AstAnalysis::MakeFormat("{int}", args, nullptr). c_str()));
2133
2134 ASSERT_NO_THROW(ASSERT_STREQ("_", AstAnalysis::MakeFormat("{}", args, nullptr). c_str()));
2135 ASSERT_NO_THROW(ASSERT_STREQ("_'string'", AstAnalysis::MakeFormat("{}{}", args, nullptr). c_str()));
2136 ASSERT_NO_THROW(ASSERT_STREQ("_'string''123'", AstAnalysis::MakeFormat("{}{}{}", args, nullptr). c_str()));
2137
2138 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{1}", args, nullptr). c_str()));
2139 ASSERT_NO_THROW(ASSERT_STREQ("_'string'_", AstAnalysis::MakeFormat("{0}{1}{0}", args, nullptr). c_str()));
2140 ASSERT_NO_THROW(ASSERT_STREQ("'string''123'_", AstAnalysis::MakeFormat("{1}{2}{none}", args, nullptr). c_str()));
2141
2142 ASSERT_NO_THROW(ASSERT_STREQ("_'string''123'_", AstAnalysis::MakeFormat("{none}{str}{int}{none}", args, nullptr). c_str()));
2143}
2144
2145TEST(Ast, MakeInclude) {
2146
2147 std::string str;
2148 str = AstAnalysis::MakeInclude(Term::CreateName("name"));
2149 ASSERT_STREQ("", str.c_str());
2150
2151 str = AstAnalysis::MakeInclude(ParseString("::val := 1;"));
2152 ASSERT_STREQ("::val := ...;\n", str.c_str());
2153
2154 str = AstAnalysis::MakeInclude(ParseString("::val := 1; $val2 := 1; @::val3 := 1; val4 := 1;"));
2155 ASSERT_STREQ("::val := ...;\n@::val3 := ...;\nval4 := ...;\n", str.c_str());
2156
2157 str = AstAnalysis::MakeInclude(ParseString("::val, val2, @::val3 := 1; $val4 := 1;"));
2158 ASSERT_STREQ("::val := ...;\nval2 := ...;\n@::val3 := ...;\n", str.c_str());
2159
2160 str = AstAnalysis::MakeInclude(ParseString("@@ macro @@ := 1; @@ macro2 @@ := @@ 2 @@; @@@@ macro @@@@;"));
2161 ASSERT_STREQ("@@ macro @@ := 1;\n@@ macro2 @@ := @@ 2 @@;\n@@@@ macro @@@@;\n", str.c_str());
2162
2163}
2164#endif // UNITTEST
std::string Dump(const std::string_view filter="", const char delim=';')
Definition types.cpp:314
ParserPtr GetParser()
Definition jit.cpp:2535
DiagPtr m_diag
Definition runtime.h:402
std::map< std::string, StorageTerm > ModuleMapType
Definition term.h:172
Definition nlc.h:59
const TermPtr getDefaultType(const std::string_view text)
Definition parser.cpp:1072
std::vector< std::string > PostLexerType
Definition types.h:255
std::string ExtractName(std::string name)
Definition types.h:1223
std::shared_ptr< Term > TermPtr
Definition variable.h:33
std::shared_ptr< RunTime > RuntimePtr
Definition types.h:242
std::string ExtractModuleName(const std::string_view name)
Definition types.h:1188
std::shared_ptr< Macro > MacroPtr
Definition types.h:244
std::shared_ptr< Diag > DiagPtr
Definition types.h:243