示例#1
0
/*
make a new node as following tree:
new_node
|
node1__
       \
       node2
*/
static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1, struct finsh_node* node2)
{
	struct finsh_node* node;

	node = finsh_node_allocate(type);

	if ((node1 != NULL) && (node != NULL))
	{
		finsh_node_child(node) = node1;
		finsh_node_sibling(node1) = node2;
	}
	else finsh_error_set(FINSH_ERROR_NULL_NODE);

	return node;
}
示例#2
0
/*
param_list -> empty
	| expr_assign
	| param_list ',' expr_assign
*/
static struct finsh_node* proc_param_list(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node *node, *assign;

	assign = proc_assign_expr(self);
	if (assign == NULL) return NULL;
	node = assign;

	next_token(token, &(self->token));
	while (token == finsh_token_type_comma )
	{
		finsh_node_sibling(assign) = proc_assign_expr(self);

		if (finsh_node_sibling(assign) != NULL)	assign = finsh_node_sibling(assign);
		else finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);

		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));

	return node;
}
示例#3
0
/*
process for function and variable declaration.
decl_variable -> type declaration_list ';'
declarator_list -> declarator_list ',' declarator
	| declarator
declarator -> identifier
	| identifier ASSIGN expr_assign
*/
static struct finsh_node* proc_variable_decl(struct finsh_parser* self)
{
	enum finsh_token_type token;
	enum finsh_type type;
	char id[FINSH_NAME_MAX + 1];

	struct finsh_node *node;
	struct finsh_node *end;
	struct finsh_node *assign;

    node = NULL;
	end  = NULL;

	/* get type */
	type = proc_type(self);

	/*process id.*/
	if (proc_identifier(self, id) == 0)
	{
		/* if add variable failed */
		if (finsh_var_insert(id, type) < 0)
		{
			finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
		}
	}

	next_token(token, &(self->token));
	switch ( token )
	{
	case finsh_token_type_comma:/*',', it's a variable_list declaration.*/
		if (proc_identifier(self, id) == 0)
		{
			/* if add variable failed */
			if (finsh_var_insert(id, type) < 0)
			{
				finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
			}
		}

		next_token(token, &(self->token));
		if ( token == finsh_token_type_assign )
		{
			/* get the right side of assign expression */
			assign = proc_assign_expr(self);

			if (assign != NULL)
			{
				struct finsh_node* idnode;

				idnode = finsh_node_new_id(id);
				end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
				node = end;

				next_token(token, &(self->token));
			}
		}

		while ( token == finsh_token_type_comma )
		{
			if (proc_identifier(self, id) == 0)
			{
				/* if add variable failed */
				if (finsh_var_insert(id, type) < 0)
				{
					finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
				}
			}

			next_token(token, &(self->token));
			if ( token == finsh_token_type_assign )
			{
				/* get the right side of assign expression */
				assign = proc_assign_expr(self);

				if (assign != NULL)
				{
					struct finsh_node* idnode;

					idnode = finsh_node_new_id(id);

					/* make assign expression node */
					if (node != NULL)
					{
						finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
						end = finsh_node_sibling(end);
					}
					else
					{
						end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
						node = end;
					}

					next_token(token, &(self->token));
				}
			}
		}

		check_token(token, &(self->token), finsh_token_type_semicolon);
		return node;

	case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/
	{
		struct finsh_node *idnode;

		assign = proc_assign_expr(self);
		if (assign != NULL)
		{
			idnode = finsh_node_new_id(id);

			/* make assign expression node */
			end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
			node = end;

			next_token(token, &(self->token));
		}

		while ( token == finsh_token_type_comma )
		{
			if (proc_identifier(self, id) == 0)
			{
				/* if add variable failed */
				if (finsh_var_insert(id, type) < 0)
				{
					finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
				}
			}

			next_token(token, &(self->token));
			if (token == finsh_token_type_assign)
			{
				/* get the right side of assign expression */
				assign = proc_assign_expr(self);

				if (assign != NULL)
				{
					idnode = finsh_node_new_id(id);

					/* make assign expression node */
					if (node != NULL)
					{
						finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
						end = finsh_node_sibling(end);
					}
					else
					{
						end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
						node = end;
					}

					next_token(token, &(self->token));
				}
			}
		}

		check_token(token, &(self->token), finsh_token_type_semicolon);
		return node;
	}

	case finsh_token_type_semicolon:/*';', it's a variable declaration.*/
		return node;

	default:
		finsh_error_set(FINSH_ERROR_EXPECT_TYPE);

		return NULL;
	}
}
示例#4
0
/*
start -> statement_expr | decl_variable
*/
void finsh_parser_run(struct finsh_parser* self, const u_char* string)
{
	enum finsh_token_type token;
	struct finsh_node *node;

    node = NULL;

	/* init parser */
	self->parser_string = (u_char*)string;

	/* init token */
	finsh_token_init(&(self->token), self->parser_string);

	/* get next token */
	next_token(token, &(self->token));
	while (token != finsh_token_type_eof && token != finsh_token_type_bad)
	{
		switch (token)
		{
        case finsh_token_type_identifier:
            /* process expr_statement */
            finsh_token_replay(&(self->token));

			if (self->root != NULL)
			{
				finsh_node_sibling(node) = proc_expr_statement(self);
				if (finsh_node_sibling(node) != NULL)
					node = finsh_node_sibling(node);
			}
			else
			{
            	node = proc_expr_statement(self);
				self->root = node;
			}
            break;

		default:
            if (is_base_type(token) || token == finsh_token_type_unsigned)
            {
            	/* variable decl */
            	finsh_token_replay(&(self->token));

				if (self->root != NULL)
				{
					finsh_node_sibling(node) = proc_variable_decl(self);
					if (finsh_node_sibling(node) != NULL)
						node = finsh_node_sibling(node);
				}
				else
				{
					node = proc_variable_decl(self);
					self->root = node;
				}
            }
            else
            {
            	/* process expr_statement */
                finsh_token_replay(&(self->token));

				if (self->root != NULL)
				{
                    finsh_node_sibling(node) = proc_expr_statement(self);
					if (finsh_node_sibling(node) != NULL)
						node = finsh_node_sibling(node);
					else next_token(token, &(self->token));
				}
				else
				{
					node = proc_expr_statement(self);
					self->root = node;
				}
            }

			break;
		}
        /* get next token */
		next_token(token, &(self->token));
	}
}
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;
}
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;
}