123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937 |
- /*
- * RT-Thread finsh shell compiler
- *
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
- *
- * This file is part of RT-Thread (http://www.rt-thread.org)
- * Maintainer: bernard.xiong <bernard.xiong at gmail.com>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date Author Notes
- * 2010-03-22 Bernard first version
- */
- #include <finsh.h>
- #include "finsh_node.h"
- #include "finsh_error.h"
- #include "finsh_var.h"
- #include "finsh_ops.h"
- union finsh_value* finsh_compile_sp; /* stack pointer */
- u_char* finsh_compile_pc; /* PC */
- #define finsh_code_byte(x) do { *finsh_compile_pc = (x); finsh_compile_pc ++; } while(0)
- #define finsh_code_word(x) do { FINSH_SET16(finsh_compile_pc, x); finsh_compile_pc +=2; } while(0)
- #define finsh_code_dword(x) do { FINSH_SET32(finsh_compile_pc, x); finsh_compile_pc +=4; } while(0)
- static int finsh_compile(struct finsh_node* node)
- {
- if (node != NULL)
- {
- /* compile child node */
- if (finsh_node_child(node) != NULL)
- finsh_compile(finsh_node_child(node));
- /* compile current node */
- switch (node->node_type)
- {
- case FINSH_NODE_ID:
- {
- /* identifier::syscall */
- if (node->idtype & FINSH_IDTYPE_SYSCALL)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)node->id.syscall->func);
- }
- /* identifier::sysvar */
- else if (node->idtype & FINSH_IDTYPE_SYSVAR)
- {
- struct finsh_sysvar* sysvar;
- sysvar = node->id.sysvar;
- if (sysvar != NULL)
- {
- switch (sysvar->type)
- {
- case finsh_type_char:
- case finsh_type_uchar:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- }
- finsh_code_dword((long)(sysvar->var));
- break;
- case finsh_type_short:
- case finsh_type_ushort:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- }
- finsh_code_dword((long)(sysvar->var));
- break;
- case finsh_type_int:
- case finsh_type_uint:
- case finsh_type_long:
- case finsh_type_ulong:
- case finsh_type_charp:
- case finsh_type_shortp:
- case finsh_type_intp:
- case finsh_type_longp:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- }
- finsh_code_dword((long)(sysvar->var));
- break;
- }
- }
- }
- /* identifier::var */
- else
- {
- struct finsh_var* var;
- var = node->id.var;
- if (var != NULL)
- {
- switch (var->type)
- {
- case finsh_type_char:
- case finsh_type_uchar:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- }
- finsh_code_dword((long)&(var->value.char_value));
- break;
- case finsh_type_short:
- case finsh_type_ushort:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- }
- finsh_code_dword((long)&(var->value.short_value));
- break;
- case finsh_type_int:
- case finsh_type_uint:
- case finsh_type_long:
- case finsh_type_ulong:
- case finsh_type_charp:
- case finsh_type_shortp:
- case finsh_type_intp:
- case finsh_type_longp:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* load address */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- }
- else
- {
- /* load value */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- }
- finsh_code_dword((long)&(var->value.long_value));
- break;
- }
- }
- }
- }
- break;
- /* load const */
- case FINSH_NODE_VALUE_CHAR:
- finsh_code_byte(FINSH_OP_LD_BYTE);
- finsh_code_byte(node->value.char_value);
- break;
- case FINSH_NODE_VALUE_INT:
- case FINSH_NODE_VALUE_LONG:
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword(node->value.long_value);
- break;
- case FINSH_NODE_VALUE_NULL:
- case FINSH_NODE_VALUE_STRING:
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((u_long)node->value.ptr);
- break;
- /* arithmetic operation */
- case FINSH_NODE_SYS_ADD:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_ADD_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_ADD_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_ADD_DWORD);
- break;
- case FINSH_NODE_SYS_SUB:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SUB_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SUB_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SUB_DWORD);
- break;
- case FINSH_NODE_SYS_MUL:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MUL_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MUL_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MUL_DWORD);
- break;
- case FINSH_NODE_SYS_DIV:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_DIV_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_DIV_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_DIV_DWORD);
- break;
- case FINSH_NODE_SYS_MOD:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MOD_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MOD_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MOD_DWORD);
- break;
- /* bit operation */
- case FINSH_NODE_SYS_AND:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_AND_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_AND_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_AND_DWORD);
- break;
- case FINSH_NODE_SYS_OR:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_OR_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_OR_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_OR_DWORD);
- break;
- case FINSH_NODE_SYS_XOR:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_XOR_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_XOR_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_XOR_DWORD);
- break;
- case FINSH_NODE_SYS_BITWISE:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_BITWISE_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_BITWISE_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_BITWISE_DWORD);
- break;
- case FINSH_NODE_SYS_SHL:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHL_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHL_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHL_DWORD);
- break;
- case FINSH_NODE_SYS_SHR:
- if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHR_BYTE);
- else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHR_WORD);
- else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHR_DWORD);
- break;
- /* syscall */
- case FINSH_NODE_SYS_FUNC:
- {
- int parameters;
- struct finsh_node* sibling;
- parameters = 0;
- if (finsh_node_child(node) != NULL)
- {
- sibling = finsh_node_sibling(finsh_node_child(node));
- while (sibling != NULL)
- {
- parameters ++;
- sibling = finsh_node_sibling(sibling);
- }
- /* load address of function */
- // finsh_code_dword((long)&(node->var->value.ptr));
- /* syscall parameters */
- finsh_code_byte(FINSH_OP_SYSCALL);
- finsh_code_byte(parameters);
- }
- }
- break;
- /* assign expression */
- case FINSH_NODE_SYS_ASSIGN:
- if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
- {
- switch (finsh_node_child(node)->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
- break;
- case FINSH_DATA_TYPE_WORD:
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
- break;
- case FINSH_DATA_TYPE_DWORD:
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- default:
- finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
- }
- }
- else if (finsh_node_child(node)->node_type == FINSH_NODE_SYS_GETVALUE)
- {
- switch ((finsh_node_child(node)->data_type) & 0x0F)
- {
- case FINSH_DATA_TYPE_BYTE:
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
- break;
- case FINSH_DATA_TYPE_WORD:
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
- break;
- case FINSH_DATA_TYPE_DWORD:
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- default:
- finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
- }
- }
- break;
- /* pre-increase */
- case FINSH_NODE_SYS_PREINC:
- if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
- {
- struct finsh_var* var;
- var = finsh_node_child(node)->id.var;
- /* ld_dword &id */
- // finsh_code_byte(FINSH_OP_LD_DWORD);
- switch (node->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- /* address */
- // finsh_code_dword((long)&(var->value.char_value));
- /* ld_value_byte &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_byte 1 */
- finsh_code_byte(FINSH_OP_LD_BYTE);
- finsh_code_byte(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_ADD_BYTE);
- /* st_byte */
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- case FINSH_DATA_TYPE_WORD:
- /* address */
- // finsh_code_dword((long)&(var->value.short_value));
- /* ld_value_word &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_word 1 */
- finsh_code_byte(FINSH_OP_LD_WORD);
- finsh_code_word(1);
- /* add_word */
- finsh_code_byte(FINSH_OP_ADD_WORD);
- /* st_word */
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- case FINSH_DATA_TYPE_DWORD:
- /* address */
- // finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword 1 */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword(1);
- /* add_dword */
- finsh_code_byte(FINSH_OP_ADD_DWORD);
- /* st_dword */
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- }
- }
- break;
- /* pre-decrease */
- case FINSH_NODE_SYS_PREDEC:
- if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
- {
- struct finsh_var* var;
- var = finsh_node_child(node)->id.var;
- /* ld_dword &id */
- // finsh_code_byte(FINSH_OP_LD_DWORD);
- switch (node->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- /* address */
- // finsh_code_dword((long)&(var->value.char_value));
- /* ld_value_byte &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_byte 1 */
- finsh_code_byte(FINSH_OP_LD_BYTE);
- finsh_code_byte(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_SUB_BYTE);
- /* st_byte */
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- case FINSH_DATA_TYPE_WORD:
- /* address */
- // finsh_code_dword((long)&(var->value.short_value));
- /* ld_value_word &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_word 1 */
- finsh_code_byte(FINSH_OP_LD_WORD);
- finsh_code_word(1);
- /* add_word */
- finsh_code_byte(FINSH_OP_SUB_WORD);
- /* st_word */
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- case FINSH_DATA_TYPE_DWORD:
- /* address */
- // finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword 1 */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword(1);
- /* add_dword */
- finsh_code_byte(FINSH_OP_SUB_DWORD);
- /* st_dword */
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* load value again */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- }
- }
- break;
- /* increase */
- case FINSH_NODE_SYS_INC:
- if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
- {
- struct finsh_var* var;
- var = finsh_node_child(node)->id.var;
- switch (node->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- /* ld_value_byte &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- // finsh_code_dword((long)&(var->value.char_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_value_byte &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_byte 1 */
- finsh_code_byte(FINSH_OP_LD_BYTE);
- finsh_code_byte(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_ADD_BYTE);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- case FINSH_DATA_TYPE_WORD:
- /* ld_value_word &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- // finsh_code_dword((long)&(var->value.short_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_value_word &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_word 1 */
- finsh_code_byte(FINSH_OP_LD_WORD);
- finsh_code_word(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_ADD_WORD);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- case FINSH_DATA_TYPE_DWORD:
- /* ld_value_dword &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- // finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_value_dword &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword 1 */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_ADD_DWORD);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- }
- }
- break;
- /* decrease */
- case FINSH_NODE_SYS_DEC:
- if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
- {
- struct finsh_var* var;
- var = finsh_node_child(node)->id.var;
- switch (node->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- /* ld_value_byte &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- // finsh_code_dword((long)&(var->value.char_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_value_byte &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
- finsh_code_dword((long)&(var->value.char_value));
- /* ld_byte 1 */
- finsh_code_byte(FINSH_OP_LD_BYTE);
- finsh_code_byte(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_SUB_BYTE);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_BYTE);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- case FINSH_DATA_TYPE_WORD:
- /* ld_value_word &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- // finsh_code_dword((long)&(var->value.short_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_value_word &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
- finsh_code_dword((long)&(var->value.short_value));
- /* ld_word 1 */
- finsh_code_byte(FINSH_OP_LD_WORD);
- finsh_code_word(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_SUB_WORD);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_WORD);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- case FINSH_DATA_TYPE_DWORD:
- /* ld_value_dword &id */
- // finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- // finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword &id */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_value_dword &id */
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
- finsh_code_dword((long)&(var->value.long_value));
- /* ld_dword 1 */
- finsh_code_byte(FINSH_OP_LD_DWORD);
- finsh_code_dword(1);
- /* add_byte */
- finsh_code_byte(FINSH_OP_SUB_DWORD);
- /* get byte */
- finsh_code_byte(FINSH_OP_ST_DWORD);
- /* pop */
- finsh_code_byte(FINSH_OP_POP);
- break;
- }
- }
- break;
- case FINSH_NODE_SYS_NULL:
- finsh_code_dword(0);
- break;
- case FINSH_NODE_SYS_GETVALUE:
- if (node->idtype & FINSH_IDTYPE_ADDRESS)
- {
- /* nothing will be generated */
- }
- else
- {
- switch (node->data_type)
- {
- case FINSH_DATA_TYPE_BYTE:
- finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
- break;
- case FINSH_DATA_TYPE_WORD:
- finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
- break;
- case FINSH_DATA_TYPE_DWORD:
- finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
- break;
- default:
- break;
- }
- }
- break;
- case FINSH_NODE_SYS_GETADDR:
- /* nothing will be generated */
- break;
- default:
- finsh_error_set(FINSH_ERROR_UNKNOWN_NODE);
- break;
- }
- /* compile sibling node */
- if (finsh_node_sibling(node) != NULL)
- finsh_compile(finsh_node_sibling(node));
- }
- return 0;
- }
- static int finsh_type_check(struct finsh_node* node, u_char is_addr)
- {
- if (node != NULL)
- {
- /* address & value */
- if (node->node_type == FINSH_NODE_SYS_ASSIGN ||
- node->node_type == FINSH_NODE_SYS_PREINC ||
- node->node_type == FINSH_NODE_SYS_PREDEC ||
- node->node_type == FINSH_NODE_SYS_GETADDR)
- {
- /* address */
- finsh_type_check(finsh_node_child(node), FINSH_IDTYPE_ADDRESS);
- }
- else if (node->node_type == FINSH_NODE_SYS_GETVALUE && is_addr)
- {
- /* change the attribute of getvalue in left expr */
- finsh_type_check(finsh_node_child(node), 0);
- }
- else
- {
- /* transfer 'av' to child node */
- finsh_type_check(finsh_node_child(node), is_addr);
- }
- /* always does not load address in sibling */
- finsh_type_check(finsh_node_sibling(node), FINSH_NODE_VALUE);
- /** set attribute of current node */
- /* make sure the current node is address or value */
- if (node->idtype != FINSH_IDTYPE_SYSCALL) node->idtype |= is_addr;
- if (finsh_node_child(node) != NULL)
- {
- node->data_type = finsh_node_child(node)->data_type;
- return 0;
- }
- if (node->node_type == FINSH_NODE_ID)
- {
- if (node->idtype & FINSH_IDTYPE_VAR)
- {
- struct finsh_var* var;
- var = node->id.var;
- if (var != NULL)
- {
- switch (var->type)
- {
- case finsh_type_void:
- node->data_type = FINSH_DATA_TYPE_VOID;
- break;
- case finsh_type_char:
- case finsh_type_uchar:
- node->data_type = FINSH_DATA_TYPE_BYTE;
- break;
- case finsh_type_short:
- case finsh_type_ushort:
- node->data_type = FINSH_DATA_TYPE_WORD;
- break;
- case finsh_type_int:
- case finsh_type_uint:
- case finsh_type_long:
- case finsh_type_ulong:
- node->data_type = FINSH_DATA_TYPE_DWORD;
- break;
- case finsh_type_charp:
- case finsh_type_voidp:
- case finsh_type_shortp:
- case finsh_type_intp:
- case finsh_type_longp:
- node->data_type = FINSH_DATA_TYPE_DWORD;
- break;
- default:
- finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
- break;
- }
- }
- }
- else if (node->idtype & FINSH_IDTYPE_SYSVAR)
- {
- struct finsh_sysvar *sysvar;
- sysvar = node->id.sysvar;
- if (sysvar != NULL)
- {
- switch (sysvar->type)
- {
- case finsh_type_void:
- node->data_type = FINSH_DATA_TYPE_VOID;
- break;
- case finsh_type_char:
- case finsh_type_uchar:
- node->data_type = FINSH_DATA_TYPE_BYTE;
- break;
- case finsh_type_short:
- case finsh_type_ushort:
- node->data_type = FINSH_DATA_TYPE_WORD;
- break;
- case finsh_type_int:
- case finsh_type_uint:
- case finsh_type_long:
- case finsh_type_ulong:
- node->data_type = FINSH_DATA_TYPE_DWORD;
- break;
- case finsh_type_charp:
- case finsh_type_voidp:
- case finsh_type_shortp:
- case finsh_type_intp:
- case finsh_type_longp:
- node->data_type = FINSH_DATA_TYPE_DWORD;
- break;
- default:
- finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
- break;
- }
- }
- }
- }
- else if (node->node_type == FINSH_NODE_VALUE_CHAR)
- {
- node->data_type = FINSH_DATA_TYPE_BYTE;
- }
- else if (node->node_type == FINSH_NODE_VALUE_INT ||
- node->node_type == FINSH_NODE_VALUE_LONG ||
- node->node_type == FINSH_NODE_VALUE_STRING ||
- node->node_type == FINSH_NODE_VALUE_NULL)
- {
- node->data_type = FINSH_DATA_TYPE_DWORD;
- }
- }
- return 0;
- }
- int finsh_compiler_run(struct finsh_node* node)
- {
- struct finsh_node* sibling;
- /* type check */
- finsh_type_check(node, FINSH_NODE_VALUE);
- /* clean text segment and vm stack */
- memset(&text_segment[0], 0, sizeof(text_segment));
- memset(&finsh_vm_stack[0], 0, sizeof(finsh_vm_stack[0]));
- /* reset compile stack pointer and pc */
- finsh_compile_sp = &finsh_vm_stack[0];
- finsh_compile_pc = &text_segment[0];
- /* compile node */
- sibling = node;
- while (sibling != NULL)
- {
- struct finsh_node* current_node;
- current_node = sibling;
- /* get sibling node */
- sibling = current_node->sibling;
- /* clean sibling node */
- current_node->sibling = NULL;
- finsh_compile(current_node);
- /* pop current value */
- if (sibling != NULL) finsh_code_byte(FINSH_OP_POP);
- }
- return 0;
- }
|