⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finsh_compiler.c

📁 中国人自己的c语言
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <finsh/finsh.h>

#include "finsh_compiler.h"
#include "finsh_error.h"
#include "finsh_type.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 { *(short*)finsh_compile_pc = (x); finsh_compile_pc +=2; } while(0)
#define finsh_code_dword(x) do { *(long*) 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->type)
		{
		case FINSH_NODE_ID:
			{
				if (node->avf == FINSH_NODE_FUNCTION)
				{
					/* load address */
					finsh_code_byte(FINSH_OP_LD_DWORD);
					finsh_code_dword((long)node->func->func);
				}
				else
				{
					struct finsh_var* var;

					var = node->var;
					if (var != NULL)
					{
						switch (var->type)
						{
						case finsh_type_char:
						case finsh_type_uchar:
							if (node->avf == FINSH_NODE_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->char_value));
							break;

						case finsh_type_short:
						case finsh_type_ushort:
							if (node->avf == FINSH_NODE_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->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->avf == FINSH_NODE_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->long_value));
							break;
						}
					}
				}
			}
			break;

		/* load const */
		case FINSH_NODE_VALUE_CHAR:
			finsh_code_byte(FINSH_OP_LD_BYTE);
			finsh_code_byte(node->char_value);
			break;

		case FINSH_NODE_VALUE_INT:
		case FINSH_NODE_VALUE_LONG:
			finsh_code_byte(FINSH_OP_LD_DWORD);
			finsh_code_dword(node->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->ptr);
			break;

		case FINSH_NODE_SYS_ADD:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_ADD_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_ADD_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_ADD_DWORD);
			break;

		case FINSH_NODE_SYS_SUB:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_SUB_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_SUB_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_NODE_TYPE_DWORD);
			break;

		case FINSH_NODE_SYS_MUL:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_MUL_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_MUL_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_NODE_TYPE_DWORD);
			break;

		case FINSH_NODE_SYS_DIV:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_DIV_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_DIV_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_DIV_DWORD);
			break;

		case FINSH_NODE_SYS_MOD:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_MOD_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_MOD_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_MOD_DWORD);
			break;

		case FINSH_NODE_SYS_AND:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_AND_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_AND_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_AND_DWORD);
			break;

		case FINSH_NODE_SYS_OR:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_OR_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_OR_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_OR_DWORD);
			break;

		case FINSH_NODE_SYS_XOR:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_XOR_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_XOR_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_XOR_DWORD);
			break;

		case FINSH_NODE_SYS_BITWISE:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_BITWISE_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_BITWISE_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_BITWISE_DWORD);
			break;

		case FINSH_NODE_SYS_SHL:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHL_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_SHL_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(FINSH_OP_SHL_DWORD);
			break;

		case FINSH_NODE_SYS_SHR:
			if (node->dtype == FINSH_NODE_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHR_BYTE);
			else if (node->dtype == FINSH_NODE_TYPE_WORD) finsh_code_word(FINSH_OP_SHR_WORD);
			else if (node->dtype == FINSH_NODE_TYPE_DWORD) finsh_code_dword(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->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)->type == FINSH_NODE_ID)
			{
				switch (finsh_node_child(node)->dtype)
				{
				case FINSH_NODE_TYPE_BYTE:
					finsh_code_byte(FINSH_OP_ST_BYTE);

					/* load value again */
					finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
					finsh_code_dword((long)&(finsh_node_child(node)->var->char_value));
					break;

				case FINSH_NODE_TYPE_WORD:
					finsh_code_word(FINSH_OP_ST_WORD);

					/* load value again */
					finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
					finsh_code_dword((long)&(finsh_node_child(node)->var->short_value));
					break;

				case FINSH_NODE_TYPE_DWORD:
					finsh_code_dword(FINSH_OP_ST_DWORD);

					/* load value again */
					finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
					finsh_code_dword((long)&(finsh_node_child(node)->var->long_value));
					break;

				default:
					finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
				}

			}
			break;

		case FINSH_NODE_SYS_CAST:
			/* not support now */
			break;

		case FINSH_NODE_SYS_PREINC:
			if (finsh_node_child(node)->type == FINSH_NODE_ID)
			{
				struct finsh_var* var;
				var = finsh_node_child(node)->var;

				/* ld_dword &id */
				// finsh_code_byte(FINSH_OP_LD_DWORD);

				switch (node->dtype)
				{
				case FINSH_NODE_TYPE_BYTE:
					/* address */
					// finsh_code_dword((long)&(var->char_value));

					/* ld_value_byte &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
					finsh_code_dword((long)&(var->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);

					/* ld_value_byte &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
					finsh_code_dword((long)&(var->char_value));
					break;

				case FINSH_NODE_TYPE_WORD:
					/* address */
					// finsh_code_dword((long)&(var->short_value));

					/* ld_value_word &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
					finsh_code_dword((long)&(var->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);

					/* ld_value_word &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
					finsh_code_dword((long)&(var->short_value));

					break;

				case FINSH_NODE_TYPE_DWORD:
					/* address */
					// finsh_code_dword((long)&(var->long_value));

					/* ld_dword &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
					finsh_code_dword((long)&(var->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);

					/* ld_dword &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
					finsh_code_dword((long)&(var->long_value));

					break;
				}
			}
			break;
			break;

		case FINSH_NODE_SYS_PREDEC:
			if (finsh_node_child(node)->type == FINSH_NODE_ID)
			{
				struct finsh_var* var;
				var = finsh_node_child(node)->var;

				/* ld_dword &id */
				// finsh_code_byte(FINSH_OP_LD_DWORD);

				switch (node->dtype)
				{
				case FINSH_NODE_TYPE_BYTE:
					/* address */
					// finsh_code_dword((long)&(var->char_value));

					/* ld_value_byte &id */
					finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
					finsh_code_dword((long)&(var->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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -