finsh_compiler.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  1. /*
  2. * File : finsh_compiler.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-03-22 Bernard first version
  13. */
  14. #include <finsh.h>
  15. #include "finsh_node.h"
  16. #include "finsh_error.h"
  17. #include "finsh_var.h"
  18. #include "finsh_ops.h"
  19. union finsh_value* finsh_compile_sp; /* stack pointer */
  20. u_char* finsh_compile_pc; /* PC */
  21. #define finsh_code_byte(x) do { *finsh_compile_pc = (x); finsh_compile_pc ++; } while(0)
  22. #define finsh_code_word(x) do { FINSH_SET16(finsh_compile_pc, x); finsh_compile_pc +=2; } while(0)
  23. #define finsh_code_dword(x) do { FINSH_SET32(finsh_compile_pc, x); finsh_compile_pc +=4; } while(0)
  24. static int finsh_compile(struct finsh_node* node)
  25. {
  26. if (node != NULL)
  27. {
  28. /* compile child node */
  29. if (finsh_node_child(node) != NULL)
  30. finsh_compile(finsh_node_child(node));
  31. /* compile current node */
  32. switch (node->node_type)
  33. {
  34. case FINSH_NODE_ID:
  35. {
  36. /* identifier::syscall */
  37. if (node->idtype & FINSH_IDTYPE_SYSCALL)
  38. {
  39. /* load address */
  40. finsh_code_byte(FINSH_OP_LD_DWORD);
  41. finsh_code_dword((long)node->id.syscall->func);
  42. }
  43. /* identifier::sysvar */
  44. else if (node->idtype & FINSH_IDTYPE_SYSVAR)
  45. {
  46. struct finsh_sysvar* sysvar;
  47. sysvar = node->id.sysvar;
  48. if (sysvar != NULL)
  49. {
  50. switch (sysvar->type)
  51. {
  52. case finsh_type_char:
  53. case finsh_type_uchar:
  54. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  55. {
  56. /* load address */
  57. finsh_code_byte(FINSH_OP_LD_DWORD);
  58. }
  59. else
  60. {
  61. /* load value */
  62. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  63. }
  64. finsh_code_dword((long)(sysvar->var));
  65. break;
  66. case finsh_type_short:
  67. case finsh_type_ushort:
  68. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  69. {
  70. /* load address */
  71. finsh_code_byte(FINSH_OP_LD_DWORD);
  72. }
  73. else
  74. {
  75. /* load value */
  76. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  77. }
  78. finsh_code_dword((long)(sysvar->var));
  79. break;
  80. case finsh_type_int:
  81. case finsh_type_uint:
  82. case finsh_type_long:
  83. case finsh_type_ulong:
  84. case finsh_type_charp:
  85. case finsh_type_shortp:
  86. case finsh_type_intp:
  87. case finsh_type_longp:
  88. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  89. {
  90. /* load address */
  91. finsh_code_byte(FINSH_OP_LD_DWORD);
  92. }
  93. else
  94. {
  95. /* load value */
  96. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  97. }
  98. finsh_code_dword((long)(sysvar->var));
  99. break;
  100. }
  101. }
  102. }
  103. /* identifier::var */
  104. else
  105. {
  106. struct finsh_var* var;
  107. var = node->id.var;
  108. if (var != NULL)
  109. {
  110. switch (var->type)
  111. {
  112. case finsh_type_char:
  113. case finsh_type_uchar:
  114. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  115. {
  116. /* load address */
  117. finsh_code_byte(FINSH_OP_LD_DWORD);
  118. }
  119. else
  120. {
  121. /* load value */
  122. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  123. }
  124. finsh_code_dword((long)&(var->value.char_value));
  125. break;
  126. case finsh_type_short:
  127. case finsh_type_ushort:
  128. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  129. {
  130. /* load address */
  131. finsh_code_byte(FINSH_OP_LD_DWORD);
  132. }
  133. else
  134. {
  135. /* load value */
  136. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  137. }
  138. finsh_code_dword((long)&(var->value.short_value));
  139. break;
  140. case finsh_type_int:
  141. case finsh_type_uint:
  142. case finsh_type_long:
  143. case finsh_type_ulong:
  144. case finsh_type_charp:
  145. case finsh_type_shortp:
  146. case finsh_type_intp:
  147. case finsh_type_longp:
  148. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  149. {
  150. /* load address */
  151. finsh_code_byte(FINSH_OP_LD_DWORD);
  152. }
  153. else
  154. {
  155. /* load value */
  156. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  157. }
  158. finsh_code_dword((long)&(var->value.long_value));
  159. break;
  160. }
  161. }
  162. }
  163. }
  164. break;
  165. /* load const */
  166. case FINSH_NODE_VALUE_CHAR:
  167. finsh_code_byte(FINSH_OP_LD_BYTE);
  168. finsh_code_byte(node->value.char_value);
  169. break;
  170. case FINSH_NODE_VALUE_INT:
  171. case FINSH_NODE_VALUE_LONG:
  172. finsh_code_byte(FINSH_OP_LD_DWORD);
  173. finsh_code_dword(node->value.long_value);
  174. break;
  175. case FINSH_NODE_VALUE_NULL:
  176. case FINSH_NODE_VALUE_STRING:
  177. finsh_code_byte(FINSH_OP_LD_DWORD);
  178. finsh_code_dword((u_long)node->value.ptr);
  179. break;
  180. /* arithmetic operation */
  181. case FINSH_NODE_SYS_ADD:
  182. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_ADD_BYTE);
  183. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_ADD_WORD);
  184. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_ADD_DWORD);
  185. break;
  186. case FINSH_NODE_SYS_SUB:
  187. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SUB_BYTE);
  188. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SUB_WORD);
  189. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SUB_DWORD);
  190. break;
  191. case FINSH_NODE_SYS_MUL:
  192. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MUL_BYTE);
  193. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MUL_WORD);
  194. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MUL_DWORD);
  195. break;
  196. case FINSH_NODE_SYS_DIV:
  197. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_DIV_BYTE);
  198. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_DIV_WORD);
  199. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_DIV_DWORD);
  200. break;
  201. case FINSH_NODE_SYS_MOD:
  202. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MOD_BYTE);
  203. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MOD_WORD);
  204. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MOD_DWORD);
  205. break;
  206. /* bit operation */
  207. case FINSH_NODE_SYS_AND:
  208. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_AND_BYTE);
  209. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_AND_WORD);
  210. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_AND_DWORD);
  211. break;
  212. case FINSH_NODE_SYS_OR:
  213. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_OR_BYTE);
  214. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_OR_WORD);
  215. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_OR_DWORD);
  216. break;
  217. case FINSH_NODE_SYS_XOR:
  218. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_XOR_BYTE);
  219. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_XOR_WORD);
  220. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_XOR_DWORD);
  221. break;
  222. case FINSH_NODE_SYS_BITWISE:
  223. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_BITWISE_BYTE);
  224. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_BITWISE_WORD);
  225. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_BITWISE_DWORD);
  226. break;
  227. case FINSH_NODE_SYS_SHL:
  228. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHL_BYTE);
  229. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHL_WORD);
  230. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHL_DWORD);
  231. break;
  232. case FINSH_NODE_SYS_SHR:
  233. if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHR_BYTE);
  234. else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHR_WORD);
  235. else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHR_DWORD);
  236. break;
  237. /* syscall */
  238. case FINSH_NODE_SYS_FUNC:
  239. {
  240. int parameters;
  241. struct finsh_node* sibling;
  242. parameters = 0;
  243. sibling = finsh_node_sibling(finsh_node_child(node));
  244. while (sibling != NULL)
  245. {
  246. parameters ++;
  247. sibling = finsh_node_sibling(sibling);
  248. }
  249. /* load address of function */
  250. // finsh_code_dword((long)&(node->var->value.ptr));
  251. /* syscall parameters */
  252. finsh_code_byte(FINSH_OP_SYSCALL);
  253. finsh_code_byte(parameters);
  254. }
  255. break;
  256. /* assign expression */
  257. case FINSH_NODE_SYS_ASSIGN:
  258. if (finsh_node_child(node)->node_type == FINSH_NODE_ID)
  259. {
  260. switch (finsh_node_child(node)->data_type)
  261. {
  262. case FINSH_DATA_TYPE_BYTE:
  263. finsh_code_byte(FINSH_OP_ST_BYTE);
  264. /* load value again */
  265. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
  266. break;
  267. case FINSH_DATA_TYPE_WORD:
  268. finsh_code_byte(FINSH_OP_ST_WORD);
  269. /* load value again */
  270. finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
  271. break;
  272. case FINSH_DATA_TYPE_DWORD:
  273. finsh_code_byte(FINSH_OP_ST_DWORD);
  274. /* load value again */
  275. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  276. break;
  277. default:
  278. finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
  279. }
  280. }
  281. else if (finsh_node_child(node)->node_type == FINSH_NODE_SYS_GETVALUE)
  282. {
  283. switch ((finsh_node_child(node)->data_type) & 0x0F)
  284. {
  285. case FINSH_DATA_TYPE_BYTE:
  286. finsh_code_byte(FINSH_OP_ST_BYTE);
  287. /* load value again */
  288. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
  289. break;
  290. case FINSH_DATA_TYPE_WORD:
  291. finsh_code_byte(FINSH_OP_ST_WORD);
  292. /* load value again */
  293. finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
  294. break;
  295. case FINSH_DATA_TYPE_DWORD:
  296. finsh_code_byte(FINSH_OP_ST_DWORD);
  297. /* load value again */
  298. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  299. break;
  300. default:
  301. finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
  302. }
  303. }
  304. break;
  305. /* pre-increase */
  306. case FINSH_NODE_SYS_PREINC:
  307. if (finsh_node_child(node)->node_type == FINSH_NODE_ID)
  308. {
  309. struct finsh_var* var;
  310. var = finsh_node_child(node)->id.var;
  311. /* ld_dword &id */
  312. // finsh_code_byte(FINSH_OP_LD_DWORD);
  313. switch (node->data_type)
  314. {
  315. case FINSH_DATA_TYPE_BYTE:
  316. /* address */
  317. // finsh_code_dword((long)&(var->value.char_value));
  318. /* ld_value_byte &id */
  319. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  320. finsh_code_dword((long)&(var->value.char_value));
  321. /* ld_byte 1 */
  322. finsh_code_byte(FINSH_OP_LD_BYTE);
  323. finsh_code_byte(1);
  324. /* add_byte */
  325. finsh_code_byte(FINSH_OP_ADD_BYTE);
  326. /* st_byte */
  327. finsh_code_byte(FINSH_OP_ST_BYTE);
  328. /* load value again */
  329. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  330. break;
  331. case FINSH_DATA_TYPE_WORD:
  332. /* address */
  333. // finsh_code_dword((long)&(var->value.short_value));
  334. /* ld_value_word &id */
  335. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  336. finsh_code_dword((long)&(var->value.short_value));
  337. /* ld_word 1 */
  338. finsh_code_byte(FINSH_OP_LD_WORD);
  339. finsh_code_word(1);
  340. /* add_word */
  341. finsh_code_byte(FINSH_OP_ADD_WORD);
  342. /* st_word */
  343. finsh_code_byte(FINSH_OP_ST_WORD);
  344. /* load value again */
  345. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  346. break;
  347. case FINSH_DATA_TYPE_DWORD:
  348. /* address */
  349. // finsh_code_dword((long)&(var->value.long_value));
  350. /* ld_dword &id */
  351. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  352. finsh_code_dword((long)&(var->value.long_value));
  353. /* ld_dword 1 */
  354. finsh_code_byte(FINSH_OP_LD_DWORD);
  355. finsh_code_dword(1);
  356. /* add_dword */
  357. finsh_code_byte(FINSH_OP_ADD_DWORD);
  358. /* st_dword */
  359. finsh_code_byte(FINSH_OP_ST_DWORD);
  360. /* load value again */
  361. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  362. break;
  363. }
  364. }
  365. break;
  366. /* pre-decrease */
  367. case FINSH_NODE_SYS_PREDEC:
  368. if (finsh_node_child(node)->node_type == FINSH_NODE_ID)
  369. {
  370. struct finsh_var* var;
  371. var = finsh_node_child(node)->id.var;
  372. /* ld_dword &id */
  373. // finsh_code_byte(FINSH_OP_LD_DWORD);
  374. switch (node->data_type)
  375. {
  376. case FINSH_DATA_TYPE_BYTE:
  377. /* address */
  378. // finsh_code_dword((long)&(var->value.char_value));
  379. /* ld_value_byte &id */
  380. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  381. finsh_code_dword((long)&(var->value.char_value));
  382. /* ld_byte 1 */
  383. finsh_code_byte(FINSH_OP_LD_BYTE);
  384. finsh_code_byte(1);
  385. /* add_byte */
  386. finsh_code_byte(FINSH_OP_SUB_BYTE);
  387. /* st_byte */
  388. finsh_code_byte(FINSH_OP_ST_BYTE);
  389. /* load value again */
  390. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  391. break;
  392. case FINSH_DATA_TYPE_WORD:
  393. /* address */
  394. // finsh_code_dword((long)&(var->value.short_value));
  395. /* ld_value_word &id */
  396. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  397. finsh_code_dword((long)&(var->value.short_value));
  398. /* ld_word 1 */
  399. finsh_code_byte(FINSH_OP_LD_WORD);
  400. finsh_code_word(1);
  401. /* add_word */
  402. finsh_code_byte(FINSH_OP_SUB_WORD);
  403. /* st_word */
  404. finsh_code_byte(FINSH_OP_ST_WORD);
  405. /* load value again */
  406. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  407. break;
  408. case FINSH_DATA_TYPE_DWORD:
  409. /* address */
  410. // finsh_code_dword((long)&(var->value.long_value));
  411. /* ld_dword &id */
  412. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  413. finsh_code_dword((long)&(var->value.long_value));
  414. /* ld_dword 1 */
  415. finsh_code_byte(FINSH_OP_LD_DWORD);
  416. finsh_code_dword(1);
  417. /* add_dword */
  418. finsh_code_byte(FINSH_OP_SUB_DWORD);
  419. /* st_dword */
  420. finsh_code_byte(FINSH_OP_ST_DWORD);
  421. /* load value again */
  422. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  423. break;
  424. }
  425. }
  426. break;
  427. /* increase */
  428. case FINSH_NODE_SYS_INC:
  429. if (finsh_node_child(node)->node_type == FINSH_NODE_ID)
  430. {
  431. struct finsh_var* var;
  432. var = finsh_node_child(node)->id.var;
  433. switch (node->data_type)
  434. {
  435. case FINSH_DATA_TYPE_BYTE:
  436. /* ld_value_byte &id */
  437. // finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  438. // finsh_code_dword((long)&(var->value.char_value));
  439. /* ld_dword &id */
  440. finsh_code_byte(FINSH_OP_LD_DWORD);
  441. finsh_code_dword((long)&(var->value.char_value));
  442. /* ld_value_byte &id */
  443. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  444. finsh_code_dword((long)&(var->value.char_value));
  445. /* ld_byte 1 */
  446. finsh_code_byte(FINSH_OP_LD_BYTE);
  447. finsh_code_byte(1);
  448. /* add_byte */
  449. finsh_code_byte(FINSH_OP_ADD_BYTE);
  450. /* get byte */
  451. finsh_code_byte(FINSH_OP_ST_BYTE);
  452. /* pop */
  453. finsh_code_byte(FINSH_OP_POP);
  454. break;
  455. case FINSH_DATA_TYPE_WORD:
  456. /* ld_value_word &id */
  457. // finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  458. // finsh_code_dword((long)&(var->value.short_value));
  459. /* ld_dword &id */
  460. finsh_code_byte(FINSH_OP_LD_DWORD);
  461. finsh_code_dword((long)&(var->value.short_value));
  462. /* ld_value_word &id */
  463. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  464. finsh_code_dword((long)&(var->value.short_value));
  465. /* ld_word 1 */
  466. finsh_code_byte(FINSH_OP_LD_WORD);
  467. finsh_code_word(1);
  468. /* add_byte */
  469. finsh_code_byte(FINSH_OP_ADD_WORD);
  470. /* get byte */
  471. finsh_code_byte(FINSH_OP_ST_WORD);
  472. /* pop */
  473. finsh_code_byte(FINSH_OP_POP);
  474. break;
  475. case FINSH_DATA_TYPE_DWORD:
  476. /* ld_value_dword &id */
  477. // finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  478. // finsh_code_dword((long)&(var->value.long_value));
  479. /* ld_dword &id */
  480. finsh_code_byte(FINSH_OP_LD_DWORD);
  481. finsh_code_dword((long)&(var->value.long_value));
  482. /* ld_value_dword &id */
  483. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  484. finsh_code_dword((long)&(var->value.long_value));
  485. /* ld_dword 1 */
  486. finsh_code_byte(FINSH_OP_LD_DWORD);
  487. finsh_code_dword(1);
  488. /* add_byte */
  489. finsh_code_byte(FINSH_OP_ADD_DWORD);
  490. /* get byte */
  491. finsh_code_byte(FINSH_OP_ST_DWORD);
  492. /* pop */
  493. finsh_code_byte(FINSH_OP_POP);
  494. break;
  495. }
  496. }
  497. break;
  498. /* decrease */
  499. case FINSH_NODE_SYS_DEC:
  500. if (finsh_node_child(node)->node_type == FINSH_NODE_ID)
  501. {
  502. struct finsh_var* var;
  503. var = finsh_node_child(node)->id.var;
  504. switch (node->data_type)
  505. {
  506. case FINSH_DATA_TYPE_BYTE:
  507. /* ld_value_byte &id */
  508. // finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  509. // finsh_code_dword((long)&(var->value.char_value));
  510. /* ld_dword &id */
  511. finsh_code_byte(FINSH_OP_LD_DWORD);
  512. finsh_code_dword((long)&(var->value.char_value));
  513. /* ld_value_byte &id */
  514. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
  515. finsh_code_dword((long)&(var->value.char_value));
  516. /* ld_byte 1 */
  517. finsh_code_byte(FINSH_OP_LD_BYTE);
  518. finsh_code_byte(1);
  519. /* add_byte */
  520. finsh_code_byte(FINSH_OP_SUB_BYTE);
  521. /* get byte */
  522. finsh_code_byte(FINSH_OP_ST_BYTE);
  523. /* pop */
  524. finsh_code_byte(FINSH_OP_POP);
  525. break;
  526. case FINSH_DATA_TYPE_WORD:
  527. /* ld_value_word &id */
  528. // finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  529. // finsh_code_dword((long)&(var->value.short_value));
  530. /* ld_dword &id */
  531. finsh_code_byte(FINSH_OP_LD_DWORD);
  532. finsh_code_dword((long)&(var->value.short_value));
  533. /* ld_value_word &id */
  534. finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
  535. finsh_code_dword((long)&(var->value.short_value));
  536. /* ld_word 1 */
  537. finsh_code_byte(FINSH_OP_LD_WORD);
  538. finsh_code_word(1);
  539. /* add_byte */
  540. finsh_code_byte(FINSH_OP_SUB_WORD);
  541. /* get byte */
  542. finsh_code_byte(FINSH_OP_ST_WORD);
  543. /* pop */
  544. finsh_code_byte(FINSH_OP_POP);
  545. break;
  546. case FINSH_DATA_TYPE_DWORD:
  547. /* ld_value_dword &id */
  548. // finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  549. // finsh_code_dword((long)&(var->value.long_value));
  550. /* ld_dword &id */
  551. finsh_code_byte(FINSH_OP_LD_DWORD);
  552. finsh_code_dword((long)&(var->value.long_value));
  553. /* ld_value_dword &id */
  554. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
  555. finsh_code_dword((long)&(var->value.long_value));
  556. /* ld_dword 1 */
  557. finsh_code_byte(FINSH_OP_LD_DWORD);
  558. finsh_code_dword(1);
  559. /* add_byte */
  560. finsh_code_byte(FINSH_OP_SUB_DWORD);
  561. /* get byte */
  562. finsh_code_byte(FINSH_OP_ST_DWORD);
  563. /* pop */
  564. finsh_code_byte(FINSH_OP_POP);
  565. break;
  566. }
  567. }
  568. break;
  569. case FINSH_NODE_SYS_NULL:
  570. finsh_code_dword(0);
  571. break;
  572. case FINSH_NODE_SYS_GETVALUE:
  573. if (node->idtype & FINSH_IDTYPE_ADDRESS)
  574. {
  575. /* nothing will be generated */
  576. }
  577. else
  578. {
  579. switch (node->data_type)
  580. {
  581. case FINSH_DATA_TYPE_BYTE:
  582. finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
  583. break;
  584. case FINSH_DATA_TYPE_WORD:
  585. finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
  586. break;
  587. case FINSH_DATA_TYPE_DWORD:
  588. finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
  589. break;
  590. default:
  591. break;
  592. }
  593. }
  594. break;
  595. case FINSH_NODE_SYS_GETADDR:
  596. /* nothing will be generated */
  597. break;
  598. default:
  599. finsh_error_set(FINSH_ERROR_UNKNOWN_NODE);
  600. break;
  601. }
  602. /* compile sibling node */
  603. if (finsh_node_sibling(node) != NULL)
  604. finsh_compile(finsh_node_sibling(node));
  605. }
  606. return 0;
  607. }
  608. static int finsh_type_check(struct finsh_node* node, u_char is_addr)
  609. {
  610. if (node != NULL)
  611. {
  612. /* address & value */
  613. if (node->node_type == FINSH_NODE_SYS_ASSIGN ||
  614. node->node_type == FINSH_NODE_SYS_PREINC ||
  615. node->node_type == FINSH_NODE_SYS_PREDEC ||
  616. node->node_type == FINSH_NODE_SYS_GETADDR)
  617. {
  618. /* address */
  619. finsh_type_check(finsh_node_child(node), FINSH_IDTYPE_ADDRESS);
  620. }
  621. else if (node->node_type == FINSH_NODE_SYS_GETVALUE && is_addr)
  622. {
  623. /* change the attribute of getvalue in left expr */
  624. finsh_type_check(finsh_node_child(node), 0);
  625. }
  626. else
  627. {
  628. /* transfer 'av' to child node */
  629. finsh_type_check(finsh_node_child(node), is_addr);
  630. }
  631. /* always does not load address in sibling */
  632. finsh_type_check(finsh_node_sibling(node), FINSH_NODE_VALUE);
  633. /** set attribute of current node */
  634. /* make sure the current node is address or value */
  635. if (node->idtype != FINSH_IDTYPE_SYSCALL) node->idtype |= is_addr;
  636. if (finsh_node_child(node) != NULL)
  637. {
  638. node->data_type = finsh_node_child(node)->data_type;
  639. return 0;
  640. }
  641. if (node->node_type == FINSH_NODE_ID)
  642. {
  643. if (node->idtype & FINSH_IDTYPE_VAR)
  644. {
  645. struct finsh_var* var;
  646. var = node->id.var;
  647. if (var != NULL)
  648. {
  649. switch (var->type)
  650. {
  651. case finsh_type_void:
  652. node->data_type = FINSH_DATA_TYPE_VOID;
  653. break;
  654. case finsh_type_char:
  655. case finsh_type_uchar:
  656. node->data_type = FINSH_DATA_TYPE_BYTE;
  657. break;
  658. case finsh_type_short:
  659. case finsh_type_ushort:
  660. node->data_type = FINSH_DATA_TYPE_WORD;
  661. break;
  662. case finsh_type_int:
  663. case finsh_type_uint:
  664. case finsh_type_long:
  665. case finsh_type_ulong:
  666. node->data_type = FINSH_DATA_TYPE_DWORD;
  667. break;
  668. case finsh_type_charp:
  669. case finsh_type_voidp:
  670. case finsh_type_shortp:
  671. case finsh_type_intp:
  672. case finsh_type_longp:
  673. node->data_type = FINSH_DATA_TYPE_DWORD;
  674. break;
  675. default:
  676. finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
  677. break;
  678. }
  679. }
  680. }
  681. else if (node->idtype & FINSH_IDTYPE_SYSVAR)
  682. {
  683. struct finsh_sysvar *sysvar;
  684. sysvar = node->id.sysvar;
  685. if (sysvar != NULL)
  686. {
  687. switch (sysvar->type)
  688. {
  689. case finsh_type_void:
  690. node->data_type = FINSH_DATA_TYPE_VOID;
  691. break;
  692. case finsh_type_char:
  693. case finsh_type_uchar:
  694. node->data_type = FINSH_DATA_TYPE_BYTE;
  695. break;
  696. case finsh_type_short:
  697. case finsh_type_ushort:
  698. node->data_type = FINSH_DATA_TYPE_WORD;
  699. break;
  700. case finsh_type_int:
  701. case finsh_type_uint:
  702. case finsh_type_long:
  703. case finsh_type_ulong:
  704. node->data_type = FINSH_DATA_TYPE_DWORD;
  705. break;
  706. case finsh_type_charp:
  707. case finsh_type_voidp:
  708. case finsh_type_shortp:
  709. case finsh_type_intp:
  710. case finsh_type_longp:
  711. node->data_type = FINSH_DATA_TYPE_DWORD;
  712. break;
  713. default:
  714. finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
  715. break;
  716. }
  717. }
  718. }
  719. }
  720. else if (node->node_type == FINSH_NODE_VALUE_CHAR)
  721. {
  722. node->data_type = FINSH_DATA_TYPE_BYTE;
  723. }
  724. else if (node->node_type == FINSH_NODE_VALUE_INT ||
  725. node->node_type == FINSH_NODE_VALUE_LONG ||
  726. node->node_type == FINSH_NODE_VALUE_STRING ||
  727. node->node_type == FINSH_NODE_VALUE_NULL)
  728. {
  729. node->data_type = FINSH_DATA_TYPE_DWORD;
  730. }
  731. }
  732. return 0;
  733. }
  734. int finsh_compiler_run(struct finsh_node* node)
  735. {
  736. struct finsh_node* sibling;
  737. /* type check */
  738. finsh_type_check(node, FINSH_NODE_VALUE);
  739. /* clean text segment and vm stack */
  740. memset(&text_segment[0], 0, sizeof(text_segment));
  741. memset(&finsh_vm_stack[0], 0, sizeof(finsh_vm_stack[0]));
  742. /* reset compile stack pointer and pc */
  743. finsh_compile_sp = &finsh_vm_stack[0];
  744. finsh_compile_pc = &text_segment[0];
  745. /* compile node */
  746. sibling = node;
  747. while (sibling != NULL)
  748. {
  749. struct finsh_node* current_node;
  750. current_node = sibling;
  751. /* get sibling node */
  752. sibling = current_node->sibling;
  753. /* clean sibling node */
  754. current_node->sibling = NULL;
  755. finsh_compile(current_node);
  756. /* pop current value */
  757. if (sibling != NULL) finsh_code_byte(FINSH_OP_POP);
  758. }
  759. return 0;
  760. }