NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
thread_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#include <chrono>
8#include <stdio.h>
9
10#include "runtime.h"
11#include "analysis.h"
12#include "jit.h"
13
14using namespace newlang;
15
16
17#include <iostream>
18#include <thread>
19#include <atomic>
20
21TEST(Thread, Atomic) {
22
23 unsigned long long not_atomic = 0;
24
25 std::thread t1([&not_atomic]() {
26 for (auto i = 0; i < 1'000'000; ++i) {
27 ++not_atomic;
28 }
29 });
30
31 std::thread t2([&not_atomic]() {
32 for (auto i = 0; i < 1'000'000; ++i) {
33 ++not_atomic;
34 }
35 });
36
37 t1.join();
38 t2.join();
39
40 EXPECT_NE(not_atomic, 2'000'000);
41
42
43 std::atomic<unsigned long long> g_count{ 0};
44
45 std::thread at1([&g_count]() {
46 for (auto i = 0; i < 1'000'000; ++i) {
47 g_count.fetch_add(1);
48 }
49 });
50
51 std::thread at2([&g_count]() {
52 for (auto i = 0; i < 1'000'000; ++i) {
53 g_count.fetch_add(1);
54 }
55 });
56
57 at1.join();
58 at2.join();
59
60 EXPECT_EQ(g_count, 2'000'000);
61}
62
63// parallel_sum.cpp
64// https://helloacm.com/how-to-async-and-await-in-c11/
65#include <iostream>
66#include <vector>
67#include <future>
68
69// for use of std::accumulate
70#if _MSC_VER
71#include <numeric> // in Visual Studio
72#else
73#include <algorithm> // g++ -std=c++14 -pthread parallel_sum.cpp
74#endif
75
76using namespace std;
77
78//std::atomic<unsigned long long> async_count{0};
79//
81//
82//template <typename TYPE>
83//int parallel_sum(TYPE beg, TYPE end) {
84// // block size
85// auto len = end - beg;
86// if (len < 5000) {
87// async_count.fetch_add(1);
88// // if block is small enough, it is faster to just sum them up.
89// return std::accumulate(beg, end, 0);
90// }
91// // (beg + end) / 2 may overflow
92// auto mid = beg + len / 2;
93// // sum the left part asynchronously
94// auto handle_left = std::async(launch::async, parallel_sum<TYPE>, beg, mid);
95// // sum the right part asynchronously
96// auto handle_right = std::async(launch::async, parallel_sum<TYPE>, mid, end);
97// // put them together
98// return handle_left.get() + handle_right.get();
99//}
100//
101//TEST(Thread, Async) {
102//
103// vector<int> v(100000000, 1);
104// std::cout << "Sum: " << parallel_sum(v.begin(), v.end()) << " async_count:" << async_count << std::endl;
105
106
107
108
109#include <thread>
110#include <chrono>
111#include <vector>
112#include <future>
113#include <iostream>
114
115__thread volatile int you_shall_not_optimize_this;
116
117void work() {
118 // This is the simplest way I can think of to prevent the compiler and
119 // operating system from doing naughty things
120 you_shall_not_optimize_this = 42;
121}
122
123[[gnu::noinline]]
124std::chrono::nanoseconds benchmark_threads(size_t count) {
125 std::vector<std::optional < std::thread>> threads;
126 threads.resize(count);
127
128 auto before = std::chrono::high_resolution_clock::now();
129
130 for (size_t i = 0; i < count; ++i)
131 threads[i] = std::thread{work};
132
133 for (size_t i = 0; i < count; ++i)
134 threads[i]->join();
135
136 threads.clear();
137
138 auto after = std::chrono::high_resolution_clock::now();
139
140 return after - before;
141}
142
143[[gnu::noinline]]
144std::chrono::nanoseconds benchmark_async(size_t count, std::launch policy) {
145 std::vector<std::optional<std::future<void>>> results;
146 results.resize(count);
147
148 auto before = std::chrono::high_resolution_clock::now();
149
150 for (size_t i = 0; i < count; ++i)
151 results[i] = std::async(policy, work);
152
153 for (size_t i = 0; i < count; ++i)
154 results[i]->wait();
155
156 results.clear();
157
158 auto after = std::chrono::high_resolution_clock::now();
159
160 return after - before;
161}
162
163
164void stat_out(std::chrono::nanoseconds duration) {
165 std::cout << "Completed in " << duration.count() << "ns (" << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << "ms)\n";
166}
167
168TEST(Thread, Async) {
169
170
171 /*
172 * launch::async – если передан этот флаг, то поведение async будет следующим:
173 * будет создан объект класса thread, с функцией и её аргументами в качестве аргументов нового потока.
174 * Т.е. async инкапсулирует создание потока, получение future и предоставляет однострочную запись для выполнения
175 * такого кода(скорее всего реализация будет использовать packaged_task,
176 * вместо простой передачи функции в поток, “под капотом”, но я не уверен)
177 *
178 * launch::deferred – если передан этот флаг, то имя функции async становится несколько не логичным.
179 * Т.к. никакого асинхронного вызова не произойдёт. Вместо исполнения функции в новом потоке,
180 * она, вместе с аргументами, будет сохранена в future(еще одна особенность future),
181 * чтобы быть вызванными позже. Это позже наступит тогда, когда кто-либо вызовет
182 * метод get(или wait, но не wait_for!) на future, которое вернул async.
183 * При этот вызываемый объект выполнится в потоке, который вызывал get!
184 * Это поведение есть ни что иное, как отложенный вызов процедуры.
185 */
186
187 const int count_iteration = 10000;
188
189 std::cout << "Running benchmark iterations " << count_iteration << '\n';
190 std::cout << "threads: ";
191 stat_out(benchmark_threads(count_iteration));
192 std::cout << "async: ";
193 stat_out(benchmark_async(count_iteration, std::launch::async));
194 std::cout << "deferred: ";
195 stat_out(benchmark_async(count_iteration, std::launch::deferred));
196
197
198 // const auto processor_count = std::thread::hardware_concurrency();
199 //
200 // unsigned long long not_atomic = 0;
201 //
202 // std::thread t1([&not_atomic]() {
203 // for (auto i = 0; i < 1'000'000; ++i) {
204 // usleep(1);
205 // ++not_atomic;
206 // }
207 // });
208 //
209 // std::thread t2([&not_atomic]() {
210 // for (auto i = 0; i < 1'000'000; ++i) {
211 // usleep(1);
212 // ++not_atomic;
213 // }
214 // });
215 //
216 // t1.join();
217 // t2.join();
218 //
219 // EXPECT_NE(not_atomic, 2'000'000);
220 //
221 //
222 // std::atomic<unsigned long long> g_count{ 0};
223 //
224 // std::thread at1([&g_count]() {
225 // for (auto i = 0; i < 1'000'000; ++i) {
226 // usleep(1);
227 // g_count.fetch_add(1);
228 // }
229 // });
230 //
231 // std::thread at2([&g_count]() {
232 // for (auto i = 0; i < 1'000'000; ++i) {
233 // usleep(1);
234 // g_count.fetch_add(1);
235 // }
236 // });
237 //
238 // at1.join();
239 // at2.join();
240 //
241 // EXPECT_EQ(g_count, 2'000'000);
242}
244// * Тест производительности на базе исходников из статьи
245// * https://towardsdatascience.com/how-fast-is-c-compared-to-python-978f18f474c7
246// */
247//extern "C" char convert(char c);
248//
249//TEST(Example, SpeedCPP) {
250//
251// LOG_INFO("Start speed test C++");
252//
253// std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
254//
255// std::string opt = "ACGT";
256// std::string s = "";
257// std::string s_last = "";
258// int len_str = 13;
259// bool change_next;
260//
261// for (int i = 0; i < len_str; i++) {
262// s += opt[0];
263// }
264//
265// for (int i = 0; i < len_str; i++) {
266// s_last += opt.back();
267// }
268//
269// int pos = 0;
270// int counter = 1;
271// while (s != s_last) {
272// counter++;
273// // You can uncomment the next line to see all k-mers.
274// //std::cout << s << std::endl;
275// change_next = true;
276// for (int i = 0; i < len_str; i++) {
277// if (change_next) {
278// if (s[i] == opt.back()) {
279// s[i] = convert(s[i]);
280// change_next = true;
281// } else {
282// s[i] = convert(s[i]);
283// i = len_str; // break;
284// }
285// }
286// }
287// }
288//
289// // You can uncomment the next line to see all k-mers.
290// // cout << s << endl;
291// std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
292// int sec = (int) std::chrono::duration_cast<std::chrono::seconds>(end - begin).count();
293// int ms = (int) std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() % 1000000;
294// LOG_INFO("Float of generated k-mers: %d at %d.%d sec", counter, sec, ms);
295//
296//}
297//
298//TEST(Example, DISABLED_SpeedNewLang) {
299//
300// JIT * jit = JIT::ReCreate();
301// ASSERT_TRUE(jit);
302//
303// setvbuf(stdin, nullptr, _IONBF, 0);
304// setvbuf(stdout, nullptr, _IONBF, 0);
305// setvbuf(stderr, nullptr, _IONBF, 0);
306//
307//
308// ObjPtr test;
309//
310// ObjPtr str = jit->Run("str := 'ABCDEF\\n';", nullptr);
311// ASSERT_TRUE(str);
312// ASSERT_STREQ("ABCDEF\n", str->GetValueAsString().c_str());
313//
314// test = jit->Run("str := 'ABCDEF\\n'; print('%s', str)");
315// ASSERT_TRUE(test);
316// ASSERT_STREQ("7", test->GetValueAsString().c_str());
317//
318// test = jit->Run("str[2] = 32; str", nullptr);
319// ASSERT_TRUE(test);
320// ASSERT_STREQ("AB DEF\n", test->GetValueAsString().c_str());
321//
322// test = jit->Run("str[0]", nullptr);
323// ASSERT_TRUE(test);
324// ASSERT_STREQ("A", test->GetValueAsString().c_str());
325//
326// test = jit->Run("str[1]", nullptr);
327// ASSERT_TRUE(test);
328// ASSERT_STREQ("B", test->GetValueAsString().c_str());
329//
330// test = jit->Run("str[2]", nullptr);
331// ASSERT_TRUE(test);
332// ASSERT_STREQ(" ", test->GetValueAsString().c_str());
333//
334// // LLVMAddSymbol("convert", (void *) &convert);
335// ObjPtr test_convert = jit->Run("test_convert(sym:Int8):Int8 := %convert ...");
336// ASSERT_TRUE(test_convert);
337//
338// // [c == 'A'] --> 'C',
339// // [c == 'C'] --> 'G',
340// // [c == 'G'] --> 'T',
341// // [c == 'T'] --> 'A',
342// // [_] --> ' ';
343//
344// test = jit->Run("test_convert(65)", nullptr);
345// ASSERT_TRUE(test);
346// ASSERT_STREQ("67", test->GetValueAsString().c_str());
347// test = jit->Run("test_convert(67)", nullptr);
348// ASSERT_TRUE(test);
349// ASSERT_STREQ("71", test->GetValueAsString().c_str());
350//
351// test = jit->Run("test_convert(71)", nullptr);
352// ASSERT_TRUE(test);
353// ASSERT_STREQ("84", test->GetValueAsString().c_str());
354//
355// test = jit->Run("test_convert(84)", nullptr);
356// ASSERT_TRUE(test);
357// ASSERT_STREQ("65", test->GetValueAsString().c_str());
358//
359// ASSERT_NO_THROW(test = jit->Run("str"));
360// ASSERT_TRUE(test);
361// ASSERT_STREQ("AB DEF\n", test->GetValueAsString().c_str());
362//
363// ASSERT_NO_THROW(test = jit->Run("str[0]"));
364// ASSERT_TRUE(test);
365// ASSERT_STREQ("A", test->GetValueAsString().c_str());
366//
367// ASSERT_NO_THROW(test = jit->Run(":Int8('A')"));
368// ASSERT_TRUE(test);
369// ASSERT_STREQ("65", test->GetValueAsString().c_str());
370//
371// // ASSERT_NO_THROW(test = jit->Run("test_convert('A')"));
372// // ASSERT_TRUE(test);
373// // ASSERT_STREQ("C", test->GetValueAsString().c_str());
374//
375// ASSERT_NO_THROW(test = jit->Run("test_convert(:Int8(str[0]))"));
376// ASSERT_TRUE(test);
377// ASSERT_STREQ("67", test->GetValueAsString().c_str());
378//
379// ASSERT_NO_THROW(test = jit->Run("str[0] = test_convert(:Int8(str[0])); str"));
380// ASSERT_TRUE(test);
381// ASSERT_STREQ("CB DEF\n", test->GetValueAsString().c_str());
382//
383// Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
384// std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
385// ObjPtr result = jit->RunFile("../examples/speed_test.src");
386// std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
387// Logger::Instance()->SetLogLevel(save);
388//
389//
390//
391// ASSERT_TRUE(result);
392// ASSERT_TRUE(result->is_string_type()) << result->toString();
393// ASSERT_STREQ("OK", result->GetValueAsString().c_str());
394//
395//
396// int sec = (int) std::chrono::duration_cast<std::chrono::seconds>(end - begin).count();
397// int ms = (int) std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() % 1000000;
398// LOG_INFO("Test speed complete at %d.%d sec", sec, ms);
399//
400// /*
401// *
402// * Start speed test C++
403// * Float of generated k-mers: 67108864 at 2.502049 sec
404// *
405// * Start
406// * Float of generated k-mers: 67108864
407// * real 0m33,794s
408// *
409// * Start speed test NewLang
410// * Float of generated k-mers: 67108864
411// * Test complete at ????????????????????
412// *
413// * Своя функция convert
414// * 5 символов - 1.3 сек (с вывоводм строк) 0.491895 sec - без вывода строк
415// * 6 символов - 14.789793 sec (с вывоводм строк) 1.898168 sec - без вывода строк
416// * 7 символов без вывода строк - 7.671152 sec
417// * 8 символов без вывода строк - 30.412468 sec
418// *
419// * Импорт С++ функции convert
420// * 5 символов - 1.23 сек (с вывоводм строк) 0.53 sec - без вывода строк
421// * 6 символов - 13.538338 sec (с вывоводм строк) 2.30900 sec - без вывода строк
422// * 7 символов без вывода строк - 8.43029 sec
423// * 8 символов без вывода строк - 32.154832 sec
424// *
425// * После переделки способа хранения скаляров в нативном виде, а не в тензорах
426// * Своя функция convert
427// * 5 символов - 1.255214 сек (с вывоводм строк) 0.306725 sec - без вывода строк
428// * 6 символов - 15.995722 sec (с вывоводм строк) 1.253190 sec - без вывода строк
429// * 7 символов без вывода строк - 5.12946 sec
430// * 8 символов без вывода строк - 19.653851 sec
431// *
432// * Импорт С++ функции convert
433// * 5 символов - 1.195008 sec (с вывоводм строк) 0.351575 sec - без вывода строк
434// * 6 символов - 13.666785 sec (с вывоводм строк) 1.428339 sec - без вывода строк
435// * 7 символов без вывода строк - 5.628200 sec
436// * 8 символов без вывода строк - 22.258760 sec
437// *
438// * Start speed test NewLang
439// * From AAAAAAAAAA to TTTTTTTTTT
440// * Float of generated k-mers: 1048576
441// * Test complete at 320.401650 sec (более 5 минут)
442// *
443// * Никакой оптимизации не проводилось.
444// * Программа не преобразуется в промежуточный byte-code, а интерпретируется какждый раз при выполнении.
445// * LLVM код вызова нативных функий генерируется каждый раз, не при создании функции.
446// * Возможности для оптимиации производительности чрезвычайно общширны ;-)
447// */
448//}
449//
580//
679//
680//TEST(Example, Hello) {
681//
682// JIT *jit = JIT::ReCreate();
683// ASSERT_TRUE(jit);
684//
685// ObjPtr prn;
686// ASSERT_NO_THROW(prn = jit->Run("prn(format:FmtChar, ...):Int32 := %printf ..."));
687// ASSERT_TRUE(prn);
688//
689// ObjPtr res = (*prn)("Привет, мир!\n");
690// ASSERT_TRUE(res);
691// ASSERT_TRUE(res->is_integer()) << res->toString();
692// ASSERT_STREQ("22", res->GetValueAsString().c_str());
693//
694// // ObjPtr func = jit->Run("func(arg) := {$arg}");
695// // ASSERT_TRUE(func);
696// //
697// // res = (*func)("TEST");
698// // ASSERT_TRUE(res);
699// // ASSERT_TRUE(res->is_string_char_type()) << res->toString();
700// // ASSERT_STREQ("TEST", res->GetValueAsString().c_str());
701// // hello(str) := {
702// // printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции
703// // printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата
704// // };
705// // hello('Привет, мир!'); # Вызвать функцию
706//
707//
708// setvbuf(stdin, nullptr, _IONBF, 0);
709// setvbuf(stdout, nullptr, _IONBF, 0);
710// setvbuf(stderr, nullptr, _IONBF, 0);
711//
712//
713// Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
714// std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
715// ObjPtr result = jit->RunFile("../examples/hello.src");
716// std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
717// Logger::Instance()->SetLogLevel(save);
718//
719//
720// ASSERT_TRUE(result);
721// ASSERT_TRUE(result->is_integral()) << result->toString();
722// ASSERT_STREQ("14", result->GetValueAsString().c_str());
723//
724//
725// // save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
726// // begin = std::chrono::steady_clock::now();
727// // ASSERT_NO_THROW(result = jit->Run("\\\\‍('../examples/hello.src')"));
728// // end = std::chrono::steady_clock::now();
729// // Logger::Instance()->SetLogLevel(save);
730// //
731// //
732// // ASSERT_TRUE(result);
733// // ASSERT_TRUE(result->is_integral()) << result->toString();
734// // ASSERT_STREQ("14", result->GetValueAsString().c_str());
735//}
736//
737//TEST(Example, Exec) {
738// JIT * jit = JIT::ReCreate({"--nlc-no-eval-enable"});
739// ASSERT_TRUE(jit);
740//
741// ASSERT_FALSE(jit->m_eval_enable);
742// ASSERT_ANY_THROW(jit->Run("`ls`"));
743// jit->m_eval_enable = true;
744//
745// ObjPtr exec;
746// ASSERT_NO_THROW(exec = jit->Run("`ls`"));
747// ASSERT_TRUE(exec);
748// ASSERT_TRUE(exec->is_string_char_type()) << exec->toString();
749// ASSERT_TRUE(exec->GetValueAsString().find("nlc-unittest\n") != std::string::npos) << exec->GetValueAsString();
750//}
751//
752//TEST(Example, Fibonacci) {
753//
754// JIT *jit = JIT::ReCreate();
755// ASSERT_TRUE(jit);
756//
757//
758// ObjPtr temp;
759// ASSERT_NO_THROW(temp = jit->Run("dict ::= (1+2, 5, 9,);\n"));
760// ASSERT_STREQ("(3, 5, 9,)", temp->toString().c_str()) << temp->toString();
761//
762// ASSERT_NO_THROW(temp = jit->Run("dict[0]"));
763// ASSERT_STREQ("3", temp->toString().c_str()) << temp->toString();
764//
765// ASSERT_NO_THROW(temp = jit->Run("dict[1]"));
766// ASSERT_STREQ("5", temp->toString().c_str()) << temp->toString();
767//
768// ASSERT_NO_THROW(temp = jit->Run("dict[1+1]"));
769// ASSERT_STREQ("9", temp->toString().c_str()) << temp->toString();
770//
771// ASSERT_NO_THROW(temp = jit->Run("( dict[1], dict[2], )"));
772// ASSERT_STREQ("(5, 9,)", temp->toString().c_str()) << temp->toString();
773//
774//
775// ASSERT_NO_THROW(temp = jit->Run("( dict[0]+dict[1], dict[2], )"));
776// ASSERT_STREQ("(8, 9,)", temp->toString().c_str()) << temp->toString();
777//
778// ASSERT_NO_THROW(temp = jit->Run("{+ var := 1; { var := 2; ++ var ++; } +}"));
779// ASSERT_STREQ("2", temp->toString().c_str()) << temp->toString();
780//
781// ASSERT_NO_THROW(temp = jit->Run("{* varth := 1; { varth := 2; @throw varth; } *}"));
782// ASSERT_STREQ("2", temp->toString().c_str()) << temp->toString();
783//
784// ASSERT_NO_THROW(temp = jit->Run("var2 := 22; { var2 := 33; }; var2"));
785// ASSERT_STREQ("22", temp->toString().c_str()) << temp->toString();
786//
787// ObjPtr fib;
788// ASSERT_NO_THROW(fib = jit->Run("fib_test(n) := {\n"
789// " @if(n < 3){ \n"
790// " @return (1\\1, 1\\1,);\n"
791// " };\n"
792// " p := fib_test(n-1);\n"
793// " @return (p[0] + p[1], p[0],);\n"
794// "};\n"));
795// ASSERT_TRUE(fib);
796// // return и throw - без скобок как оператор
797// // запятые в аргументах макросов ?????????????????
798//
799// std::cout << "\n1:\n\n";
800// ASSERT_NO_THROW(temp = jit->Run("fib_test(1)"));
801// ASSERT_TRUE(temp);
802// ASSERT_STREQ("(1\\1, 1\\1,)", temp->toString().c_str()) << temp->toString();
803//
804// std::cout << "\n2:\n\n";
805// ASSERT_NO_THROW(temp = jit->Run("fib_test(2)"));
806// ASSERT_TRUE(temp);
807// ASSERT_STREQ("(1\\1, 1\\1,)", temp->toString().c_str()) << temp->toString();
808//
809// std::cout << "\n3:\n\n";
810// ASSERT_NO_THROW(temp = jit->Run("fib_test(3)"));
811// ASSERT_TRUE(temp);
812// ASSERT_STREQ("(2\\1, 1\\1,)", temp->toString().c_str()) << temp->toString();
813//
814// ASSERT_NO_THROW(temp = jit->Run("fib_test(4)"));
815// ASSERT_TRUE(temp);
816// ASSERT_STREQ("(3\\1, 2\\1,)", temp->toString().c_str()) << temp->toString();
817//
818// ASSERT_NO_THROW(temp = jit->Run("fib_test(5)"));
819// ASSERT_TRUE(temp);
820// ASSERT_STREQ("(5\\1, 3\\1,)", temp->toString().c_str()) << temp->toString();
821//
822// ASSERT_NO_THROW(temp = jit->Run("fib_test(6)"));
823// ASSERT_TRUE(temp);
824// ASSERT_STREQ("(8\\1, 5\\1,)", temp->toString().c_str()) << temp->toString();
825//
826// // ASSERT_NO_THROW(temp = jit->Run("fib_test(100)"));
827// // ASSERT_TRUE(temp);
828// // ASSERT_STREQ("(354224848179261915075\\1, 218922995834555169026\\1,)", temp->toString().c_str()) << temp->toString();
829// //
830// // ASSERT_NO_THROW(temp = jit->Run("fib_test(250)"));
831// // ASSERT_TRUE(temp);
832// // ASSERT_STREQ("(7896325826131730509282738943634332893686268675876375\\1, 4880197746793002076754294951020699004973287771475874\\1,)", temp->toString().c_str()) << temp->toString();
833//
834//
835//
836// ObjPtr calc;
837// ASSERT_NO_THROW(calc = jit->Run(""
838// "'{1}'(123456); \n"
839// ));
840// ASSERT_TRUE(calc);
841// ASSERT_STREQ("'123456'", calc->toString().c_str()) << calc->toString();
842//
843//
844// ObjPtr time;
845// ASSERT_NO_THROW(time = jit->Run(""
846// "@timeit( fib_test(5) ); \n"
847// ));
848// ASSERT_TRUE(time);
849// ASSERT_TRUE(time->toString().find("'Exec time 'fib_test(5)':") == 0) << time->toString();
850//
851//
852//
853// ObjPtr fib_calc;
854// ASSERT_NO_THROW(fib_calc = jit->Run("fib_calc(n) := {\n"
855// " res := fib_test(n);\n"
856// " $value := '{1}'( res[1] );\n"
857// " print('%d: %d\\n%s\\n', $n, len($value), $value);\n"
858// "};\n"));
859// ASSERT_TRUE(fib_calc);
860//
861// ASSERT_NO_THROW(fib_calc = jit->Run("fib_calc(5)")) << fib_calc->m_sequence->toString();
862// ASSERT_TRUE(fib_calc);
863//
864//
865//
866//
867// setvbuf(stdin, nullptr, _IONBF, 0);
868// setvbuf(stdout, nullptr, _IONBF, 0);
869// setvbuf(stderr, nullptr, _IONBF, 0);
870//
871//
872// Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
873// std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
874// ObjPtr result = jit->RunFile("../examples/fibonacci.src");
875// std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
876// Logger::Instance()->SetLogLevel(save);
877//
878// ASSERT_TRUE(result);
879// ASSERT_TRUE(result->is_string_type()) << result->toString();
880// ASSERT_TRUE(result->toString().find("'Exec time 'calc(") == 0) << result->toString();
881//
882//}
883//
1084//
1085//TEST(Example, Thread_With) {
1086//
1087// JIT *jit = JIT::ReCreate();
1088// ASSERT_TRUE(jit);
1089//
1090// // ObjPtr prn;
1091// // ASSERT_NO_THROW(prn = jit->Run("prn(format:FmtChar, ...):Int32 := %printf ..."));
1092// // ASSERT_TRUE(prn);
1093// //
1094// // ObjPtr res = (*prn)("Привет, мир!\n");
1095// // ASSERT_TRUE(res);
1096// // ASSERT_TRUE(res->is_integer()) << res->toString();
1097// // ASSERT_STREQ("22", res->GetValueAsString().c_str());
1098// //
1099// // // ObjPtr func = jit->Run("func(arg) := {$arg}");
1100// // // ASSERT_TRUE(func);
1101// // //
1102// // // res = (*func)("TEST");
1103// // // ASSERT_TRUE(res);
1104// // // ASSERT_TRUE(res->is_string_char_type()) << res->toString();
1105// // // ASSERT_STREQ("TEST", res->GetValueAsString().c_str());
1106// // // hello(str) := {
1107// // // printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции
1108// // // printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата
1109// // // };
1110// // // hello('Привет, мир!'); # Вызвать функцию
1111// //
1112// //
1113// // setvbuf(stdin, nullptr, _IONBF, 0);
1114// // setvbuf(stdout, nullptr, _IONBF, 0);
1115// // setvbuf(stderr, nullptr, _IONBF, 0);
1116// //
1117// //
1118// // Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1119// // std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
1120// // ObjPtr result = jit->RunFile("../examples/hello.src");
1121// // std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
1122// // Logger::Instance()->SetLogLevel(save);
1123// //
1124// //
1125// // ASSERT_TRUE(result);
1126// // ASSERT_TRUE(result->is_integral()) << result->toString();
1127// // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1128// //
1129// //
1130// // // save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1131// // // begin = std::chrono::steady_clock::now();
1132// // // ASSERT_NO_THROW(result = jit->Run("\\\\‍('../examples/hello.src')"));
1133// // // end = std::chrono::steady_clock::now();
1134// // // Logger::Instance()->SetLogLevel(save);
1135// // //
1136// // //
1137// // // ASSERT_TRUE(result);
1138// // // ASSERT_TRUE(result->is_integral()) << result->toString();
1139// // // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1140//}
1141//
1142//TEST(Example, FileIO) {
1143//
1144// JIT *jit = JIT::ReCreate();
1145// ASSERT_TRUE(jit);
1146//
1147// // ObjPtr prn;
1148// // ASSERT_NO_THROW(prn = jit->Run("prn(format:FmtChar, ...):Int32 := %printf ..."));
1149// // ASSERT_TRUE(prn);
1150// //
1151// // ObjPtr res = (*prn)("Привет, мир!\n");
1152// // ASSERT_TRUE(res);
1153// // ASSERT_TRUE(res->is_integer()) << res->toString();
1154// // ASSERT_STREQ("22", res->GetValueAsString().c_str());
1155// //
1156// // // ObjPtr func = jit->Run("func(arg) := {$arg}");
1157// // // ASSERT_TRUE(func);
1158// // //
1159// // // res = (*func)("TEST");
1160// // // ASSERT_TRUE(res);
1161// // // ASSERT_TRUE(res->is_string_char_type()) << res->toString();
1162// // // ASSERT_STREQ("TEST", res->GetValueAsString().c_str());
1163// // // hello(str) := {
1164// // // printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции
1165// // // printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата
1166// // // };
1167// // // hello('Привет, мир!'); # Вызвать функцию
1168// //
1169// //
1170// // setvbuf(stdin, nullptr, _IONBF, 0);
1171// // setvbuf(stdout, nullptr, _IONBF, 0);
1172// // setvbuf(stderr, nullptr, _IONBF, 0);
1173// //
1174// //
1175// // Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1176// // std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
1177// // ObjPtr result = jit->RunFile("../examples/hello.src");
1178// // std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
1179// // Logger::Instance()->SetLogLevel(save);
1180// //
1181// //
1182// // ASSERT_TRUE(result);
1183// // ASSERT_TRUE(result->is_integral()) << result->toString();
1184// // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1185// //
1186// //
1187// // // save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1188// // // begin = std::chrono::steady_clock::now();
1189// // // ASSERT_NO_THROW(result = jit->Run("\\\\‍('../examples/hello.src')"));
1190// // // end = std::chrono::steady_clock::now();
1191// // // Logger::Instance()->SetLogLevel(save);
1192// // //
1193// // //
1194// // // ASSERT_TRUE(result);
1195// // // ASSERT_TRUE(result->is_integral()) << result->toString();
1196// // // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1197//}
1198//
1199//TEST(Example, MatchCase) {
1200//
1201// JIT *jit = JIT::ReCreate();
1202// ASSERT_TRUE(jit);
1203//
1204// // ObjPtr prn;
1205// // ASSERT_NO_THROW(prn = jit->Run("prn(format:FmtChar, ...):Int32 := %printf ..."));
1206// // ASSERT_TRUE(prn);
1207// //
1208// // ObjPtr res = (*prn)("Привет, мир!\n");
1209// // ASSERT_TRUE(res);
1210// // ASSERT_TRUE(res->is_integer()) << res->toString();
1211// // ASSERT_STREQ("22", res->GetValueAsString().c_str());
1212// //
1213// // // ObjPtr func = jit->Run("func(arg) := {$arg}");
1214// // // ASSERT_TRUE(func);
1215// // //
1216// // // res = (*func)("TEST");
1217// // // ASSERT_TRUE(res);
1218// // // ASSERT_TRUE(res->is_string_char_type()) << res->toString();
1219// // // ASSERT_STREQ("TEST", res->GetValueAsString().c_str());
1220// // // hello(str) := {
1221// // // printf := :Pointer('printf(format:FmtChar, ...):Int32'); # Импорт стандартной C функции
1222// // // printf('%s\n', $str); # Вызов C функции с проверкой типов аргументов по строке формата
1223// // // };
1224// // // hello('Привет, мир!'); # Вызвать функцию
1225// //
1226// //
1227// // setvbuf(stdin, nullptr, _IONBF, 0);
1228// // setvbuf(stdout, nullptr, _IONBF, 0);
1229// // setvbuf(stderr, nullptr, _IONBF, 0);
1230// //
1231// //
1232// // Logger::LogLevelType save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1233// // std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
1234// // ObjPtr result = jit->RunFile("../examples/hello.src");
1235// // std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
1236// // Logger::Instance()->SetLogLevel(save);
1237// //
1238// //
1239// // ASSERT_TRUE(result);
1240// // ASSERT_TRUE(result->is_integral()) << result->toString();
1241// // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1242// //
1243// //
1244// // // save = Logger::Instance()->SetLogLevel(LOG_LEVEL_INFO);
1245// // // begin = std::chrono::steady_clock::now();
1246// // // ASSERT_NO_THROW(result = jit->Run("\\\\‍('../examples/hello.src')"));
1247// // // end = std::chrono::steady_clock::now();
1248// // // Logger::Instance()->SetLogLevel(save);
1249// // //
1250// // //
1251// // // ASSERT_TRUE(result);
1252// // // ASSERT_TRUE(result->is_integral()) << result->toString();
1253// // // ASSERT_STREQ("14", result->GetValueAsString().c_str());
1254//}
1255
1256#endif // UNITTEST
Definition nlc.h:59