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 "module.h"
10#include "runtime.h"
11#include "analysis.h"
12#include "jit.h"
13
14using namespace newlang;
15
16/* Проблема совместного использования namespace и декораторов имен.
17 *
18 * Дектораторы имен ($ и @) импользуютсядля указания области видимости и времени жизни объектов.
19 * $ - локальные объекты, размещаемые "условно" на стеке. Удаляются по мере выхода из текущей области видимости.
20 * Локальный объект скрывает другие локальные и глобальные объекты с таким же именем.
21 * @ - глобальные объекты, размещаемые "условно" в куче и их время жизни не зависит от текущей области видимости.
22 * Глобальный объект заменяет другой глобальный объект с таким же именем.
23 *
24 * Namespace позволяют использовать одинаковые имена объектов разделяя для них области видимости,
25 * но можно ли совместить и использовтаь namespace и дектораторы одновременно?
26 *
27 * $local; @global;
28 * $name::local; \\name::global;
29 * но ns {
30 * $name::local; # Будет $ns::name::local
31 * \\name::global; # Все равно \\name::global или тоже \\ns::name::global ????
32 * }
33 * тогда без указания области видимости (без начального символа "::", т.е. name::var - объект выбирается автоматически,
34 * т.е. сперва ищется локальный объект с таким именем, потом глобальный)
35 * Какая разница между ::name::var и name::var?
36 * Первый в глобальной области видимости, второй в текущей?
37 *
38 * $var := 0; # ::var или $var
39 * @func() := {0}; # ::func или @func - 0
40 * name {
41 * $var := 1; # ::name::var
42 * $func() := {11}; # локальная с именем - ::name::func
43 * @func() := {111}; # глобальная с именем - @func
44 * \\name::func() := {1111}; # глобальная \\name::func и тоже самое, что и локальная $func() !!!
45 * name {
46 * var := 2; # ::name::name::var или $var или \\name::name::var
47 * @var := 2; # ::var
48 * \\name::name::var := 2; # ::name::name::var или \\name::name::var
49 * func() := {2}; # ::name::name::func или \\name::name::func - 2
50 * name3 {
51 * var := 3; # ::name::name::name3::var или $name::name::name3::var - 3
52 * func() := {3}; # ::name::name::name3::func или \\name::name::name3::func() - 3
53 *
54 * var??; # name::name::name3::var или $name::name::name3::var - 3
55 * name::var??; # name::name::var или \\name::name::var - 2
56 * name::name::var??; # name::var или \\name::name::var - 2
57 * ::name::var??; # name::var или $name::var - 1
58 * ::var??; # ::var или $var - 0
59 * }
60 * }
61 * }
62 * Предположим, что: <<<<<<<<<<<<<<< НЕ АКТУАЛЬНО после изменения ситаксиса мароксов !!!!!!!!!!!!!!!!!!!!!!!!!! >>>>>>>>>>>
63 * :: - глобальный корень. Может быть заменен на @ или $
64 * @@ — родительская функция после её переопределния
65 * $$ — родительский объект
66 * тогда:
67 * $$.field - поле родительского класса
68 * @@() - вызов переопределенной функции текущего класса или области видимости
69 * @func() []= {@@() + 10}; # @func - 10
70 * ::name::name@func
71 * \\name::name::func - такая запись ненравится, но будет самой правильной и логичной, так как все остальные еще хуже для понимания и разбора
72 * @::name::name::func
73 * @::name::name@func
74 * ::name::name::func@@
75 *
76 * <<<<<<<<<<<<<<<<<< НОВАЯ КОНЦЕПЦИЯ >>>>>>>>>>>>>>>>>>
77 *
78 * Все объекты физически размещаюится в куче, но время их жизни определяется областью видимости.
79 * Объекты с декораторами $ обозначают локальные объекты (аналог "на стеке") и они удаляются по мере выхода из текущей области видимости.
80 * Объекты с декораторами @ являются модулями или его объектами, доступны из других частй программы и сохраняют состояние при выходе из текущей области видимости.
81 *
82 * Указание модуля (имя файла) @file или @dir.file или @dir1.dir2.file
83 * Указание объекта в модуле @file::var или @dir.file::ns::func() или @dir.file::ns::obj.field; @file::ns:type @file::ns$local ???
84 *
85 * Файл модуля загружается однократно при первом обращении и не выгружается до явной команды???
86 * @module <*>;
87 * @dir.module2 <*>; # Импорт всех функций модуля (кроме начинающихся на подчерк)
88 * @dir.module2 <ns::name::*>; # Импорт всех функций из указанной области имен (кроме начинающихся на подчерк)
89 * @dir.module2 <map=ns::name::*>; # Импорт всех функций из указанной области имен с переименованием (кроме начинающихся на подчерк)
90 * @dir.module2 <func1, func2=::module2::ns::name::func2>; # Импорт только конкретных функций + переименование
91 * @dir.module2 <_>; # Выгрузить модуль?????
92 *
93 * \\ns ::name::space::long@\
94 * \ns::name;
95 *
96 * @dsl{}; # Загрузка модуля с определниями макросов для DSL в самом начале любой программы?
97 *
98 * @@ - главный модуль
99 * @$ - текущий модуль
100 * $$ - родительский объект (базовый объект или переопределяемая функция)
101 * $0 - текущий объект (this)
102 *
103 * [@$.__main__] --> { # 1 или 0
104 *
105 * }
106 * @$.__@@__ := {}; # Деструктор модуля
107 * __@@__ := {}; # Деструктор модуля
108 *
109 * \destructor() { // _____ ::=
110 * }
111 *
112 *
113 * Дектораторы имен ($ и @) импользуютсядля указания области видимости и времени жизни объектов.
114 * $ - локальные объекты, размещаемые "условно" на стеке. Удаляются по мере выхода из текущей области видимости.
115 * Локальный объект скрывает другие локальные и глобальные объекты с таким же именем.
116 * @ - глобальные объекты, размещаемые "условно" в куче и их время жизни не зависит от текущей области видимости.
117 * Глобальный объект заменяет другой глобальный объект с таким же именем.
118 *
119 * Namespace позволяют использовать одинаковые имена объектов разделяя для них области видимости,
120 * но можно ли совместить и использовтаь namespace и дектораторы одновременно?
121 *
122 *
123 * Наследование
124 * Часто композиция класса более подходяща, чем наследование. Когда используйте наследование, делайте его открытым (public).
125 * Когда дочерний класс наследуется от базового, он включает определения всех данных и операций от базового. "Наследование интерфейса" - это наследование от чистого абстрактного базового класса (в нём не определены состояние или методы). Всё остальное - это "наследование реализации".
126 * Наследование реализации уменьшает размер кода благодаря повторному использованию частей базового класса (который становится частью нового класса). Т.к. наследование является декларацией времени компиляции, это позволяет компилятору понимать структуру и находить ошибки. Наследование интерфейса может быть использовано чтобы класс поддерживал требуемый API. И также, компилятор может находить ошибки, если класс не определяет требуемый метод наследуемого API.
127 * В случае наследования реализации, код начинает размазываться между базовым и дочерним классом и это может усложнить понимание кода. Также, дочерний класс не может переопределять код невиртуальных функций (не может менять их реализацию).
128 * Множественное наследование ещё более проблемное, а также иногда приводит к уменьшению производительности. Часто просадка производительности при переходе от одиночного наследования к множественному может быть больше, чем переход от обычных функций к виртуальным. Также от множественного наследования один шаг до ромбического, а это уже ведёт к неопределённости, путанице и, конечно же, багам.
129 * Любое наследование должно быть открытым (public). Если хочется сделать закрытое (private), то лучше добавить новый член с экземпляром базового класса.
130 * Не злоупотребляйте наследованием реализации. Композиция классов часто более предпочтительна. Попытайтесь ограничить использование наследования семантикой "Является": Bar можно наследовать от Foo, если можно сказать, что Bar "Является" Foo (т.е. там, где используется Foo, можно также использовать и Bar).
131 * Защищёнными (protected) делайте лишь те функции, которые должны быть доступны для дочерних классов. Заметьте, что данные должны быть закрытыми (private).
132 * Явно декларируйте переопределение виртуальных функций/деструктора с помошью спецификаторов: либо override, либо (если требуется) final. Не используйте спецификатор virtual при переопределении функций. Объяснение: функция или деструктор, помеченные override или final, но не являющиеся виртуальными просто не скомпилируются (что помогает обнаружить общие ошибки). Также спецификаторы работают как документация; а если спецификаторов нет, то программист будет вынужден проверить всю иерархию, чтобы уточнить виртуальность функции.
133 * Множественное наследование <интерфейсов> допустимо, однако множественное наследование реализации не рекомендуется от слова совсем.
134 *
135 * Для замены множественного наследования можно исопльзовать оператор утиной типизации (сравнения интерфейсов)
136 *
137 * Конструкторы и деструкторы классов
138 *
139 * Конструктор у класса может быть только один - и это обычная функция с именем класса.
140 * Конструктор должен вернуть созданный экземпляр класса, который ему передается в $0 аргументе.
141 * Другие аргументы соотетствуют передаваемым при вызове конструктора.
142 * Конструктор по умолчанию принимает произвольное количество аргументов (для переопределения значения у
143 * свойств по время вызова конструтокра) и возвращает аргумент $0, т.е. constructor(...) :- {$0($*)};
144 * Пользователський конструтор лучше переопреелять в теле класса через оператор присвоения значения,
145 * аналог override, т.е. constructor(...) **=** {...}; (чтобы исключить ошибки в написании имени функции).
146 * Конструторы базовых классов автоматически не вызываются, и если это требуется по логике работы,
147 * то вызовы конструторов базовых классов необходимо выполнять вручную, например так: $0 = $$.base_constructor();
148 *
149 * Деструктор класса определяется в теле класса анонимной функицей (имя функци подчерк),
150 * т.е. _() :- {} и по умолчанию отсутствует. Деструткоры базовых классов вызываются автоматически?????
151 *
152
153 - Расширен список имен базовых типов данных для более точного указания нативной функций С++ при её импорте.
154- Добавлен признак константности объекта (символ карет в конце имени), причем идентификатор константы частью имени не является.
155- Оператор добавления элемента в словарь или тензор "[]="
156- С помощью операторов добавления "[]=" и обращения к родительскому обекту "$$" реализована возможность перегрузки и отката перегрузки функции
157- Документирование свойств и методов ?????
158
159 *
160 */
161TEST(Ast, Mangling) {
162 ASSERT_STREQ("name", ExtractName("name").c_str());
163 ASSERT_STREQ("name", ExtractName("::name").c_str());
164 ASSERT_STREQ("name", ExtractName("ns::name").c_str());
165 ASSERT_STREQ("", ExtractName("\\file").c_str());
166 ASSERT_STREQ("", ExtractName("\\\\dir.file").c_str());
167 ASSERT_STREQ("var", ExtractName("\\dir.file::var").c_str());
168 ASSERT_STREQ("var.field", ExtractName("\\\\dir.file::var.field").c_str());
169
170
171 ASSERT_STREQ("\\file", ExtractModuleName("\\file").c_str());
172 ASSERT_STREQ("\\\\dir.file", ExtractModuleName("\\\\dir.file").c_str());
173 ASSERT_STREQ("\\dir.file", ExtractModuleName("\\dir.file::var").c_str());
174 ASSERT_STREQ("\\\\dir.file", ExtractModuleName("\\\\dir.file::var.field").c_str());
175
176 ASSERT_STREQ("", ExtractModuleName("").c_str());
177 ASSERT_STREQ("", ExtractModuleName("_$$_").c_str());
178 ASSERT_STREQ("\\\\file", ExtractModuleName("_$file$_").c_str());
179 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file_dir$_").c_str());
180 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file_dir$_var$").c_str());
181 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file_dir$_var$$").c_str());
182 ASSERT_STREQ("\\\\file\\dir", ExtractModuleName("_$file_dir$_var$$$").c_str());
183}
184
185TEST(Ast, ScopeStack) {
186
187 StorageTerm storage;
188 ScopeStack ns_stack(storage);
189 ASSERT_EQ(ns_stack.m_static, storage);
190
191 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
192 ASSERT_STREQ("name1$", ns_stack.CreateVarName("name1").c_str());
193 ASSERT_STREQ("name1$", ns_stack.CreateVarName("$name1").c_str());
194 ASSERT_STREQ("name1:::", ns_stack.CreateVarName(":name1").c_str());
195
196 ASSERT_STREQ("Storage: \n", ns_stack.Dump().c_str());
197 ns_stack.PushScope(nullptr);
198
199 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
200 ASSERT_STREQ("1::name1$", ns_stack.CreateVarName("name1").c_str());
201 ASSERT_STREQ("1::name1$", ns_stack.CreateVarName("$name1").c_str());
202 ASSERT_STREQ("name1:::", ns_stack.CreateVarName(":name1").c_str());
203
204 ns_stack.back().vars.insert({"name1", Term::Create(parser::token_type::NAME, TermID::NAME, "term_name1")});
205 ns_stack.back().vars.insert({"name2", Term::Create(parser::token_type::NAME, TermID::NAME, "term_name2")});
206
207 ns_stack.PushScope(Term::Create(parser::token_type::NAME, TermID::NAME, "ns"));
208 ns_stack.back().vars.insert({"name3", Term::Create(parser::token_type::NAME, TermID::NAME, "term_name3")});
209
210 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
211 ASSERT_STREQ("1::ns::name1$", ns_stack.CreateVarName("name1").c_str());
212 ASSERT_STREQ("1::ns::name1$", ns_stack.CreateVarName("$name1").c_str());
213 ASSERT_STREQ("ns::name1:::", ns_stack.CreateVarName(":name1").c_str());
214
215
216 storage.insert({"name4", Term::Create(parser::token_type::NAME, TermID::NAME, "term_name4")});
217 storage.insert({"name5", Term::Create(parser::token_type::NAME, TermID::NAME, "term_name5")});
218
219 ASSERT_STREQ("Storage: name4, name5\nStack [1::]: name1, name2\nStack [ns::]: name3\n", ns_stack.Dump().c_str());
220 storage.clear();
221 ns_stack.clear();
222
223 // ...
224 ASSERT_EQ(0, ns_stack.size());
225 ASSERT_STREQ("", ns_stack.GetNamespace().c_str());
226
227 ASSERT_FALSE(ns_stack.LookupName("name1"));
228 ASSERT_FALSE(ns_stack.LookupName("$name1"));
229 ASSERT_FALSE(ns_stack.LookupName("::name1"));
230
231 TermPtr name1 = Term::Create(parser::token_type::NAME, TermID::NAME, "name1");
232 ASSERT_EQ(0, storage.size()) << ns_stack.Dump();
233 ASSERT_TRUE(storage.find("$name1") == storage.end()) << ns_stack.Dump();
234
235 name1->m_int_name = ns_stack.CreateVarName(name1->m_text);
236 ASSERT_TRUE(ns_stack.AddName(name1)) << ns_stack.Dump();
237
238 ASSERT_EQ(0, ns_stack.size());
239 ASSERT_EQ(1, storage.size()) << ns_stack.Dump();
240 ASSERT_TRUE(storage.find("name1$") != storage.end()) << ns_stack.Dump();
241
242 ASSERT_STREQ("name1$", name1->m_int_name.c_str());
243 TermPtr temp1;
244 ASSERT_TRUE(temp1 = ns_stack.LookupName("name1")) << ns_stack.Dump();
245 ASSERT_EQ(temp1.get(), name1.get());
246 ASSERT_TRUE(temp1 = ns_stack.LookupName("$name1")) << ns_stack.Dump();
247 ASSERT_EQ(temp1.get(), name1.get());
248 ASSERT_FALSE(ns_stack.LookupName("::name1")) << ns_stack.Dump();
249
250 // name { ... }
251 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "name"));
252 ASSERT_EQ(1, ns_stack.size());
253 ASSERT_STREQ("name::", ns_stack.GetNamespace().c_str());
254
255
256 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
257 ASSERT_STREQ("name::name1$", ns_stack.CreateVarName("name1").c_str());
258 ASSERT_STREQ("name::name1$", ns_stack.CreateVarName("$name1").c_str());
259 ASSERT_STREQ("name::name1:::", ns_stack.CreateVarName(":name1").c_str());
260
261
262 TermPtr name2 = Term::Create(parser::token_type::NAME, TermID::NAME, "name2");
263 ASSERT_EQ(1, ns_stack.size()) << ns_stack.Dump();
264 ASSERT_EQ(1, storage.size()) << ns_stack.Dump();
265 ASSERT_TRUE(storage.find("$name2") == storage.end()) << ns_stack.Dump();
266 ASSERT_TRUE(ns_stack[0].vars.find("$name2") == ns_stack[0].vars.end()) << ns_stack.Dump();
267
268 name2->m_int_name = ns_stack.CreateVarName(name2->m_text);
269 ASSERT_TRUE(ns_stack.AddName(name2)) << ns_stack.Dump();
270
271 ASSERT_STREQ("name2", name2->m_text.c_str());
272 TermPtr temp2;
273 ASSERT_TRUE(temp2 = ns_stack.LookupName("name2")) << ns_stack.Dump();
274 ASSERT_EQ(temp2.get(), name2.get());
275 ASSERT_TRUE(temp2 = ns_stack.LookupName("$name2")) << ns_stack.Dump();
276 ASSERT_EQ(temp2.get(), name2.get());
277 ASSERT_FALSE(ns_stack.LookupName("::name2")) << ns_stack.Dump();
278
279 TermPtr temp;
280 ASSERT_TRUE(temp = ns_stack.LookupName("name1")) << ns_stack.Dump();
281 ASSERT_EQ(temp.get(), name1.get());
282 ASSERT_TRUE(temp = ns_stack.LookupName("$name1")) << ns_stack.Dump();
283 ASSERT_EQ(temp.get(), name1.get());
284
285
286 // name { {...} }
287 ns_stack.PushScope(nullptr);
288 ASSERT_EQ(2, ns_stack.size());
289
290 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
291 ASSERT_STREQ("name::2::name1$", ns_stack.CreateVarName("name1").c_str());
292 ASSERT_STREQ("name::2::name1$", ns_stack.CreateVarName("$name1").c_str());
293 ASSERT_STREQ("name::name1:::", ns_stack.CreateVarName(":name1").c_str());
294
295
296 TermPtr name3 = Term::Create(parser::token_type::NAME, TermID::NAME, "$name3");
297 ASSERT_EQ(2, ns_stack.size()) << ns_stack.Dump();
298 ASSERT_EQ(2, storage.size()) << ns_stack.Dump();
299 ASSERT_TRUE(ns_stack[1].vars.find("$name3") == ns_stack[1].vars.end()) << ns_stack.Dump();
300
301 name3->m_int_name = ns_stack.CreateVarName(name3->m_text);
302 ASSERT_TRUE(ns_stack.AddName(name3)) << ns_stack.Dump();
303
304 ASSERT_STREQ("$name3", name3->m_text.c_str());
305 TermPtr temp3;
306 ASSERT_TRUE(temp3 = ns_stack.LookupName("name3")) << ns_stack.Dump();
307 ASSERT_EQ(temp3.get(), name3.get());
308 ASSERT_TRUE(temp3 = ns_stack.LookupName("$name3")) << ns_stack.Dump();
309 ASSERT_EQ(temp3.get(), name3.get());
310 ASSERT_FALSE(ns_stack.LookupName("::name3")) << ns_stack.Dump();
311
312 ASSERT_TRUE(temp = ns_stack.LookupName("name1")) << ns_stack.Dump();
313 ASSERT_EQ(temp.get(), name1.get());
314 ASSERT_TRUE(temp = ns_stack.LookupName("$name1")) << ns_stack.Dump();
315 ASSERT_EQ(temp.get(), name1.get());
316
317 ASSERT_TRUE(temp = ns_stack.LookupName("name2")) << ns_stack.Dump();
318 ASSERT_EQ(temp.get(), name2.get());
319 ASSERT_TRUE(temp = ns_stack.LookupName("$name2")) << ns_stack.Dump();
320 ASSERT_EQ(temp.get(), name2.get());
321
322
323 // name { { name2 {...} } }
324 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "name2"));
325 ASSERT_EQ(3, ns_stack.size());
326 ASSERT_STREQ("name::2::name2::", ns_stack.GetNamespace(false).c_str());
327 ASSERT_STREQ("name::name2::", ns_stack.GetNamespace(true).c_str());
328
329 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
330 ASSERT_STREQ("name::2::name2::name1$", ns_stack.CreateVarName("name1").c_str());
331 ASSERT_STREQ("name::2::name2::name1$", ns_stack.CreateVarName("$name1").c_str());
332 ASSERT_STREQ("name::name2::name1:::", ns_stack.CreateVarName(":name1").c_str());
333
334 TermPtr name4 = Term::Create(parser::token_type::NAME, TermID::NAME, "name4");
335 ASSERT_EQ(3, ns_stack.size()) << ns_stack.Dump();
336 ASSERT_EQ(3, storage.size()) << ns_stack.Dump();
337 ASSERT_TRUE(ns_stack[2].vars.find("$name4") == ns_stack[2].vars.end()) << ns_stack.Dump();
338
339 name4->m_int_name = ns_stack.CreateVarName(name4->m_text);
340 ASSERT_TRUE(ns_stack.AddName(name4)) << ns_stack.Dump();
341
342 ASSERT_TRUE(temp = ns_stack.LookupName("name4")) << ns_stack.Dump();
343 ASSERT_EQ(temp.get(), name4.get()) << ns_stack.Dump();
344 ASSERT_TRUE(temp = ns_stack.LookupName("$name4")) << ns_stack.Dump();
345 ASSERT_EQ(temp.get(), name4.get()) << ns_stack.Dump();
346
347 ASSERT_TRUE(temp = ns_stack.LookupName("name1")) << ns_stack.Dump();
348 ASSERT_EQ(temp.get(), name1.get()) << ns_stack.Dump();
349 ASSERT_TRUE(temp = ns_stack.LookupName("$name1")) << ns_stack.Dump();
350 ASSERT_EQ(temp.get(), name1.get()) << ns_stack.Dump();
351
352 ASSERT_TRUE(temp = ns_stack.LookupName("name2")) << ns_stack.Dump();
353 ASSERT_EQ(temp.get(), name2.get()) << temp->toString() << " " << name2->toString() << " " << ns_stack.Dump();
354 ASSERT_TRUE(temp = ns_stack.LookupName("$name2")) << ns_stack.Dump();
355 ASSERT_EQ(temp.get(), name2.get()) << ns_stack.Dump();
356
357 ASSERT_TRUE(temp = ns_stack.LookupName("name3")) << ns_stack.Dump();
358 ASSERT_EQ(temp.get(), name3.get()) << ns_stack.Dump();
359 ASSERT_TRUE(temp = ns_stack.LookupName("$name3")) << ns_stack.Dump();
360 ASSERT_EQ(temp.get(), name3.get()) << ns_stack.Dump();
361
362
363
364 // name { { name2 { name3::name4 {...} } } }
365 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "name3::name4"));
366 ASSERT_EQ(4, ns_stack.size());
367 ASSERT_STREQ("name::2::name2::name3::name4::", ns_stack.GetNamespace().c_str());
368
369 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
370 ASSERT_STREQ("name::2::name2::name3::name4::name1$", ns_stack.CreateVarName("name1").c_str());
371 ASSERT_STREQ("name::2::name2::name3::name4::name1$", ns_stack.CreateVarName("$name1").c_str());
372 ASSERT_STREQ("name::name2::name3::name4::name1:::", ns_stack.CreateVarName(":name1").c_str());
373
374 // name { { name2 { name3::name4 { ::{...} } } } }
375 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "::"));
376 ASSERT_EQ(5, ns_stack.size());
377 ASSERT_STREQ("::", ns_stack.GetNamespace(false).c_str());
378 ASSERT_STREQ("::", ns_stack.GetNamespace(true).c_str());
379 // ASSERT_STREQ("::name", ns_stack.GetFullName("name").c_str());
380
381 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
382 ASSERT_STREQ("::name1$", ns_stack.CreateVarName("name1").c_str());
383 ASSERT_STREQ("::name1$", ns_stack.CreateVarName("$name1").c_str());
384 ASSERT_STREQ("::name1:::", ns_stack.CreateVarName(":name1").c_str());
385
386 // name { { name2 { name3::name4 { ::{ {...} } } } } }
387 ns_stack.PushScope(nullptr);
388 ASSERT_EQ(6, ns_stack.size());
389
390 ASSERT_STREQ("::3::", ns_stack.GetNamespace(false).c_str());
391 ASSERT_STREQ("::", ns_stack.GetNamespace(true).c_str());
392
393 ASSERT_STREQ("::name1::", ns_stack.CreateVarName("::name1").c_str());
394 ASSERT_STREQ("::3::name1$", ns_stack.CreateVarName("name1").c_str());
395 ASSERT_STREQ("::3::name1$", ns_stack.CreateVarName("$name1").c_str());
396 ASSERT_STREQ("::name1:::", ns_stack.CreateVarName(":name1").c_str());
397
398
399 TermPtr name_g = Term::Create(parser::token_type::NAME, TermID::NAME, "@::name_g");
400 ASSERT_EQ(6, ns_stack.size()) << ns_stack.Dump();
401 ASSERT_EQ(4, storage.size()) << ns_stack.Dump();
402 ASSERT_TRUE(storage.find("::name_g") == storage.end()) << ns_stack.Dump();
403 ASSERT_TRUE(ns_stack[5].vars.find("$name4") == ns_stack[5].vars.end()) << ns_stack.Dump();
404
405 name_g->m_int_name = ns_stack.CreateVarName(name_g->m_text);
406 ASSERT_TRUE(ns_stack.AddName(name_g)) << ns_stack.Dump();
407
408 ASSERT_EQ(5, storage.size()) << ns_stack.Dump();
409 ASSERT_TRUE(storage.find("::3::name_g::") != storage.end()) << ns_stack.Dump();
410 ASSERT_TRUE(ns_stack[5].vars.find("::3::name_g::") != ns_stack[5].vars.end()) << ns_stack.Dump();
411
412 ASSERT_STREQ("::3::name_g::", name_g->m_int_name.c_str());
413
414 ASSERT_TRUE(temp = ns_stack.LookupName("name_g")) << ns_stack.Dump();
415 ASSERT_EQ(temp.get(), name_g.get());
416 ASSERT_FALSE(temp = ns_stack.LookupName("$name_g")) << ns_stack.Dump();
417 ASSERT_FALSE(ns_stack.LookupName("::name_g")) << ns_stack.Dump();
418 ASSERT_TRUE(temp = ns_stack.LookupName("@::name_g")) << ns_stack.Dump();
419 ASSERT_EQ(temp.get(), name_g.get());
420
421 ASSERT_TRUE(temp = ns_stack.LookupName("name1")) << ns_stack.Dump();
422 ASSERT_EQ(temp.get(), name1.get());
423 ASSERT_TRUE(temp = ns_stack.LookupName("$name1")) << ns_stack.Dump();
424 ASSERT_EQ(temp.get(), name1.get());
425
426 ASSERT_TRUE(temp = ns_stack.LookupName("name2")) << ns_stack.Dump();
427 ASSERT_EQ(temp.get(), name2.get());
428 ASSERT_TRUE(temp = ns_stack.LookupName("$name2")) << ns_stack.Dump();
429 ASSERT_EQ(temp.get(), name2.get());
430
431 ASSERT_TRUE(temp = ns_stack.LookupName("name3")) << ns_stack.Dump();
432 ASSERT_EQ(temp.get(), name3.get());
433 ASSERT_TRUE(temp = ns_stack.LookupName("$name3")) << ns_stack.Dump();
434 ASSERT_EQ(temp.get(), name3.get());
435
436 ASSERT_TRUE(temp = ns_stack.LookupName("name_g")) << ns_stack.Dump();
437 ASSERT_EQ(temp.get(), name_g.get());
438 ASSERT_FALSE(temp = ns_stack.LookupName("$name_g")) << ns_stack.Dump();
439 ASSERT_FALSE(temp = ns_stack.LookupName("::name_g")) << ns_stack.Dump();
440 ASSERT_TRUE(temp = ns_stack.LookupName("@::name_g")) << ns_stack.Dump();
441 ASSERT_EQ(temp.get(), name_g.get());
442
443
444
445
446
447 // name { { name2 { name3::name4 { ::{ { ::name5::name6 {...} } } } } } }
448 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "::name5::name6"));
449 ASSERT_EQ(7, ns_stack.size());
450 ASSERT_STREQ("::name5::name6::", ns_stack.GetNamespace().c_str());
451
452 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ::{ ... } } } } } } } }
453 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "::"));
454 ASSERT_STREQ("::", ns_stack.GetNamespace().c_str());
455
456 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ::{ name7 {...} } } } } } } } }
457 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "name7"));
458 ASSERT_EQ(9, ns_stack.size());
459 ASSERT_STREQ("::name7::", ns_stack.GetNamespace().c_str());
460
461 // name { { name2 { name3::name4 { ::{ { ::name5::name6 { ... } } } } } } }
462 ns_stack.PopScope();
463 ns_stack.PopScope();
464 ASSERT_EQ(7, ns_stack.size());
465 ASSERT_STREQ("::name5::name6::", ns_stack.GetNamespace().c_str());
466
467 // name { { name2 { name3::name4 { ::{ { ... } } } } } }
468 ns_stack.PopScope();
469 ASSERT_EQ(6, ns_stack.size());
470 ASSERT_STREQ("::", ns_stack.GetNamespace(true).c_str()) << ns_stack.Dump();
471 ASSERT_STREQ("::3::", ns_stack.GetNamespace(false).c_str()) << ns_stack.Dump();
472
473 // name { { name2 { name3::name4 { ::{ ... } } } } }
474 ns_stack.PopScope();
475 ASSERT_EQ(5, ns_stack.size());
476 ASSERT_STREQ("::", ns_stack.GetNamespace(true).c_str()) << ns_stack.Dump();
477 ASSERT_STREQ("::", ns_stack.GetNamespace(false).c_str()) << ns_stack.Dump();
478
479 // name { { name2 { name3::name4 { ... } } } }
480 ns_stack.PopScope();
481 ASSERT_EQ(4, ns_stack.size());
482 ASSERT_STREQ("name::name2::name3::name4::", ns_stack.GetNamespace(true).c_str());
483 ASSERT_STREQ("name::2::name2::name3::name4::", ns_stack.GetNamespace(false).c_str());
484
485 // name { { name2 { ... } } }
486 ns_stack.PopScope();
487 ASSERT_EQ(3, ns_stack.size());
488 ASSERT_STREQ("name::name2::", ns_stack.GetNamespace(true).c_str());
489 ASSERT_STREQ("name::2::name2::", ns_stack.GetNamespace(false).c_str());
490
491 // name { { ... } }
492 ns_stack.PopScope();
493 ASSERT_EQ(2, ns_stack.size());
494 ASSERT_STREQ("name::", ns_stack.GetNamespace(true).c_str());
495 ASSERT_STREQ("name::2::", ns_stack.GetNamespace(false).c_str());
496
497
498 // name { ... }
499 ns_stack.PopScope();
500 ASSERT_EQ(1, ns_stack.size());
501 ASSERT_STREQ("name::", ns_stack.GetNamespace(true).c_str());
502 ASSERT_STREQ("name::", ns_stack.GetNamespace(false).c_str());
503
504 // -
505 ns_stack.PopScope();
506 ASSERT_EQ(0, ns_stack.size());
507 ASSERT_STREQ("", ns_stack.GetNamespace(true).c_str());
508 ASSERT_STREQ("", ns_stack.GetNamespace(false).c_str());
509
510 // ns::name { ... }
511 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "ns::name"));
512 ASSERT_EQ(1, ns_stack.size());
513 ASSERT_STREQ("ns::name::", ns_stack.GetNamespace().c_str());
514
515
516 // ns::name { ::{ ... } }
517 ns_stack.PushScope(Term::Create(parser::token_type::NAMESPACE, TermID::NAMESPACE, "::"));
518 ASSERT_EQ(2, ns_stack.size());
519 ASSERT_STREQ("::", ns_stack.GetNamespace().c_str());
520
521 // ns::name { ... }
522 ns_stack.PopScope();
523 // ...
524 ns_stack.PopScope();
525 ASSERT_EQ(0, ns_stack.size());
526
527}
528
529TEST(Ast, AstAnalyze) {
530
531 RuntimePtr rt = RunTime::Init();
532 ASSERT_TRUE(rt);
533 JitPtr jit = JIT::Init(*rt);
534
535 AstAnalysis analysis(*rt, rt->m_diag.get());
536
537 TermPtr ast = jit->GetParser()->Parse("var1 ::= '1';");
538
539 ASSERT_TRUE(ast);
540 ASSERT_TRUE(analysis.Analyze(ast, ast)) << ast->m_int_vars.Dump();
541 ASSERT_EQ(1, ast->m_int_vars.size());
542 ASSERT_TRUE(ast->m_int_vars.find("var1$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
543 ASSERT_STREQ("var1", ast->m_int_vars.find("var1$")->second->m_text.c_str());
544 ASSERT_STREQ("var1$", ast->m_int_vars.find("var1$")->second->m_int_name.c_str());
545
546 ast = jit->GetParser()->Parse("$var2 ::= '1';$var3 ::= '1';");
547
548 ASSERT_TRUE(ast);
549 ASSERT_TRUE(analysis.Analyze(ast, ast));
550 ASSERT_EQ(2, ast->m_int_vars.size());
551 ASSERT_TRUE(ast->m_int_vars.find("1::var2$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
552 ASSERT_TRUE(ast->m_int_vars.find("1::var3$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
553 ASSERT_STREQ("$var2", ast->m_int_vars.find("1::var2$")->second->m_text.c_str());
554 ASSERT_STREQ("$var3", ast->m_int_vars.find("1::var3$")->second->m_text.c_str());
555 ASSERT_STREQ("1::var2$", ast->m_int_vars.find("1::var2$")->second->m_int_name.c_str());
556 ASSERT_STREQ("1::var3$", ast->m_int_vars.find("1::var3$")->second->m_int_name.c_str());
557
558 ast = jit->GetParser()->Parse("$var ::= '1'; $var := '2';");
559
560 ASSERT_TRUE(ast);
561 ASSERT_TRUE(analysis.Analyze(ast, ast));
562 ASSERT_EQ(1, ast->m_int_vars.size());
563 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
564 ASSERT_STREQ("$var", ast->m_int_vars.find("1::var$")->second->m_text.c_str());
565 ASSERT_STREQ("1::var$", ast->m_int_vars.find("1::var$")->second->m_int_name.c_str());
566
567 ast = jit->GetParser()->Parse("$var := '1'; $var = '2';");
568
569 ASSERT_TRUE(ast);
570 ASSERT_TRUE(analysis.Analyze(ast, ast));
571 ASSERT_EQ(1, ast->m_int_vars.size());
572 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
573 ASSERT_STREQ("$var", ast->m_int_vars.find("1::var$")->second->m_text.c_str());
574 ASSERT_STREQ("1::var$", ast->m_int_vars.find("1::var$")->second->m_int_name.c_str());
575
576
577 ast = jit->GetParser()->Parse("$var = '1'; $var := '2';");
578 ASSERT_TRUE(ast);
579 ASSERT_FALSE(analysis.Analyze(ast, ast));
580
581 ast = jit->GetParser()->Parse("$var ::= '1'; $var ::= '2';");
582 ASSERT_TRUE(ast);
583 ASSERT_FALSE(analysis.Analyze(ast, ast));
584
585 ast = jit->GetParser()->Parse("$var := 'строка'; $var = 2;");
586 ASSERT_TRUE(ast);
587 ASSERT_EQ(2, ast->m_block.size());
588 ASSERT_STREQ(":=", ast->m_block[0]->m_text.c_str());
589 ASSERT_TRUE(ast->m_block[0]->m_left);
590 ASSERT_STREQ("$var", ast->m_block[0]->m_left->m_text.c_str());
591 ASSERT_FALSE(ast->m_block[0]->m_left->m_type);
592 ASSERT_TRUE(ast->m_block[0]->m_right);
593 ASSERT_STREQ("строка", ast->m_block[0]->m_right->m_text.c_str());
594 ASSERT_TRUE(ast->m_block[0]->m_right->m_type);
595 ASSERT_STREQ(":StrChar", ast->m_block[0]->m_right->m_type->asTypeString().c_str());
596
597 ASSERT_STREQ("=", ast->m_block[1]->m_text.c_str());
598 ASSERT_TRUE(ast->m_block[1]->m_left);
599 ASSERT_STREQ("$var", ast->m_block[1]->m_left->m_text.c_str());
600 ASSERT_FALSE(ast->m_block[1]->m_left->m_type);
601 ASSERT_TRUE(ast->m_block[1]->m_right);
602 ASSERT_STREQ("2", ast->m_block[1]->m_right->m_text.c_str());
603 ASSERT_TRUE(ast->m_block[1]->m_right->m_type);
604 ASSERT_STREQ(":Int8", ast->m_block[1]->m_right->m_type->asTypeString().c_str());
605
606 ASSERT_FALSE(analysis.Analyze(ast, ast));
607
608 ast = jit->GetParser()->Parse("$var := 2; $var = '';");
609 ASSERT_TRUE(ast);
610 ASSERT_FALSE(analysis.Analyze(ast, ast));
611
612 // ast = jit->GetParser()->Parse("$var := 2; $var = _;");
613 // ASSERT_TRUE(ast);
614 // ASSERT_TRUE(analysis.Analyze(ast));
615 // ASSERT_STREQ(":None", ast->m_int_vars["$var"].proto->GetType()->asTypeString().c_str());
616
617 ast = jit->GetParser()->Parse("$var := 2; $var = 2222;");
618 ASSERT_TRUE(ast);
619 ASSERT_TRUE(analysis.Analyze(ast, ast));
620 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
621 ASSERT_STREQ(":Int16", ast->m_int_vars.find("1::var$")->second->GetType()->asTypeString().c_str());
622
623 ast = jit->GetParser()->Parse("$var:Int8 := 2; $var = 2222;");
624 ASSERT_TRUE(ast);
625 ASSERT_FALSE(analysis.Analyze(ast, ast));
626
627
628 ast = jit->GetParser()->Parse("$var := 2; $var = 22222222;");
629 ASSERT_TRUE(ast);
630 ASSERT_TRUE(analysis.Analyze(ast, ast));
631 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
632 ASSERT_STREQ(":Int32", ast->m_int_vars.find("1::var$")->second->GetType()->asTypeString().c_str());
633
634 ast = jit->GetParser()->Parse("$var := 2; $var = 2222222222222;");
635 ASSERT_TRUE(ast);
636 ASSERT_TRUE(analysis.Analyze(ast, ast));
637 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
638 ASSERT_STREQ(":Int64", ast->m_int_vars.find("1::var$")->second->GetType()->asTypeString().c_str());
639
640 ast = jit->GetParser()->Parse("$var := 2; $var = 2.0;");
641 ASSERT_TRUE(ast);
642 ASSERT_TRUE(analysis.Analyze(ast, ast));
643 ASSERT_TRUE(ast->m_int_vars.find("1::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
644 ASSERT_STREQ(":Float32", ast->m_int_vars.find("1::var$")->second->GetType()->asTypeString().c_str());
645
646}
647
648/*
649 *
650 */
651
652TEST(Ast, Namespace) {
653
654 RuntimePtr rt = RunTime::Init();
655 ASSERT_TRUE(rt);
656 JitPtr jit = JIT::Init(*rt);
657 AstAnalysis analysis(*rt, rt->m_diag.get());
658
659 TermPtr ast = jit->GetParser()->Parse("$var := 1;");
660 ASSERT_TRUE(ast);
661 ASSERT_EQ(0, ast->m_int_vars.size());
662 ASSERT_TRUE(analysis.Analyze(ast, ast));
663 ASSERT_EQ(1, ast->m_int_vars.size());
664 ASSERT_TRUE(ast->m_int_vars.find("var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
665 ASSERT_STREQ("$var", ast->m_int_vars.find("var$")->second->m_text.c_str());
666 ASSERT_STREQ("var$", ast->m_int_vars.find("var$")->second->m_int_name.c_str());
667
668 ast = jit->GetParser()->Parse("var := 1;");
669 ASSERT_TRUE(ast);
670 ASSERT_EQ(0, ast->m_int_vars.size());
671 ASSERT_TRUE(analysis.Analyze(ast, ast));
672 ASSERT_TRUE(ast->m_int_vars.find("var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
673 ASSERT_STREQ("var", ast->m_int_vars.find("var$")->second->m_text.c_str());
674 ASSERT_STREQ("var$", ast->m_int_vars.find("var$")->second->m_int_name.c_str());
675
676
677 ast = jit->GetParser()->Parse("::ns::var := 1;");
678 ASSERT_TRUE(ast);
679 ASSERT_EQ(0, ast->m_int_vars.size());
680 ASSERT_TRUE(analysis.Analyze(ast, ast));
681 ASSERT_TRUE(ast->m_int_vars.find("::ns::var::") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
682 ASSERT_STREQ("::ns::var", ast->m_int_vars.find("::ns::var::")->second->m_text.c_str());
683 ASSERT_STREQ("::ns::var::", ast->m_int_vars.find("::ns::var::")->second->m_int_name.c_str());
684
685 ast = jit->GetParser()->Parse("ns::var := 1;");
686 ASSERT_TRUE(ast);
687 ASSERT_EQ(0, ast->m_int_vars.size());
688 ASSERT_TRUE(analysis.Analyze(ast, ast));
689 ASSERT_TRUE(ast->m_int_vars.find("ns::var::") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
690 ASSERT_STREQ("ns::var", ast->m_int_vars.find("ns::var::")->second->m_text.c_str());
691 ASSERT_STREQ("ns::var::", ast->m_int_vars.find("ns::var::")->second->m_int_name.c_str());
692
693
694 ast = jit->GetParser()->Parse("name { var := 1; }");
695 ASSERT_TRUE(ast);
696 ASSERT_EQ(0, ast->m_int_vars.size());
697 ASSERT_TRUE(analysis.Analyze(ast, ast));
698 ASSERT_TRUE(ast->m_int_vars.find("1::name::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
699 ASSERT_STREQ("var", ast->m_int_vars.find("1::name::var$")->second->m_text.c_str());
700 ASSERT_STREQ("1::name::var$", ast->m_int_vars.find("1::name::var$")->second->m_int_name.c_str());
701
702
703 ASSERT_EQ(1, ast->m_block.size());
704 ASSERT_STREQ(":=", ast->m_block[0]->m_text.c_str());
705 ASSERT_TRUE(ast->m_block[0]->m_left);
706 ASSERT_STREQ("1::name::var$", ast->m_block[0]->m_left->m_int_name.c_str());
707 ASSERT_TRUE(ast->m_block[0]->m_right);
708 ASSERT_STREQ("1", ast->m_block[0]->m_right->m_text.c_str());
709
710 ast = jit->GetParser()->Parse("name:: { var := 1; }");
711 ASSERT_TRUE(ast);
712 ASSERT_EQ(0, ast->m_int_vars.size());
713 ASSERT_TRUE(analysis.Analyze(ast, ast));
714 ASSERT_TRUE(ast->m_int_vars.find("1::name::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
715 ASSERT_STREQ("var", ast->m_int_vars.find("1::name::var$")->second->m_text.c_str());
716 ASSERT_STREQ("1::name::var$", ast->m_int_vars.find("1::name::var$")->second->m_int_name.c_str());
717
718 ast = jit->GetParser()->Parse("ns::name:: { var := 1; }");
719 ASSERT_TRUE(ast);
720 ASSERT_EQ(0, ast->m_int_vars.size());
721 ASSERT_TRUE(analysis.Analyze(ast, ast));
722 ASSERT_TRUE(ast->m_int_vars.find("1::ns::name::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
723 ASSERT_STREQ("var", ast->m_int_vars.find("1::ns::name::var$")->second->m_text.c_str());
724 ASSERT_STREQ("1::ns::name::var$", ast->m_int_vars.find("1::ns::name::var$")->second->m_int_name.c_str());
725
726 ast = jit->GetParser()->Parse("name:: { ::var := 1; }");
727 ASSERT_TRUE(ast);
728 ASSERT_EQ(0, ast->m_int_vars.size());
729 ASSERT_TRUE(analysis.Analyze(ast, ast));
730 ASSERT_TRUE(ast->m_int_vars.find("::var::") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
731 ASSERT_STREQ("::var", ast->m_int_vars.find("::var::")->second->m_text.c_str());
732 ASSERT_STREQ("::var::", ast->m_int_vars.find("::var::")->second->m_int_name.c_str());
733
734 ast = jit->GetParser()->Parse("::name:: { ::ns2::var := 1; }");
735 ASSERT_TRUE(ast);
736 ASSERT_EQ(0, ast->m_int_vars.size());
737 ASSERT_TRUE(analysis.Analyze(ast, ast));
738 ASSERT_TRUE(ast->m_int_vars.find("::ns2::var::") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
739 ASSERT_STREQ("::ns2::var", ast->m_int_vars.find("::ns2::var::")->second->m_text.c_str());
740 ASSERT_STREQ("::ns2::var::", ast->m_int_vars.find("::ns2::var::")->second->m_int_name.c_str());
741
742 ast = jit->GetParser()->Parse("name { $var := 1; }");
743 ASSERT_TRUE(ast);
744 ASSERT_EQ(0, ast->m_int_vars.size());
745 ASSERT_TRUE(analysis.Analyze(ast, ast));
746 ASSERT_TRUE(ast->m_int_vars.find("1::name::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
747 ASSERT_STREQ("$var", ast->m_int_vars.find("1::name::var$")->second->m_text.c_str());
748 ASSERT_STREQ("1::name::var$", ast->m_int_vars.find("1::name::var$")->second->m_int_name.c_str());
749
750 ast = jit->GetParser()->Parse("name { { $var := 1; } }");
751 ASSERT_TRUE(ast);
752 ASSERT_EQ(0, ast->m_int_vars.size());
753 ASSERT_TRUE(analysis.Analyze(ast, ast));
754 ASSERT_TRUE(ast->m_int_vars.find("1::name::2::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
755 ASSERT_STREQ("$var", ast->m_int_vars.find("1::name::2::var$")->second->m_text.c_str());
756 ASSERT_STREQ("1::name::2::var$", ast->m_int_vars.find("1::name::2::var$")->second->m_int_name.c_str());
757
758 ast = jit->GetParser()->Parse("ns{ name { { $var := 1; } } }");
759 ASSERT_TRUE(ast);
760 ASSERT_EQ(0, ast->m_int_vars.size());
761 ASSERT_TRUE(analysis.Analyze(ast, ast));
762 ASSERT_TRUE(ast->m_int_vars.find("1::ns::name::2::var$") != ast->m_int_vars.end()) << ast->m_int_vars.Dump();
763 ASSERT_STREQ("$var", ast->m_int_vars.find("1::ns::name::2::var$")->second->m_text.c_str());
764 ASSERT_STREQ("1::ns::name::2::var$", ast->m_int_vars.find("1::ns::name::2::var$")->second->m_int_name.c_str());
765
766}
767
768TEST(Ast, Interruption) {
769
770 RuntimePtr rt = RunTime::Init();
771 ASSERT_TRUE(rt);
772 JitPtr jit = JIT::Init(*rt);
773
774 AstAnalysis analysis(*rt, rt->m_diag.get());
775
776 TermPtr ast = jit->GetParser()->Parse(":: --;");
777 ASSERT_TRUE(ast);
778 ASSERT_STREQ("::", ast->m_namespace->m_text.c_str());
779 ASSERT_TRUE(analysis.Analyze(ast, ast));
780 ASSERT_TRUE(ast->m_namespace);
781 ASSERT_STREQ("::", ast->m_namespace->m_text.c_str());
782
783 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("name { name -- };"));
784 ASSERT_TRUE(ast);
785 ASSERT_EQ(1, ast->m_block.size());
786 ASSERT_STREQ("--", ast->m_block[0]->m_text.c_str());
787 ASSERT_TRUE(ast->m_block[0]->isBlock());
788 ASSERT_TRUE(ast->m_block[0]->m_block[0]->isInterrupt());
789 ASSERT_TRUE(ast->m_block[0]->m_block[0]->m_namespace);
790 ASSERT_STREQ("name", ast->m_block[0]->m_block[0]->m_namespace->m_text.c_str());
791 ASSERT_TRUE(analysis.Analyze(ast, ast));
792 ASSERT_STREQ("name", ast->m_block[0]->m_block[0]->m_namespace->m_text.c_str());
793
794 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns::name { ns::name -+ };"));
795 ASSERT_TRUE(analysis.Analyze(ast, ast));
796 ASSERT_TRUE(ast);
797
798 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { name { ns::name +- } };"));
799 ASSERT_TRUE(analysis.Analyze(ast, ast));
800 ASSERT_TRUE(ast);
801
802 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { { ns::name ++ } } } };"));
803 ASSERT_TRUE(analysis.Analyze(ast, ast));
804 ASSERT_TRUE(ast);
805
806 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("{ ns { name { ns::name +- } } };"));
807 ASSERT_TRUE(analysis.Analyze(ast, ast));
808 ASSERT_TRUE(ast);
809
810 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { ns::name ++ } } } };"));
811 ASSERT_TRUE(analysis.Analyze(ast, ast));
812 ASSERT_TRUE(ast);
813
814 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { local:: ++ } } } };"));
815 ASSERT_TRUE(analysis.Analyze(ast, ast));
816 ASSERT_TRUE(ast);
817
818 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { ns ++ } } } };"));
819 ASSERT_TRUE(analysis.Analyze(ast, ast));
820 ASSERT_TRUE(ast);
821
822
823 ASSERT_NO_THROW(ast = jit->GetParser()->Parse("ns { { name { local:: { bad_name ++ } } } };"));
824 ASSERT_FALSE(analysis.Analyze(ast, ast));
825
826 // ast = jit->GetParser()->Parse("name { bad_name -- };");
827 // ASSERT_TRUE(ast);
828 // ASSERT_FALSE(analysis.Analyze(ast));
829 //
830 // ast = jit->GetParser()->Parse("name { bad_name:: -- };");
831 // ASSERT_TRUE(ast);
832 // ASSERT_FALSE(analysis.Analyze(ast));
833 //
834 // ast = jit->GetParser()->Parse("name1 { name2 { name3 { ::bad_name -- }}};");
835 // ASSERT_TRUE(ast);
836 // ASSERT_FALSE(analysis.Analyze(ast));
837 //
838 // ast = jit->GetParser()->Parse("name { name2::name3 { ::bad_name::name -- }};");
839 // ASSERT_TRUE(ast);
840 // ASSERT_FALSE(analysis.Analyze(ast));
841 //
842 // ast = jit->GetParser()->Parse("name { name::bad -- };");
843 // ASSERT_TRUE(ast);
844 // ASSERT_FALSE(analysis.Analyze(ast));
845 //
846 // // ast = jit->GetParser()->Parse("@$$ --;");
847 // // ASSERT_TRUE(ast);
848 // // ASSERT_STREQ("@$$", ast->m_namespace->m_text.c_str());
849 // // ASSERT_TRUE(analysis.Analyze(ast));
850 // // ASSERT_STREQ("", ast->m_namespace->m_text.c_str());
851 //
852 // // ast = jit->GetParser()->Parse("name { @$$ -- };");
853 // // ASSERT_TRUE(ast);
854 // // ASSERT_EQ(1, ast->m_block.size());
855 // // ASSERT_STREQ("--", ast->m_block[0]->m_text.c_str());
856 // // ASSERT_TRUE(ast->m_block[0]->m_namespace);
857 // // ASSERT_STREQ("@$$", ast->m_block[0]->m_namespace->m_text.c_str());
858 // // ASSERT_TRUE(analysis.Analyze(ast));
859 // // ASSERT_STREQ("name", ast->m_block[0]->m_namespace->m_text.c_str());
860 //
861 // ast = jit->GetParser()->Parse("@::var := 1");
862 // ASSERT_TRUE(ast);
863 // ASSERT_EQ(0, ast->m_variables.size());
864 // ASSERT_EQ(3, rt->size() - buildin_count);
865 // ASSERT_TRUE(analysis.Analyze(ast));
866 // ASSERT_EQ(3, rt->size() - buildin_count);
867 // ASSERT_EQ(1, ast->m_variables.size());
868 // ASSERT_STREQ("$$var", ast->m_variables.begin()->second.proto->m_text.c_str());
869 //
870 // ast = jit->GetParser()->Parse("@::var ::= 1");
871 // ASSERT_TRUE(ast);
872 // ASSERT_EQ(0, ast->m_variables.size());
873 // ASSERT_EQ(3, rt->size() - buildin_count);
874 // ASSERT_TRUE(analysis.Analyze(ast));
875 // ASSERT_EQ(3, rt->size() - buildin_count);
876 // ASSERT_EQ(1, ast->m_variables.size());
877 // ASSERT_STREQ("$$var", ast->m_variables.begin()->second.proto->m_text.c_str());
878 //
879 // ast = jit->GetParser()->Parse("ns { name { @::var := 1 } };");
880 // ASSERT_TRUE(ast);
881 // ASSERT_EQ(0, ast->m_variables.size());
882 // ASSERT_EQ(3, rt->size() - buildin_count);
883 // ASSERT_TRUE(analysis.Analyze(ast));
884 // ASSERT_EQ(3, rt->size() - buildin_count);
885 // ASSERT_EQ(1, ast->m_variables.size());
886 // ASSERT_STREQ("ns::name::var", ast->m_variables.begin()->second.proto->m_text.c_str());
887 //
888 //
889 // // ast = jit->GetParser()->Parse("ns { name { { var7 := @:: } } };");
890 // // ASSERT_TRUE(ast);
891 // // ASSERT_EQ(0, ast->m_variables.size());
892 // // ASSERT_EQ(3, rt->size() - buildin_count);
893 // // ASSERT_TRUE(analysis.Analyze(ast));
894 // // ASSERT_EQ(3, rt->size() - buildin_count);
895 // // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
896 // // ASSERT_STREQ("ns::name$var7", ast->m_variables.begin()->second.proto->m_text.c_str());
897 //
898 // // // В каком модуле ::$var_glob ???
899 // // ast = jit->GetParser()->Parse(":: { var_glob := 1 };");
900 // // ASSERT_TRUE(ast);
901 // // ASSERT_EQ(0, ast->m_variables.size());
902 // // ASSERT_EQ(3, rt->size() - buildin_count);
903 // // ASSERT_TRUE(analysis.Analyze(ast));
904 // // ASSERT_EQ(0, ast->m_variables.size()) << ast->m_variables.begin()->second.proto->m_text.c_str();
905 // // ASSERT_EQ(4, rt->size() - buildin_count);
906 // // ASSERT_STREQ("::$var_glob", ast->m_variables.begin()->second.proto->m_text.c_str());
907 //
908 //
909 // /*
910 // * Функции
911 // */
912 //
913 // buildin_count = rt->size();
914 // ast = jit->GetParser()->Parse("func() ::= {};");
915 // ASSERT_TRUE(ast);
916 // ASSERT_EQ(0, rt->size() - buildin_count);
917 // ASSERT_EQ(0, ast->m_variables.size());
918 // ASSERT_TRUE(analysis.Analyze(ast));
919 // ASSERT_EQ(0, rt->size() - buildin_count);
920 // ASSERT_EQ(1, ast->m_variables.size());
921 // ASSERT_STREQ("$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
922 //
923 // ast = jit->GetParser()->Parse("@::func() ::= {};");
924 // ASSERT_TRUE(ast);
925 //
926 // ASSERT_TRUE(ast->m_left);
927 // ASSERT_TRUE(ast->m_left->isCall()) << ast->toString();
928 // ASSERT_STREQ("@::func", ast->m_left->m_text.c_str());
929 //
930 // ASSERT_EQ(0, rt->size() - buildin_count);
931 // ASSERT_EQ(0, ast->m_variables.size());
932 // ASSERT_TRUE(analysis.Analyze(ast));
933 // ASSERT_EQ(0, rt->size() - buildin_count);
934 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
935 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
936 // ASSERT_STREQ("$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
937 //
938 //
939 // ast = jit->GetParser()->Parse("name { func() ::= {} };");
940 // ASSERT_TRUE(ast);
941 //
942 // ASSERT_EQ(1, ast->m_block.size());
943 // ASSERT_TRUE(ast->m_block[0]->m_left);
944 // ASSERT_TRUE(ast->m_block[0]->m_left->isCall()) << ast->m_block[0]->toString();
945 // ASSERT_STREQ("func", ast->m_block[0]->m_left->m_text.c_str());
946 //
947 // ASSERT_EQ(0, rt->size() - buildin_count);
948 // ASSERT_EQ(0, ast->m_variables.size());
949 // ASSERT_TRUE(analysis.Analyze(ast));
950 // ASSERT_EQ(0, rt->size() - buildin_count);
951 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
952 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
953 // ASSERT_STREQ("name$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
954 // ASSERT_STREQ("name$$func", ast->m_block[0]->m_left->m_text.c_str());
955 //
956 // ast = jit->GetParser()->Parse("ns { name { func() ::= {} } };");
957 // ASSERT_TRUE(ast);
958 //
959 // ASSERT_EQ(1, ast->m_block.size());
960 // ASSERT_TRUE(ast->m_block[0]->m_left);
961 // ASSERT_TRUE(ast->m_block[0]->m_left->isCall()) << ast->m_block[0]->toString();
962 // ASSERT_STREQ("func", ast->m_block[0]->m_left->m_text.c_str());
963 //
964 // ASSERT_EQ(0, rt->size() - buildin_count);
965 // ASSERT_EQ(0, ast->m_variables.size());
966 // ASSERT_TRUE(analysis.Analyze(ast));
967 // ASSERT_EQ(0, rt->size() - buildin_count);
968 // ASSERT_EQ(1, ast->m_variables.size()) << ast->m_variables.Dump();
969 // ASSERT_TRUE(ast->m_variables.begin()->second.proto);
970 // ASSERT_STREQ("ns::name$$func", ast->m_variables.begin()->second.proto->m_text.c_str());
971 // ASSERT_STREQ("ns::name$$func", ast->m_block[0]->m_left->m_text.c_str());
972 //
973 // // ast = jit->GetParser()->Parse("var := 1;");
974 // // ASSERT_TRUE(ast);
975 // // ASSERT_EQ(0, ast->m_variables.size());
976 // // ASSERT_EQ(0, rt->size() - buildin_count);
977 // // ASSERT_TRUE(analysis.Analyze(ast));
978 // // ASSERT_EQ(0, rt->size() - buildin_count);
979 // // ASSERT_EQ(1, ast->m_variables.size());
980 // // ASSERT_STREQ("$var", ast->m_variables.begin()->second.proto->m_text.c_str());
981 // //
982 // //
983 // // ast = jit->GetParser()->Parse("ns::var := 1;");
984 // // ASSERT_TRUE(ast);
985 // // ASSERT_EQ(0, ast->m_variables.size());
986 // // ASSERT_EQ(0, rt->size() - buildin_count);
987 // // ASSERT_TRUE(analysis.Analyze(ast));
988 // // ASSERT_EQ(0, rt->size() - buildin_count);
989 // // ASSERT_EQ(1, ast->m_variables.size());
990 // // ASSERT_STREQ("ns::var", ast->m_variables.begin()->second.proto->m_text.c_str());
991 // //
992 // //
993 // // ast = jit->GetParser()->Parse("::ns::var := 1;");
994 // // ASSERT_TRUE(ast);
995 // // ASSERT_EQ(0, ast->m_variables.size());
996 // // ASSERT_EQ(0, rt->size() - buildin_count);
997 // // ASSERT_TRUE(analysis.Analyze(ast));
998 // // ASSERT_EQ(1, rt->size() - buildin_count);
999 // // ASSERT_EQ(0, ast->m_variables.size());
1000 // // ASSERT_STREQ("::ns::var", (*rt)["::ns::var"].proto->m_text.c_str());
1001 // //
1002 // //
1003 // // ast = jit->GetParser()->Parse("name { var := 1 };");
1004 // // ASSERT_TRUE(ast);
1005 // // ASSERT_EQ(0, ast->m_variables.size());
1006 // // ASSERT_EQ(1, rt->size() - buildin_count);
1007 // // ASSERT_TRUE(analysis.Analyze(ast));
1008 // // ASSERT_EQ(1, rt->size() - buildin_count);
1009 // // ASSERT_EQ(1, ast->m_variables.size());
1010 // //
1011 // // ASSERT_EQ(1, ast->m_block.size());
1012 // // ASSERT_STREQ(":=", ast->m_block[0]->m_text.c_str());
1013 // // ASSERT_TRUE(ast->m_block[0]->m_left);
1014 // // ASSERT_STREQ("name$var", ast->m_block[0]->m_left->m_text.c_str());
1015 // // ASSERT_TRUE(ast->m_block[0]->m_right);
1016 // // ASSERT_STREQ("1", ast->m_block[0]->m_right->m_text.c_str());
1017 // //
1018 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1019 // //
1020 // // ast = jit->GetParser()->Parse("name:: { var := 1 };");
1021 // // ASSERT_TRUE(ast);
1022 // // ASSERT_EQ(0, ast->m_variables.size());
1023 // // ASSERT_EQ(1, rt->size() - buildin_count);
1024 // // ASSERT_TRUE(analysis.Analyze(ast));
1025 // // ASSERT_EQ(1, rt->size() - buildin_count);
1026 // // ASSERT_EQ(1, ast->m_variables.size());
1027 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1028 // //
1029 // //
1030 // // ast = jit->GetParser()->Parse("ns::name:: { var := 1 };");
1031 // // ASSERT_TRUE(ast);
1032 // // ASSERT_EQ(0, ast->m_variables.size());
1033 // // ASSERT_EQ(1, rt->size() - buildin_count);
1034 // // ASSERT_TRUE(analysis.Analyze(ast));
1035 // // ASSERT_EQ(1, rt->size() - buildin_count);
1036 // // ASSERT_EQ(1, ast->m_variables.size());
1037 // // ASSERT_STREQ("ns::name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1038 // //
1039 // // ast = jit->GetParser()->Parse("name:: { ::var := 1 };");
1040 // // ASSERT_TRUE(ast);
1041 // // ASSERT_EQ(0, ast->m_variables.size());
1042 // // ASSERT_EQ(1, rt->size() - buildin_count);
1043 // // ASSERT_TRUE(analysis.Analyze(ast));
1044 // // ASSERT_EQ(2, rt->size() - buildin_count);
1045 // // ASSERT_EQ(0, ast->m_variables.size());
1046 // // ASSERT_STREQ("::var", (*rt)["::var"].proto->m_text.c_str());
1047 // //
1048 // // ast = jit->GetParser()->Parse("::name:: { ::ns2::var := 1 };");
1049 // // ASSERT_TRUE(ast);
1050 // // ASSERT_EQ(0, ast->m_variables.size());
1051 // // ASSERT_EQ(2, rt->size() - buildin_count);
1052 // // ASSERT_TRUE(analysis.Analyze(ast));
1053 // // ASSERT_EQ(3, rt->size() - buildin_count);
1054 // // ASSERT_EQ(0, ast->m_variables.size());
1055 // // ASSERT_STREQ("::ns2::var", (*rt)["::ns2::var"].proto->m_text.c_str());
1056 // //
1057 // //
1058 // // ast = jit->GetParser()->Parse("name { $var := 1 };");
1059 // // ASSERT_TRUE(ast);
1060 // // ASSERT_EQ(0, ast->m_variables.size());
1061 // // ASSERT_EQ(3, rt->size() - buildin_count);
1062 // // ASSERT_TRUE(analysis.Analyze(ast));
1063 // // ASSERT_EQ(3, rt->size() - buildin_count);
1064 // // ASSERT_EQ(1, ast->m_variables.size());
1065 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1066 // //
1067 // // ast = jit->GetParser()->Parse("name { { $var := 1 } };");
1068 // // ASSERT_TRUE(ast);
1069 // // ASSERT_EQ(0, ast->m_variables.size());
1070 // // ASSERT_EQ(3, rt->size() - buildin_count);
1071 // // ASSERT_TRUE(analysis.Analyze(ast));
1072 // // ASSERT_EQ(3, rt->size() - buildin_count);
1073 // // ASSERT_EQ(1, ast->m_variables.size());
1074 // // ASSERT_STREQ("name$var", ast->m_variables.begin()->second.proto->m_text.c_str());
1075}
1076
1077TEST(Ast, Dims) {
1078 // :Bool[...]() - OK
1079 // :Bool[0]() - Error !!!!!!!!!!!!!!!!!
1080 // :Bool() - Ok
1081 // :Bool[..., ...]() - Error !!!!!!!!!!!!!!!!!
1082
1083 RuntimePtr rt = RunTime::Init();
1084 ASSERT_TRUE(rt);
1085 JitPtr jit = JIT::Init(*rt);
1086 AstAnalysis analysis(*rt, rt->m_diag.get());
1087
1088 TermPtr ast;
1089 ast = jit->GetParser()->Parse(":Bool(1)");
1090 ASSERT_TRUE(analysis.Analyze(ast, ast));
1091
1092 ASSERT_ANY_THROW(ast = jit->GetParser()->Parse(":Bool[](1)"));
1093
1094 AstAnalysis analysis2(*rt, rt->m_diag.get());
1095 ast = jit->GetParser()->Parse(":Bool[...](1)");
1096 ASSERT_TRUE(analysis2.Analyze(ast, ast));
1097
1098 AstAnalysis analysis3(*rt, rt->m_diag.get());
1099 ast = jit->GetParser()->Parse(":Bool[ ..., ...](1)");
1100 ASSERT_FALSE(analysis3.Analyze(ast, ast));
1101
1102 AstAnalysis analysis4(*rt, rt->m_diag.get());
1103 ast = jit->GetParser()->Parse(":Bool[0](1)");
1104 ASSERT_TRUE(analysis4.Analyze(ast, ast));
1105
1106 AstAnalysis analysis5(*rt, rt->m_diag.get());
1107 ast = jit->GetParser()->Parse(":Bool[_](1)");
1108 ASSERT_TRUE(analysis5.Analyze(ast, ast));
1109
1110 AstAnalysis analysis6(*rt, rt->m_diag.get());
1111 ast = jit->GetParser()->Parse(":Bool[0..1..2](1)");
1112 ASSERT_TRUE(analysis6.Analyze(ast, ast));
1113
1114 AstAnalysis analysis7(*rt, rt->m_diag.get());
1115 ast = jit->GetParser()->Parse("0.._..2");
1116 ASSERT_TRUE(analysis7.Analyze(ast, ast));
1117}
1118
1119
1120//TEST(Ast, ClassFunc) {
1121//
1122// Context::Reset();
1123// Context ctx(RunTime::Init());
1124//
1125// size_t buildin_count = ctx.m_runtime->size();
1126//
1127// ASSERT_EQ(0, ctx.m_runtime->m_macro->m_ns_stack.size());
1128// ASSERT_EQ(0, ctx.size());
1129//
1130// ASSERT_EQ(0, ctx.size());
1131//
1132// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { func1() := {1}; }");
1133// ASSERT_TRUE(class1);
1134// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1135// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1136// ASSERT_STREQ(":class1", class1->getName().c_str());
1137//
1138// // ASSERT_TRUE(ctx.size() > 0) << ctx.Dump("; ").c_str();
1139// // ASSERT_STREQ(":class1", ctx.at(0).first.c_str()) << ctx.Dump("; ").c_str();
1140// // ASSERT_TRUE(ctx.find(":class1") != ctx.end()) << ctx.Dump("; ").c_str();
1141// // ASSERT_STREQ("class1::func1", ctx.at(1).first.c_str()) << ctx.Dump("; ").c_str();
1142// ASSERT_EQ(2, ctx.m_runtime->size()-buildin_count);
1143// ASSERT_STREQ("class1::class1", ctx.m_terms->at(0).first.c_str());
1144// ASSERT_STREQ("class1::func1", ctx.m_terms->at(1).first.c_str());
1145// ObjPtr func1 = ctx.ExecStr("class1::func1");
1146// ASSERT_EQ(1, func1->Call(&ctx)->GetValueAsInteger());
1147//
1148// ASSERT_STREQ("class::class", MakeConstructorName(":class").c_str());
1149// ASSERT_STREQ("ns::class::class", MakeConstructorName(":ns::class").c_str());
1150// ASSERT_STREQ("ns::class::class::class", MakeConstructorName(":ns::class::class").c_str());
1151//
1152// EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_func1 := :class1 { func1() ::= {11}; }"));
1153// EXPECT_ANY_THROW(ctx.ExecStr(":class_func_not_found := :class1 { func_not_found() = {0}; }"));
1154//
1155// ObjPtr class2 = ctx.ExecStr(":class2 := :class1() { func2() := {2}; }");
1156// ASSERT_TRUE(class2);
1157// ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1158// ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1159// ASSERT_STREQ(":class2", class2->getName().c_str());
1160//
1161// ASSERT_TRUE(ctx.size() > 2) << ctx.Dump("; ").c_str();
1162// // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1163//
1164// std::string dump;
1165// for (int i = 0; i < ctx.m_terms->size(); i++) {
1166// dump += ctx.m_terms->at(i).first;
1167// dump += "; ";
1168// }
1169// ASSERT_EQ(5, ctx.m_terms->size()) << dump;
1170// ASSERT_STREQ("class2::class2", ctx.m_terms->at(2).first.c_str());
1171// ASSERT_STREQ("class2::func1", ctx.m_terms->at(3).first.c_str());
1172// ASSERT_STREQ("class2::func2", ctx.m_terms->at(4).first.c_str());
1173// ObjPtr func2_1 = ctx.ExecStr("class2::func1");
1174// ASSERT_EQ(1, func2_1->Call(&ctx)->GetValueAsInteger());
1175// ObjPtr func2_2 = ctx.ExecStr("class2::func2");
1176// ASSERT_EQ(2, func2_2->Call(&ctx)->GetValueAsInteger());
1177//
1178//
1179//
1180// ObjPtr func_name = ctx.ExecStr("class2 { func_name() := {'func_name'}; }");
1181// ASSERT_TRUE(func_name);
1182// ASSERT_EQ(ObjType::EVAL_FUNCTION, func_name->m_var_type_current) << toString(func_name->m_var_type_current);
1183// ASSERT_STREQ("class2::func_name", func_name->getName().c_str());
1184//
1185// dump = "";
1186// for (int i = 0; i < ctx.m_terms->size(); i++) {
1187// dump += ctx.m_terms->at(i).first;
1188// dump += "; ";
1189// }
1190// ASSERT_EQ(6, ctx.m_terms->size()) << dump;
1191// ASSERT_STREQ("class2::func_name", ctx.m_terms->at(5).first.c_str());
1192// ASSERT_STREQ("func_name", func_name->Call(&ctx)->GetValueAsString().c_str());
1193//
1194//
1195// ObjPtr class3 = ctx.ExecStr(":class3 := :class1, :class2 { func3() := {33}; func4() := {4}; }");
1196// ASSERT_TRUE(class3);
1197// ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class3->m_var_type_current);
1198// ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class3->m_var_type_fixed);
1199// ASSERT_STREQ(":class3", class3->getName().c_str());
1200//
1201// ASSERT_TRUE(ctx.size() > 4) << ctx.Dump("; ").c_str();
1202//
1203// dump = "";
1204// for (int i = 0; i < ctx.m_terms->size(); i++) {
1205// dump += ctx.m_terms->at(i).first;
1206// dump += "; ";
1207// }
1208// ASSERT_EQ(12, ctx.m_terms->size()) << dump;
1209// ASSERT_STREQ("class3::class3", ctx.m_terms->at(6).first.c_str());
1210// ASSERT_STREQ("class3::func1", ctx.m_terms->at(7).first.c_str());
1211// ASSERT_STREQ("class3::func3", ctx.m_terms->at(8).first.c_str());
1212// ASSERT_STREQ("class3::func4", ctx.m_terms->at(9).first.c_str());
1213// ASSERT_STREQ("class3::func2", ctx.m_terms->at(10).first.c_str());
1214// ASSERT_STREQ("class3::func_name", ctx.m_terms->at(11).first.c_str());
1215// ObjPtr func3_1 = ctx.ExecStr("class3::func1");
1216// ASSERT_EQ(1, func3_1->Call(&ctx)->GetValueAsInteger());
1217// ObjPtr func3_2 = ctx.ExecStr("class3::func2");
1218// ASSERT_EQ(2, func3_2->Call(&ctx)->GetValueAsInteger());
1219// ObjPtr func3_3 = ctx.ExecStr("class3::func3");
1220// ASSERT_EQ(33, func3_3->Call(&ctx)->GetValueAsInteger());
1221// ObjPtr func3_4 = ctx.ExecStr("class3::func4");
1222// ASSERT_EQ(4, func3_4->Call(&ctx)->GetValueAsInteger());
1223// ObjPtr result = ctx.ExecStr("class3::func_name()");
1224// ASSERT_TRUE(result);
1225// ASSERT_STREQ("func_name", result->GetValueAsString().c_str());
1226//
1227//
1228//
1229//
1230// ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1231// ASSERT_TRUE(var1);
1232// ObjPtr var1_1 = ctx.ExecStr("var1.func1()");
1233// ASSERT_TRUE(var1_1);
1234// ASSERT_EQ(1, var1_1->GetValueAsInteger());
1235//
1236//
1237// ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1238// ASSERT_TRUE(var2);
1239// ObjPtr var2_1 = ctx.ExecStr("var2.func1()");
1240// ASSERT_TRUE(var2_1);
1241// ASSERT_EQ(1, var2_1->GetValueAsInteger());
1242// ObjPtr var2_2 = ctx.ExecStr("var2.func2()");
1243// ASSERT_TRUE(var2_2);
1244// ASSERT_EQ(2, var2_2->GetValueAsInteger());
1245//
1246//
1247// ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1248// ASSERT_TRUE(var3);
1249// ObjPtr var3_1 = ctx.ExecStr("var3.func1()");
1250// ASSERT_TRUE(var3_1);
1251// ASSERT_EQ(1, var3_1->GetValueAsInteger());
1252// ObjPtr var3_2 = ctx.ExecStr("var3.func2()");
1253// ASSERT_TRUE(var3_2);
1254// ASSERT_EQ(2, var3_2->GetValueAsInteger());
1255// ObjPtr var3_3 = ctx.ExecStr("var3.func3()");
1256// ASSERT_TRUE(var3_3);
1257// ASSERT_EQ(33, var3_3->GetValueAsInteger());
1258// ObjPtr var3_4 = ctx.ExecStr("var3.func4()");
1259// ASSERT_TRUE(var3_4);
1260// ASSERT_EQ(4, var3_4->GetValueAsInteger());
1261//
1262//}
1263//
1264//TEST(Ast, ClassProp) {
1265//
1266// Context::Reset();
1267// Context ctx(RunTime::Init());
1268//
1269// ASSERT_EQ(0, ctx.m_runtime->m_macro->m_ns_stack.size());
1270// ASSERT_EQ(0, ctx.size());
1271// ASSERT_EQ(0, ctx.m_terms->size());
1272//
1273// ASSERT_EQ(0, ctx.size());
1274//
1275// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { prop1 := 1; }");
1276// ASSERT_TRUE(class1);
1277// ASSERT_TRUE(class1->is_init());
1278// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1279// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1280// ASSERT_STREQ(":class1", class1->getName().c_str());
1281// ASSERT_EQ(1, class1->size());
1282// ASSERT_TRUE(class1->at("prop1").second);
1283// ASSERT_STREQ("1", class1->at("prop1").second->toString().c_str());
1284//
1285// ObjPtr class2 = ctx.ExecStr(":class2 := :class1 { prop2 := 2; }");
1286// ASSERT_TRUE(class2);
1287// ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1288// ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1289// ASSERT_STREQ(":class2", class2->getName().c_str());
1290// ASSERT_EQ(2, class2->size());
1291// ASSERT_STREQ("1", class2->at("prop1").second->toString().c_str());
1292// ASSERT_STREQ("2", class2->at("prop2").second->toString().c_str());
1293//
1294//
1295// ObjPtr class3 = ctx.ExecStr(":class3 := :class2 { prop1 = 10; }");
1296// ASSERT_TRUE(class3);
1297// ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class2->m_var_type_current);
1298// ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1299// ASSERT_STREQ(":class3", class3->getName().c_str());
1300// ASSERT_EQ(2, class3->size());
1301// ASSERT_STREQ("10", class3->at("prop1").second->toString().c_str());
1302// ASSERT_STREQ("2", class3->at("prop2").second->toString().c_str());
1303//
1304//
1305// EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_prop2 := :class2 { prop2 ::= 1; }"));
1306// EXPECT_ANY_THROW(ctx.ExecStr(":class_prop_not_found := :class2 { prop_not_found = 1; }"));
1307//
1308//
1309// ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1310// ASSERT_TRUE(var1);
1311// ObjPtr var1_1;
1312//
1313// ASSERT_NO_THROW(var1_1 = ctx.ExecStr("var1.prop1")) << ctx.Dump() << " (" << var1->toString() << ")";
1314//
1315// ASSERT_TRUE(var1_1);
1316// ASSERT_EQ(1, var1_1->GetValueAsInteger());
1317//
1318//
1319// ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1320// ASSERT_TRUE(var2);
1321// ObjPtr var2_1 = ctx.ExecStr("var2.prop1");
1322// ASSERT_TRUE(var2_1);
1323// ASSERT_EQ(1, var2_1->GetValueAsInteger());
1324// ObjPtr var2_2 = ctx.ExecStr("var2.prop2");
1325// ASSERT_TRUE(var2_2);
1326// ASSERT_EQ(2, var2_2->GetValueAsInteger());
1327//
1328// ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1329// ASSERT_TRUE(var3);
1330// ObjPtr var3_1 = ctx.ExecStr("var3.prop1");
1331// ASSERT_TRUE(var3_1);
1332// ASSERT_EQ(10, var3_1->GetValueAsInteger());
1333// ObjPtr var3_2 = ctx.ExecStr("var3.prop2");
1334// ASSERT_TRUE(var3_2);
1335// ASSERT_EQ(2, var3_2->GetValueAsInteger());
1336//
1337//
1338// ObjPtr var4 = ctx.ExecStr("var4 := :class3(prop2=100, prop1=99)");
1339// ASSERT_TRUE(var4);
1340// ObjPtr var4_1 = ctx.ExecStr("var4.prop1");
1341// ASSERT_TRUE(var4_1);
1342// ASSERT_EQ(99, var4_1->GetValueAsInteger());
1343// ObjPtr var4_2 = ctx.ExecStr("var4.prop2");
1344// ASSERT_TRUE(var4_2);
1345// ASSERT_EQ(100, var4_2->GetValueAsInteger());
1346//
1347//
1348// EXPECT_ANY_THROW(ctx.ExecStr("var_not_found := :class3(prop_not_found=100)"));
1349// EXPECT_ANY_THROW(ctx.ExecStr("var_bad_type := :class3(prop1='BAD TYPE')"));
1350//}
1351
1352
1353
1354
1355//TEST(Ast, ClassConstruct) {
1356//
1357//
1358// ASSERT_STREQ("class::class", MakeConstructorName(":class").c_str());
1359// ASSERT_STREQ("ns::class::class", MakeConstructorName(":ns::class").c_str());
1360// ASSERT_STREQ("ns::class::class::class", MakeConstructorName(":ns::class::class").c_str());
1361//
1362//
1363// Context::Reset();
1364// Context ctx(RunTime::Init());
1365//
1366// ASSERT_EQ(0, ctx.m_ns_stack.size());
1367// ASSERT_EQ(0, ctx.size());
1368// ASSERT_EQ(0, ctx.m_terms->size());
1369//
1370// ASSERT_EQ(0, ctx.size());
1371//
1372// ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { func1() := {1}; prop1 := 1; class1() = {$0.prop1 = 99; $0}; }");
1373// ASSERT_TRUE(class1);
1374// ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1375// ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1376// ASSERT_STREQ(":class1", class1->getName().c_str());
1377//
1378// ASSERT_EQ(3, ctx.m_terms->size());
1379// ASSERT_STREQ(":class1::class1", ctx.m_terms->at(0).first.c_str());
1380// ASSERT_STREQ("class1::func1", ctx.m_terms->at(1).first.c_str());
1381// ObjPtr func1 = ctx.ExecStr("class1::func1");
1382// ASSERT_EQ(1, func1->Call(&ctx)->GetValueAsInteger());
1383//
1384// ASSERT_ANY_THROW(ctx.ExecStr("class1::class1()")); // Object not found
1385//
1386// ObjPtr obj1 = ctx.ExecStr("var1 := :class1()");
1387// ASSERT_TRUE(obj1);
1388// ObjPtr var1_1 = ctx.ExecStr("var1.prop1");
1389// ASSERT_TRUE(var1_1);
1390// ASSERT_EQ(99, var1_1->GetValueAsInteger());
1391//
1392// //
1393// // ASSERT_ANY_THROW(ctx.ExecStr(":class_dup_func1 := :class1 { func1() ::= {11}; }"));
1394// // ASSERT_ANY_THROW(ctx.ExecStr(":class_func_not_found := :class1 { func_not_found() = {0}; }"));
1395// //
1396// // ObjPtr class2 = ctx.ExecStr(":class2 := :class1() { func2() := {2}; }");
1397// // ASSERT_TRUE(class2);
1398// // ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1399// // ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1400// // ASSERT_STREQ(":class2", class2->getName().c_str());
1401// //
1402// // ASSERT_TRUE(ctx.size() > 2) << ctx.Dump("; ").c_str();
1403// // // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1404// // ASSERT_EQ(3, ctx.m_terms->size());
1405// // ASSERT_STREQ("class2::func1", ctx.m_terms->at(1).first.c_str());
1406// // ASSERT_STREQ("class2::func2", ctx.m_terms->at(2).first.c_str());
1407// // ObjPtr func2_1 = ctx.ExecStr("class2::func1");
1408// // ASSERT_EQ(1, func2_1->Call(&ctx)->GetValueAsInteger());
1409// // ObjPtr func2_2 = ctx.ExecStr("class2::func2");
1410// // ASSERT_EQ(2, func2_2->Call(&ctx)->GetValueAsInteger());
1411// //
1412// //
1413// //
1414// // ObjPtr func_name = ctx.ExecStr("class2 { func_name() := {'func_name'}; }");
1415// // ASSERT_TRUE(func_name);
1416// // ASSERT_EQ(ObjType::EVAL_FUNCTION, func_name->m_var_type_current) << toString(func_name->m_var_type_current);
1417// // ASSERT_STREQ("class2::func_name", func_name->getName().c_str());
1418// //
1419// // ASSERT_EQ(4, ctx.m_terms->size());
1420// // ASSERT_STREQ("class2::func_name", ctx.m_terms->at(3).first.c_str());
1421// // ASSERT_STREQ("func_name", func_name->Call(&ctx)->GetValueAsString().c_str());
1422// //
1423// //
1424// // ObjPtr class3 = ctx.ExecStr(":class3 := :class1, :class2 { func3() := {33}; func4() := {4}; }");
1425// // ASSERT_TRUE(class3);
1426// // ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class3->m_var_type_current);
1427// // ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class3->m_var_type_fixed);
1428// // ASSERT_STREQ(":class3", class3->getName().c_str());
1429// //
1430// // ASSERT_TRUE(ctx.size() > 4) << ctx.Dump("; ").c_str();
1431// // // ASSERT_STREQ(":class2", ctx.at(2).first.c_str()) << ctx.Dump("; ").c_str();
1432// // ASSERT_EQ(9, ctx.m_terms->size());
1433// // ASSERT_STREQ("class3::func1", ctx.m_terms->at(4).first.c_str());
1434// // ASSERT_STREQ("class3::func2", ctx.m_terms->at(5).first.c_str());
1435// // ASSERT_STREQ("class3::func_name", ctx.m_terms->at(6).first.c_str());
1436// // ASSERT_STREQ("class3::func3", ctx.m_terms->at(7).first.c_str());
1437// // ASSERT_STREQ("class3::func4", ctx.m_terms->at(8).first.c_str());
1438// // ObjPtr func3_1 = ctx.ExecStr("class3::func1");
1439// // ASSERT_EQ(1, func3_1->Call(&ctx)->GetValueAsInteger());
1440// // ObjPtr func3_2 = ctx.ExecStr("class3::func2");
1441// // ASSERT_EQ(2, func3_2->Call(&ctx)->GetValueAsInteger());
1442// // ObjPtr func3_3 = ctx.ExecStr("class3::func3");
1443// // ASSERT_EQ(33, func3_3->Call(&ctx)->GetValueAsInteger());
1444// // ObjPtr func3_4 = ctx.ExecStr("class3::func4");
1445// // ASSERT_EQ(4, func3_4->Call(&ctx)->GetValueAsInteger());
1446// // ObjPtr result = ctx.ExecStr("class3::func_name()");
1447// // ASSERT_TRUE(result);
1448// // ASSERT_STREQ("func_name", result->GetValueAsString().c_str());
1449// //
1450// //
1451// //
1452// //
1453// // ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1454// // ASSERT_TRUE(var1);
1455// // ObjPtr var1_1 = ctx.ExecStr("var1.func1()");
1456// // ASSERT_TRUE(var1_1);
1457// // ASSERT_EQ(1, var1_1->GetValueAsInteger());
1458// //
1459// //
1460// // ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1461// // ASSERT_TRUE(var2);
1462// // ObjPtr var2_1 = ctx.ExecStr("var2.func1()");
1463// // ASSERT_TRUE(var2_1);
1464// // ASSERT_EQ(1, var2_1->GetValueAsInteger());
1465// // ObjPtr var2_2 = ctx.ExecStr("var2.func2()");
1466// // ASSERT_TRUE(var2_2);
1467// // ASSERT_EQ(2, var2_2->GetValueAsInteger());
1468// //
1469// //
1470// // ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1471// // ASSERT_TRUE(var3);
1472// // ObjPtr var3_1 = ctx.ExecStr("var3.func1()");
1473// // ASSERT_TRUE(var3_1);
1474// // ASSERT_EQ(1, var3_1->GetValueAsInteger());
1475// // ObjPtr var3_2 = ctx.ExecStr("var3.func2()");
1476// // ASSERT_TRUE(var3_2);
1477// // ASSERT_EQ(2, var3_2->GetValueAsInteger());
1478// // ObjPtr var3_3 = ctx.ExecStr("var3.func3()");
1479// // ASSERT_TRUE(var3_3);
1480// // ASSERT_EQ(33, var3_3->GetValueAsInteger());
1481// // ObjPtr var3_4 = ctx.ExecStr("var3.func4()");
1482// // ASSERT_TRUE(var3_4);
1483// // ASSERT_EQ(4, var3_4->GetValueAsInteger());
1484// //
1485// //}
1486// //
1487// //TEST(Oop, ClassProp) {
1488// //
1489// // Context::Reset();
1490// // Context ctx(RunTime::Init());
1491// //
1492// // ASSERT_EQ(0, ctx.m_ns_stack.size());
1493// // ASSERT_EQ(0, ctx.size());
1494// // ASSERT_EQ(0, ctx.m_terms->size());
1495// //
1496// // ASSERT_EQ(0, ctx.size());
1497// //
1498// // ObjPtr class1 = ctx.ExecStr(":class1 := :Class() { prop1 := 1; }");
1499// // ASSERT_TRUE(class1);
1500// // ASSERT_EQ(ObjType::Type, class1->m_var_type_current) << toString(class1->m_var_type_current);
1501// // ASSERT_EQ(ObjType::Class, class1->m_var_type_fixed) << toString(class1->m_var_type_fixed);
1502// // ASSERT_STREQ(":class1", class1->getName().c_str());
1503// // ASSERT_EQ(1, class1->size());
1504// // ASSERT_STREQ("1", class1->at("prop1").second->toString().c_str());
1505// //
1506// // ObjPtr class2 = ctx.ExecStr(":class2 := :class1 { prop2 := 2; }");
1507// // ASSERT_TRUE(class2);
1508// // ASSERT_EQ(ObjType::Type, class2->m_var_type_current) << toString(class2->m_var_type_current);
1509// // ASSERT_EQ(ObjType::Class, class2->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1510// // ASSERT_STREQ(":class2", class2->getName().c_str());
1511// // ASSERT_EQ(2, class2->size());
1512// // ASSERT_STREQ("1", class2->at("prop1").second->toString().c_str());
1513// // ASSERT_STREQ("2", class2->at("prop2").second->toString().c_str());
1514// //
1515// //
1516// // ObjPtr class3 = ctx.ExecStr(":class3 := :class2 { prop1 = 10; }");
1517// // ASSERT_TRUE(class3);
1518// // ASSERT_EQ(ObjType::Type, class3->m_var_type_current) << toString(class2->m_var_type_current);
1519// // ASSERT_EQ(ObjType::Class, class3->m_var_type_fixed) << toString(class2->m_var_type_fixed);
1520// // ASSERT_STREQ(":class3", class3->getName().c_str());
1521// // ASSERT_EQ(2, class3->size());
1522// // ASSERT_STREQ("10", class3->at("prop1").second->toString().c_str());
1523// // ASSERT_STREQ("2", class3->at("prop2").second->toString().c_str());
1524// //
1525// //
1526// // EXPECT_ANY_THROW(ctx.ExecStr(":class_dup_prop2 := :class2 { prop2 ::= 1; }"));
1527// // EXPECT_ANY_THROW(ctx.ExecStr(":class_prop_not_found := :class2 { prop_not_found = 1; }"));
1528// //
1529// //
1530// // ObjPtr var1 = ctx.ExecStr("var1 := :class1()");
1531// // ASSERT_TRUE(var1);
1532// // ObjPtr var1_1;
1533// //
1534// // ASSERT_NO_THROW(var1_1 = ctx.ExecStr("var1.prop1")) << ctx.Dump() << " (" << var1->toString() << ")";
1535// //
1536// // ASSERT_TRUE(var1_1);
1537// // ASSERT_EQ(1, var1_1->GetValueAsInteger());
1538// //
1539// //
1540// // ObjPtr var2 = ctx.ExecStr("var2 := :class2()");
1541// // ASSERT_TRUE(var2);
1542// // ObjPtr var2_1 = ctx.ExecStr("var2.prop1");
1543// // ASSERT_TRUE(var2_1);
1544// // ASSERT_EQ(1, var2_1->GetValueAsInteger());
1545// // ObjPtr var2_2 = ctx.ExecStr("var2.prop2");
1546// // ASSERT_TRUE(var2_2);
1547// // ASSERT_EQ(2, var2_2->GetValueAsInteger());
1548// //
1549// // ObjPtr var3 = ctx.ExecStr("var3 := :class3()");
1550// // ASSERT_TRUE(var3);
1551// // ObjPtr var3_1 = ctx.ExecStr("var3.prop1");
1552// // ASSERT_TRUE(var3_1);
1553// // ASSERT_EQ(10, var3_1->GetValueAsInteger());
1554// // ObjPtr var3_2 = ctx.ExecStr("var3.prop2");
1555// // ASSERT_TRUE(var3_2);
1556// // ASSERT_EQ(2, var3_2->GetValueAsInteger());
1557// //
1558// //
1559// // ObjPtr var4 = ctx.ExecStr("var4 := :class3(prop2=100, prop1=99)");
1560// // ASSERT_TRUE(var4);
1561// // ObjPtr var4_1 = ctx.ExecStr("var4.prop1");
1562// // ASSERT_TRUE(var4_1);
1563// // ASSERT_EQ(99, var4_1->GetValueAsInteger());
1564// // ObjPtr var4_2 = ctx.ExecStr("var4.prop2");
1565// // ASSERT_TRUE(var4_2);
1566// // ASSERT_EQ(100, var4_2->GetValueAsInteger());
1567// //
1568// //
1569// // EXPECT_ANY_THROW(ctx.ExecStr("var_not_found := :class3(prop_not_found=100)"));
1570// // EXPECT_ANY_THROW(ctx.ExecStr("var_bad_type := :class3(prop1='BAD TYPE')"));
1571//
1572//}
1573
1574TEST(Ast, CheckStrPrintf) {
1575
1576 TermPtr args = Term::CreateDict();
1577
1578 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("", args, 0));
1579 args->push_back(Term::CreateName(""));
1580 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("", args, 0));
1581 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("", args, 1));
1582
1583 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s", args, 0));
1584 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s", args, 1));
1585 args->push_back(Term::CreateName(""));
1586 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s", args, 1));
1587 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s", args, 2));
1588
1589 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d", args, 0));
1590 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d", args, 1));
1591 args->push_back(Term::CreateName("1"));
1592 args->back().second->m_type = getDefaultType(ObjType::Int8);
1593 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d", args, 1));
1594 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d", args, 2));
1595
1596 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 0));
1597 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 1));
1598 args->push_back(Term::CreateName("1"));
1599 args->back().second->m_type = getDefaultType(ObjType::Int64);
1600 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%d", args, 1));
1601 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 1));
1602 args->back().second->m_type = getDefaultType(ObjType::Int32);
1603 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 1));
1604 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld", args, 2));
1605
1606 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 0));
1607 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 1));
1608 args->push_back(Term::CreateName("0"));
1609 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 1));
1610 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f", args, 2));
1611
1612 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 0));
1613 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 1));
1614 args->push_back(Term::CreateName(""));
1615 ASSERT_TRUE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 1));
1616 ASSERT_FALSE(AstAnalysis::CheckStrPrintf("%s%d%ld%f%s", args, 2));
1617
1618
1619 RuntimePtr rt = RunTime::Init();
1620 JitPtr jit = JIT::Init(*rt);
1621 ASSERT_TRUE(rt);
1622
1623 ASSERT_ANY_THROW(rt->MakeAst("print()"));
1624 ASSERT_ANY_THROW(rt->MakeAst("print(123)"));
1625 ASSERT_ANY_THROW(rt->MakeAst("print('%s - %s', 1, 'test')"));
1626 ASSERT_ANY_THROW(rt->MakeAst("print('%d - %d', 1, 'test')"));
1627
1628 ASSERT_NO_THROW(rt->MakeAst("print(format='')"));
1629 ASSERT_NO_THROW(rt->MakeAst("print(format='%d', 1)"));
1630
1631 ASSERT_ANY_THROW(rt->MakeAst("print(format='', 1)"));
1632 ASSERT_ANY_THROW(rt->MakeAst("print(format='%d', named=1)"));
1633 ASSERT_ANY_THROW(rt->MakeAst("print(format='%d', __sys__=1)"));
1634
1635 ObjPtr print;
1636 ASSERT_NO_THROW(print = jit->Run("print(format='\\n')"));
1637 ASSERT_NO_THROW(print = jit->Run("print('%d - %s\\n', 1, 'test')"));
1638}
1639
1640TEST(Ast, CheckStrFormat) {
1641
1642 TermPtr args = Term::CreateDict();
1643
1644 ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("", nullptr));
1645 ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("{", args));
1646
1647 ASSERT_STREQ("", AstAnalysis::ConvertToVFormat_("", args).c_str());
1648 ASSERT_STREQ("{{", AstAnalysis::ConvertToVFormat_("{{", args).c_str());
1649 ASSERT_STREQ("format", AstAnalysis::ConvertToVFormat_("format", args).c_str());
1650 ASSERT_STREQ("{}", AstAnalysis::ConvertToVFormat_("{}", args).c_str());
1651 ASSERT_STREQ("{1}", AstAnalysis::ConvertToVFormat_("{1}", args).c_str());
1652 ASSERT_STREQ("{1:}", AstAnalysis::ConvertToVFormat_("{1:}", args).c_str());
1653 ASSERT_STREQ("{:0}", AstAnalysis::ConvertToVFormat_("{:0}", args).c_str());
1654 ASSERT_STREQ("{:0}{:0}", AstAnalysis::ConvertToVFormat_("{:0}{:0}", args).c_str());
1655 ASSERT_STREQ("{1:1}{1:1}", AstAnalysis::ConvertToVFormat_("{1:1}{1:1}", args).c_str());
1656
1657 ASSERT_ANY_THROW(AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1", args));
1658 ASSERT_STREQ("{{{1:1}{1:1}", AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1}", args).c_str());
1659 ASSERT_STREQ("{{{1:1}{1:1}}}", AstAnalysis::ConvertToVFormat_("{{{1:1}{1:1}}}", args).c_str());
1660
1661 args->push_back(Term::CreateNone(), "name");
1662 ASSERT_STREQ("{0}", AstAnalysis::ConvertToVFormat_("{name}", args).c_str());
1663 ASSERT_STREQ("{0}{0}", AstAnalysis::ConvertToVFormat_("{name}{name}", args).c_str());
1664 ASSERT_STREQ("{0:0}{0:123}{0:0.0}", AstAnalysis::ConvertToVFormat_("{name:0}{0:123}{name:0.0}", args).c_str());
1665 ASSERT_STREQ("{0}{0}", AstAnalysis::ConvertToVFormat_("{0}{name}", args).c_str());
1666
1667 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{0}}}", args).c_str());
1668 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{name}}}", args).c_str());
1669
1670 ASSERT_STREQ("{{0}{0}}", AstAnalysis::ConvertToVFormat_("{{0}{name}}", args).c_str());
1671 ASSERT_STREQ("{{{0}{0}}", AstAnalysis::ConvertToVFormat_("{{{0}{name}}", args).c_str());
1672
1673
1674 args->push_back(Term::CreateNone(), "name2");
1675 ASSERT_STREQ("{0}{1}", AstAnalysis::ConvertToVFormat_("{name}{name2}", args).c_str());
1676 ASSERT_STREQ("{1}", AstAnalysis::ConvertToVFormat_("{name2}", args).c_str());
1677 ASSERT_STREQ("{1:0}{1:.0}{0:0.0}", AstAnalysis::ConvertToVFormat_("{name2:0}{1:.0}{name:0.0}", args).c_str());
1678 ASSERT_STREQ("{1}{0}", AstAnalysis::ConvertToVFormat_("{name2}{name}", args).c_str());
1679
1680 ASSERT_STREQ("{{name2}{0}}", AstAnalysis::ConvertToVFormat_("{{name2}{name}}", args).c_str());
1681 ASSERT_STREQ("{{{1}{0}}", AstAnalysis::ConvertToVFormat_("{{{name2}{name}}", args).c_str());
1682 ASSERT_STREQ("{{{1}}}", AstAnalysis::ConvertToVFormat_("{{{name2}}}", args).c_str());
1683
1684 ASSERT_STREQ("{{{0}}}", AstAnalysis::ConvertToVFormat_("{{{name}}}", args).c_str());
1685
1686 args->clear();
1687 ASSERT_TRUE(!args->size());
1688
1689 ASSERT_STREQ("", AstAnalysis::MakeFormat("", args, nullptr). c_str());
1690 ASSERT_ANY_THROW(AstAnalysis::MakeFormat("{", args, nullptr));
1691 ASSERT_STREQ("{", AstAnalysis::MakeFormat("{{", args, nullptr). c_str());
1692
1693 ASSERT_NO_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{}}", args, nullptr). c_str()));
1694 ASSERT_ANY_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{{}}}", args, nullptr). c_str()));
1695
1696 args->push_back(Term::CreateNone(), "none");
1697 ASSERT_NO_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{{}}}", args, nullptr). c_str()));
1698 ASSERT_NO_THROW(ASSERT_STREQ("{}", AstAnalysis::MakeFormat("{{{none}}}", args, nullptr). c_str()));
1699
1700
1701 ASSERT_NO_THROW(ASSERT_STREQ("", AstAnalysis::MakeFormat("{none}", args, nullptr). c_str()));
1702
1703 args->push_back(Term::CreateName("string", TermID::STRCHAR), "str");
1704 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{str}", args, nullptr). c_str()));
1705
1706 args->push_back(Term::CreateName("123", TermID::STRCHAR), "int");
1707 ASSERT_NO_THROW(ASSERT_STREQ("'123'", AstAnalysis::MakeFormat("{int}", args, nullptr). c_str()));
1708
1709 ASSERT_NO_THROW(ASSERT_STREQ("", AstAnalysis::MakeFormat("{}", args, nullptr). c_str()));
1710 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{}{}", args, nullptr). c_str()));
1711 ASSERT_NO_THROW(ASSERT_STREQ("'string''123'", AstAnalysis::MakeFormat("{}{}{}", args, nullptr). c_str()));
1712
1713 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{1}", args, nullptr). c_str()));
1714 ASSERT_NO_THROW(ASSERT_STREQ("'string'", AstAnalysis::MakeFormat("{0}{1}{0}", args, nullptr). c_str()));
1715 ASSERT_NO_THROW(ASSERT_STREQ("'string''123'", AstAnalysis::MakeFormat("{1}{2}{none}", args, nullptr). c_str()));
1716
1717 ASSERT_NO_THROW(ASSERT_STREQ("'string''123'", AstAnalysis::MakeFormat("{none}{str}{int}{none}", args, nullptr). c_str()));
1718}
1719
1720TEST(Ast, MakeInclude) {
1721
1722 std::string str;
1723 str = AstAnalysis::MakeInclude(Term::CreateName("name"));
1724 ASSERT_STREQ("", str.c_str());
1725
1726 str = AstAnalysis::MakeInclude(Parser::ParseString("::val := 1;"));
1727 ASSERT_STREQ("::val := ...;\n", str.c_str());
1728
1729 str = AstAnalysis::MakeInclude(Parser::ParseString("::val := 1; val2 := 1; @::val3 := 1"));
1730 ASSERT_STREQ("::val := ...;\n@::val3 := ...;\n", str.c_str());
1731
1732 str = AstAnalysis::MakeInclude(Parser::ParseString("::val, val2, @::val3 := 1"));
1733 ASSERT_STREQ("::val := ...;\n@::val3 := ...;\n", str.c_str());
1734
1735 str = AstAnalysis::MakeInclude(Parser::ParseString("@@ macro @@ := 1; @@ macro2 @@ := @@ 2 @@; @@@@ macro @@@@;"));
1736 ASSERT_STREQ("@@ macro @@ := 1;\n@@ macro2 @@ := @@ 2 @@;\n@@@@ macro @@@@;\n", str.c_str());
1737
1738}
1739#endif // UNITTEST
Definition nlc.h:59
const TermPtr getDefaultType(const std::string_view text)
Definition parser.cpp:1072
std::string ExtractName(std::string name)
Definition types.h:1223
std::shared_ptr< Term > TermPtr
Definition variable.h:33
std::shared_ptr< Obj > ObjPtr
Definition variable.h:28
std::shared_ptr< RunTime > RuntimePtr
Definition types.h:242
std::string ExtractModuleName(const std::string_view name)
Definition types.h:1188