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