compile-test.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include "gtest/gtest.h"
  2. extern "C" {
  3. #include "PikaMain.h"
  4. #include "PikaParser.h"
  5. #include "PikaStdLib_MemChecker.h"
  6. #include "PikaVM.h"
  7. #include "dataArgs.h"
  8. #include "dataMemory.h"
  9. #include "dataStrs.h"
  10. #include "pikaCompiler.h"
  11. #include "pikaScript.h"
  12. #include "pika_config_gtest.h"
  13. }
  14. extern char log_buff[LOG_BUFF_MAX][LOG_SIZE];
  15. TEST(compiler, file) {
  16. char* lines =(char*)
  17. "len = __calls.len()\n"
  18. "mode = 'none'\n"
  19. "info_index = 0\n"
  20. "for i in range(0, len):\n"
  21. " if len == 0:\n"
  22. " break\n"
  23. " if info_index == 0:\n"
  24. " mode = __calls[i]\n"
  25. " info_index = 1\n"
  26. " elif info_index == 1:\n"
  27. " if mode == 'always':\n"
  28. " todo = __calls[i]\n"
  29. " todo()\n"
  30. " info_index = 0\n"
  31. " elif mode == 'when':\n"
  32. " when = __calls[i]\n"
  33. " info_index = 2\n"
  34. " elif mode == 'period_ms':\n"
  35. " period_ms = __calls[i]\n"
  36. " info_index = 2\n"
  37. " elif info_index == 2:\n"
  38. " if mode == 'when':\n"
  39. " if when():\n"
  40. " todo = __calls[i]\n"
  41. " todo()\n"
  42. " info_index = 0\n"
  43. " elif mode == 'period_ms':\n"
  44. " todo = __calls[i]\n"
  45. " info_index = 3\n"
  46. " elif info_index == 3:\n"
  47. " if mode == 'period_ms':\n"
  48. " if __tick > __calls[i]:\n"
  49. " todo()\n"
  50. " __calls[i] = __tick + period_ms\n"
  51. " info_index = 0\n"
  52. "\n";
  53. pikaCompile((char*)"task.bin", (char*)lines);
  54. EXPECT_EQ(pikaMemNow(), 0);
  55. }
  56. TEST(compiler, task) {
  57. char* lines =(char*)
  58. "len = __calls.len()\n"
  59. "mode = 'none'\n"
  60. "info_index = 0\n"
  61. "for i in range(0, len):\n"
  62. " if len == 0:\n"
  63. " break\n"
  64. " if info_index == 0:\n"
  65. " mode = __calls[i]\n"
  66. " info_index = 1\n"
  67. " elif info_index == 1:\n"
  68. " if mode == 'always':\n"
  69. " todo = __calls[i]\n"
  70. " todo()\n"
  71. " info_index = 0\n"
  72. " elif mode == 'when':\n"
  73. " when = __calls[i]\n"
  74. " info_index = 2\n"
  75. " elif mode == 'period_ms':\n"
  76. " period_ms = __calls[i]\n"
  77. " info_index = 2\n"
  78. " elif info_index == 2:\n"
  79. " if mode == 'when':\n"
  80. " if when():\n"
  81. " todo = __calls[i]\n"
  82. " todo()\n"
  83. " info_index = 0\n"
  84. " elif mode == 'period_ms':\n"
  85. " todo = __calls[i]\n"
  86. " info_index = 3\n"
  87. " elif info_index == 3:\n"
  88. " if mode == 'period_ms':\n"
  89. " if __tick > __calls[i]:\n"
  90. " todo()\n"
  91. " __calls[i] = __tick + period_ms\n"
  92. " info_index = 0\n"
  93. "\n";
  94. Args buffs = {0};
  95. char* pikaAsm = Parser_multiLineToAsm(&buffs, (char*)lines);
  96. ByteCodeFrame bytecode_frame;
  97. byteCodeFrame_init(&bytecode_frame);
  98. byteCodeFrame_appendFromAsm(&bytecode_frame, pikaAsm);
  99. /* do something */
  100. byteCodeFrame_print(&bytecode_frame);
  101. printf("Asm size: %d\r\n", strGetSize(pikaAsm));
  102. byteCodeFrame_printAsArray(&bytecode_frame);
  103. /* deinit */
  104. byteCodeFrame_deinit(&bytecode_frame);
  105. strsDeinit(&buffs);
  106. EXPECT_EQ(pikaMemNow(), 0);
  107. }
  108. TEST(compiler, demo1) {
  109. char* lines = (char*)"append(__val)";
  110. Parser_compilePyToBytecodeArray(lines);
  111. EXPECT_EQ(pikaMemNow(), 0);
  112. }
  113. TEST(compiler, snake_file) {
  114. char* lines =(char*)
  115. "from PikaObj import *\n"
  116. "import PikaStdLib\n"
  117. "import machine \n"
  118. "\n"
  119. "# hardware init\n"
  120. "lcd = machine.LCD()\n"
  121. "lcd.init()\n"
  122. "lcd.clear('white')\n"
  123. "key = machine.KEY()\n"
  124. "key.init()\n"
  125. "time = machine.Time()\n"
  126. "x_max = 120\n"
  127. "y_max = 150\n"
  128. "\n"
  129. "# snake init\n"
  130. "s = machine.Point()\n"
  131. "w = 9\n"
  132. "h = 9\n"
  133. "s.x = 50\n"
  134. "s.y = 10\n"
  135. "len = 0\n"
  136. "while len < 3:\n"
  137. " b = s\n"
  138. " i = 0\n"
  139. " while i < len:\n"
  140. " b = b.next\n"
  141. " i = i + 1\n"
  142. " b.next = machine.Point()\n"
  143. " b.next.x = b.x - 10\n"
  144. " b.next.y = b.y\n"
  145. " b.next.prev = b\n"
  146. " len = len + 1\n"
  147. "# ring link\n"
  148. "b.next = s\n"
  149. "s.prev = b\n"
  150. "\n"
  151. "i = 0\n"
  152. "b = s\n"
  153. "while i < len:\n"
  154. " lcd.fill(b.x, b.y, w, h, 'blue')\n"
  155. " b = b.next\n"
  156. " i = i + 1\n"
  157. "\n"
  158. "print('snake lengh')\n"
  159. "print(len)\n"
  160. "\n"
  161. "# fruit init\n"
  162. "f = machine.Point()\n"
  163. "f.x = 30\n"
  164. "f.y = 20\n"
  165. "lcd.fill(f.x, f.y, w, h, 'green')\n"
  166. "\n"
  167. "# memory check\n"
  168. "mem = PikaStdLib.MemChecker()\n"
  169. "print('mem used max:')\n"
  170. "mem.max()\n"
  171. "\n"
  172. "# main loop\n"
  173. "d = 0\n"
  174. "isUpdate = 1\n"
  175. "isEat = 0\n"
  176. "while True:\n"
  177. " if isUpdate:\n"
  178. " # isUpdate = 0\n"
  179. " # check eat fruit\n"
  180. " if f.x == s.x and f.y == s.y:\n"
  181. " # have eat fruit\n"
  182. " isEat = 1\n"
  183. " f.x = f.x + 30\n"
  184. " if f.x > x_max:\n"
  185. " f.x = f.x - x_max\n"
  186. " f.y = f.y + 30\n"
  187. " if f.y > y_max:\n"
  188. " f.y = f.y - y_max\n"
  189. " lcd.fill(f.x, f.y, w, h, 'green')\n"
  190. " # move snake by the direction\n"
  191. " if d == 0:\n"
  192. " x_new = s.x + 10\n"
  193. " y_new = s.y\n"
  194. " if x_new > x_max:\n"
  195. " x_new = 0\n"
  196. " elif d == 1:\n"
  197. " x_new = s.x\n"
  198. " y_new = s.y - 10\n"
  199. " if y_new < 0:\n"
  200. " y_new = y_max\n"
  201. " elif d == 2:\n"
  202. " x_new = s.x\n"
  203. " y_new = s.y + 10\n"
  204. " if y_new > y_max:\n"
  205. " y_new = 0\n"
  206. " elif d == 3:\n"
  207. " x_new = s.x - 10\n"
  208. " y_new = s.y\n"
  209. " if x_new < 0:\n"
  210. " x_new = x_max\n"
  211. " if isEat:\n"
  212. " isEat = 0\n"
  213. " b_new = machine.Point()\n"
  214. " b_new.x = x_new\n"
  215. " b_new.y = y_new\n"
  216. " b_new.prev = s.prev\n"
  217. " b_new.next = s\n"
  218. " s.prev.next = b_new\n"
  219. " s.prev = b_new\n"
  220. " s = b_new\n"
  221. " len = len + 1\n"
  222. " print('snake lengh')\n"
  223. " print(len)\n"
  224. " print('mem used max:')\n"
  225. " mem.max()\n"
  226. " # drow the snake and fruit\n"
  227. " # clear last body\n"
  228. " lcd.fill(s.prev.x, s.prev.y, w, h, 'white')\n"
  229. " # new body\n"
  230. " s.prev.x = x_new\n"
  231. " s.prev.y = y_new\n"
  232. " # head is last body\n"
  233. " s = s.prev\n"
  234. " lcd.fill(s.x, s.y, w, h, 'blue')\n"
  235. " b = s\n"
  236. " i = 0\n"
  237. " # scan key\n"
  238. " key_val = key.get()\n"
  239. " if key_val == 0:\n"
  240. " d = 0\n"
  241. " isUpdate = 1\n"
  242. " elif key_val == 1:\n"
  243. " d = 1\n"
  244. " isUpdate = 1\n"
  245. " elif key_val == 2:\n"
  246. " d = 2\n"
  247. " isUpdate = 1\n"
  248. " elif key_val == 3:\n"
  249. " d = 3\n"
  250. " isUpdate = 1\n";
  251. pikaCompile((char*)"snake.bin", (char*)lines);
  252. EXPECT_EQ(pikaMemNow(), 0);
  253. }
  254. TEST(compiler, import_bf_mem) {
  255. PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain);
  256. char* lines =(char*)
  257. "def mytest():\n"
  258. " print('test')\n"
  259. "\n";
  260. ByteCodeFrame bf;
  261. byteCodeFrame_init(&bf);
  262. bytecodeFrame_fromMultiLine(&bf, lines);
  263. obj_importModuleWithByteCodeFrame(pikaMain, (char*)"mtest", &bf);
  264. byteCodeFrame_deinit(&bf);
  265. obj_deinit(pikaMain);
  266. EXPECT_EQ(pikaMemNow(), 0);
  267. }
  268. TEST(compiler, import_bf1) {
  269. PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain);
  270. char* lines =(char*)
  271. "def mytest():\n"
  272. " print('test_import_bf1')\n"
  273. "\n";
  274. ByteCodeFrame bf;
  275. byteCodeFrame_init(&bf);
  276. bytecodeFrame_fromMultiLine(&bf, lines);
  277. obj_importModuleWithByteCodeFrame(pikaMain, (char*)"mtest", &bf);
  278. obj_run(pikaMain, (char*)
  279. "mtest.mytest()\n"
  280. "\n"
  281. );
  282. EXPECT_STREQ(log_buff[0], "test_import_bf1\r\n");
  283. byteCodeFrame_deinit(&bf);
  284. obj_deinit(pikaMain);
  285. EXPECT_EQ(pikaMemNow(), 0);
  286. }
  287. TEST(compiler, import_bf2) {
  288. PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain);
  289. char* lines =(char*)
  290. "class Test:\n"
  291. " def mytest(self):\n"
  292. " print('test_import_bf2')\n"
  293. "\n";
  294. ByteCodeFrame bf;
  295. byteCodeFrame_init(&bf);
  296. bytecodeFrame_fromMultiLine(&bf, lines);
  297. obj_importModuleWithByteCodeFrame(pikaMain, (char*)"mtest", &bf);
  298. obj_run(pikaMain, (char*)
  299. "m = mtest.Test()\n"
  300. "m.mytest()\n"
  301. "\n"
  302. );
  303. byteCodeFrame_deinit(&bf);
  304. obj_deinit(pikaMain);
  305. EXPECT_STREQ(log_buff[0], "test_import_bf2\r\n");
  306. EXPECT_EQ(pikaMemNow(), 0);
  307. }
  308. TEST(compiler, file1) {
  309. pikaCompileFile((char*)"test/python/main.py");
  310. EXPECT_EQ(pikaMemNow(), 0);
  311. }
  312. TEST(compiler, file2) {
  313. pikaCompileFile((char*)"test/python/main_snake_LCD.py");
  314. EXPECT_EQ(pikaMemNow(), 0);
  315. }
  316. TEST(lib, init) {
  317. PikaLib* lib = New_PikaLib();
  318. PikaLib_deinit(lib);
  319. EXPECT_EQ(pikaMemNow(), 0);
  320. }
  321. TEST(lib, lib_link_bytecode) {
  322. PikaLib* lib = New_PikaLib();
  323. PikaLib_LinkByteCode(lib, "module1", (uint8_t*)0x3344);
  324. EXPECT_STREQ(obj_getStr(lib, "index.module1.name"), "module1");
  325. EXPECT_EQ((uintptr_t)obj_getPtr(lib, "index.module1.bytecode"), 0x3344);
  326. /* deinit */
  327. PikaLib_deinit(lib);
  328. EXPECT_EQ(pikaMemNow(), 0);
  329. }