📄 finsh_compiler.c.svn-base
字号:
#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; 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)->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)->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)->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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -