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