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

📄 slang_compile.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
				return 0;
			}
			if (!slang_struct_construct_a (spec->_struct))
			{
				slang_alloc_free (spec->_struct);
				spec->_struct = NULL;
				slang_alloc_free (name);
				slang_info_log_memory (C->L);
				return 0;
			}
			spec->_struct->name = name;
			spec->_struct->structs->outer_scope = structs;
		}
		do
		{
			slang_type_specifier sp;
			slang_type_specifier_construct (&sp);
			if (!parse_type_specifier (C, &sp, spec->_struct->structs, scope, funcs))
			{
				slang_type_specifier_destruct (&sp);
				return 0;
			}
			do
			{
				slang_variable *var;
				spec->_struct->fields->variables = (slang_variable *) slang_alloc_realloc (
					spec->_struct->fields->variables,
					spec->_struct->fields->num_variables * sizeof (slang_variable),
					(spec->_struct->fields->num_variables + 1) * sizeof (slang_variable));
				if (spec->_struct->fields->variables == NULL)
				{
					slang_type_specifier_destruct (&sp);
					slang_info_log_memory (C->L);
					return 0;
				}
				var = spec->_struct->fields->variables + spec->_struct->fields->num_variables;
				spec->_struct->fields->num_variables++;
				slang_variable_construct (var);
				if (!slang_type_specifier_copy (&var->type.specifier, &sp))
				{
					slang_type_specifier_destruct (&sp);
					return 0;
				}
				if (!parse_identifier (C, &var->name))
				{
					slang_type_specifier_destruct (&sp);
					return 0;
				}
				switch (*C->I++)
				{
				case FIELD_NONE:
					break;
				case FIELD_ARRAY:
					var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (
						slang_operation));
					if (var->array_size == NULL)
					{
						slang_type_specifier_destruct (&sp);
						slang_info_log_memory (C->L);
						return 0;
					}
					if (!slang_operation_construct_a (var->array_size))
					{
						slang_alloc_free (var->array_size);
						var->array_size = NULL;
						slang_type_specifier_destruct (&sp);
						slang_info_log_memory (C->L);
						return 0;
					}
					if (!parse_expression (C, var->array_size, scope, structs, funcs))
					{
						slang_type_specifier_destruct (&sp);
						return 0;
					}
					break;
				default:
					return 0;
				}
			}
			while (*C->I++ != FIELD_NONE);
		}
		while (*C->I++ != FIELD_NONE);
		if (*spec->_struct->name != '\0')
		{
			slang_struct *s;
			structs->structs = (slang_struct *) slang_alloc_realloc (structs->structs,
				structs->num_structs * sizeof (slang_struct),
				(structs->num_structs + 1) * sizeof (slang_struct));
			if (structs->structs == NULL)
			{
				slang_info_log_memory (C->L);
				return 0;
			}
			s = structs->structs + structs->num_structs;
			if (!slang_struct_construct_a (s))
				return 0;
			structs->num_structs++;
			if (!slang_struct_copy (s, spec->_struct))
				return 0;
		}
		break;
	case TYPE_SPECIFIER_TYPENAME:
		spec->type = slang_spec_struct;
		{
			char *name;
			slang_struct *stru;
			if (!parse_identifier (C, &name))
				return 0;
			stru = slang_struct_scope_find (structs, name, 1);
			if (stru == NULL)
			{
				slang_info_log_error (C->L, "%s: undeclared type name", name);
				slang_alloc_free (name);
				return 0;
			}
			slang_alloc_free (name);
			spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
			if (spec->_struct == NULL)
			{
				slang_info_log_memory (C->L);
				return 0;
			}
			if (!slang_struct_construct_a (spec->_struct))
			{
				slang_alloc_free (spec->_struct);
				spec->_struct = NULL;
				return 0;
			}
			if (!slang_struct_copy (spec->_struct, stru))
				return 0;
		}
		break;
	default:
		return 0;
	}
	return 1;
}

static int parse_fully_specified_type (slang_parse_ctx *C, slang_fully_specified_type *type,
	slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
	if (!parse_type_qualifier (C, &type->qualifier))
		return 0;
	return parse_type_specifier (C, &type->specifier, structs, scope, funcs);
}

/* operation */
#define OP_END 0
#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
#define OP_BLOCK_BEGIN_NEW_SCOPE 2
#define OP_DECLARE 3
#define OP_ASM 4
#define OP_BREAK 5
#define OP_CONTINUE 6
#define OP_DISCARD 7
#define OP_RETURN 8
#define OP_EXPRESSION 9
#define OP_IF 10
#define OP_WHILE 11
#define OP_DO 12
#define OP_FOR 13
#define OP_PUSH_VOID 14
#define OP_PUSH_BOOL 15
#define OP_PUSH_INT 16
#define OP_PUSH_FLOAT 17
#define OP_PUSH_IDENTIFIER 18
#define OP_SEQUENCE 19
#define OP_ASSIGN 20
#define OP_ADDASSIGN 21
#define OP_SUBASSIGN 22
#define OP_MULASSIGN 23
#define OP_DIVASSIGN 24
/*#define OP_MODASSIGN 25*/
/*#define OP_LSHASSIGN 26*/
/*#define OP_RSHASSIGN 27*/
/*#define OP_ORASSIGN 28*/
/*#define OP_XORASSIGN 29*/
/*#define OP_ANDASSIGN 30*/
#define OP_SELECT 31
#define OP_LOGICALOR 32
#define OP_LOGICALXOR 33
#define OP_LOGICALAND 34
/*#define OP_BITOR 35*/
/*#define OP_BITXOR 36*/
/*#define OP_BITAND 37*/
#define OP_EQUAL 38
#define OP_NOTEQUAL 39
#define OP_LESS 40
#define OP_GREATER 41
#define OP_LESSEQUAL 42
#define OP_GREATEREQUAL 43
/*#define OP_LSHIFT 44*/
/*#define OP_RSHIFT 45*/
#define OP_ADD 46
#define OP_SUBTRACT 47
#define OP_MULTIPLY 48
#define OP_DIVIDE 49
/*#define OP_MODULUS 50*/
#define OP_PREINCREMENT 51
#define OP_PREDECREMENT 52
#define OP_PLUS 53
#define OP_MINUS 54
/*#define OP_COMPLEMENT 55*/
#define OP_NOT 56
#define OP_SUBSCRIPT 57
#define OP_CALL 58
#define OP_FIELD 59
#define OP_POSTINCREMENT 60
#define OP_POSTDECREMENT 61

static int parse_child_operation (slang_parse_ctx *C, slang_operation *oper, int statement,
	slang_variable_scope *scope, slang_struct_scope *structs, slang_function_scope *funcs)
{
	oper->children = (slang_operation *) slang_alloc_realloc (oper->children,
		oper->num_children * sizeof (slang_operation),
		(oper->num_children + 1) * sizeof (slang_operation));
	if (oper->children == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	if (!slang_operation_construct_a (oper->children + oper->num_children))
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	oper->num_children++;
	if (statement)
		return parse_statement (C, oper->children + oper->num_children - 1, scope, structs, funcs);
	return parse_expression (C, oper->children + oper->num_children - 1, scope, structs, funcs);
}

static int parse_declaration (slang_parse_ctx *C, slang_variable_scope *, slang_struct_scope *,
	slang_function_scope *);

static int parse_statement (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope,
	slang_struct_scope *structs, slang_function_scope *funcs)
{
	oper->locals->outer_scope = scope;
	switch (*C->I++)
	{
	case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
		oper->type = slang_oper_block_no_new_scope;
		while (*C->I != OP_END)
			if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
				return 0;
		C->I++;
		break;
	case OP_BLOCK_BEGIN_NEW_SCOPE:
		oper->type = slang_oper_block_new_scope;
		while (*C->I != OP_END)
			if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
				return 0;
		C->I++;
		break;
	case OP_DECLARE:
		oper->type = slang_oper_variable_decl;
		{
			const unsigned int first_var = scope->num_variables;
			if (!parse_declaration (C, scope, structs, funcs))
				return 0;
			if (first_var < scope->num_variables)
			{
				const unsigned int num_vars = scope->num_variables - first_var;
				unsigned int i;
				oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof (
					slang_operation));
				if (oper->children == NULL)
				{
					slang_info_log_memory (C->L);
					return 0;
				}
				for (i = 0; i < num_vars; i++)
					if (!slang_operation_construct_a (oper->children + i))
					{
						unsigned int j;
						for (j = 0; j < i; j++)
							slang_operation_destruct (oper->children + j);
						slang_alloc_free (oper->children);
						oper->children = NULL;
						slang_info_log_memory (C->L);
						return 0;
					}
				oper->num_children = num_vars;
				for (i = first_var; i < scope->num_variables; i++)
				{
					slang_operation *o = oper->children + i - first_var;
					o->type = slang_oper_identifier;
					o->locals->outer_scope = scope;
					o->identifier = slang_string_duplicate (scope->variables[i].name);
					if (o->identifier == NULL)
					{
						slang_info_log_memory (C->L);
						return 0;
					}
				}
			}
		}
		break;
	case OP_ASM:
		oper->type = slang_oper_asm;
		if (!parse_identifier (C, &oper->identifier))
			return 0;
		while (*C->I != OP_END)
			if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
				return 0;
		C->I++;
		break;
	case OP_BREAK:
		oper->type = slang_oper_break;
		break;
	case OP_CONTINUE:
		oper->type = slang_oper_continue;
		break;
	case OP_DISCARD:
		oper->type = slang_oper_discard;
		break;
	case OP_RETURN:
		oper->type = slang_oper_return;
		if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
			return 0;
		break;
	case OP_EXPRESSION:
		oper->type = slang_oper_expression;
		if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
			return 0;
		break;
	case OP_IF:
		oper->type = slang_oper_if;
		if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
			return 0;
		break;
	case OP_WHILE:
		oper->type = slang_oper_while;
		if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
			return 0;
		break;
	case OP_DO:
		oper->type = slang_oper_do;
		if (!parse_child_operation (C, oper, 1, scope, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 0, scope, structs, funcs))
			return 0;
		break;
	case OP_FOR:
		oper->type = slang_oper_for;
		if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 0, oper->locals, structs, funcs))
			return 0;
		if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs))
			return 0;
		break;
	default:
		return 0;
	}
	return 1;
}

static int handle_trinary_expression (slang_parse_ctx *C, slang_operation *op,
	slang_operation **ops, unsigned int *num_ops)
{
	op->num_children = 3;
	op->children = (slang_operation *) slang_alloc_malloc (3 * sizeof (slang_operation));
	if (op->children == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	op->children[0] = (*ops)[*num_ops - 4];
	op->children[1] = (*ops)[*num_ops - 3];
	op->children[2] = (*ops)[*num_ops - 2];
	(*ops)[*num_ops - 4] = (*ops)[*num_ops - 1];
	*num_ops -= 3;
	*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 3) * sizeof (slang_operation),
		*num_ops * sizeof (slang_operation));
	if (*ops == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	return 1;
}

static int handle_binary_expression (slang_parse_ctx *C, slang_operation *op,
	slang_operation **ops, unsigned int *num_ops)
{
	op->num_children = 2;
	op->children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
	if (op->children == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	op->children[0] = (*ops)[*num_ops - 3];
	op->children[1] = (*ops)[*num_ops - 2];
	(*ops)[*num_ops - 3] = (*ops)[*num_ops - 1];
	*num_ops -= 2;
	*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 2) * sizeof (slang_operation),
		*num_ops * sizeof (slang_operation));
	if (*ops == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	return 1;
}

static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op,
	slang_operation **ops, unsigned int *num_ops)
{
	op->num_children = 1;
	op->children = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
	if (op->children == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	op->children[0] = (*ops)[*num_ops - 2];
	(*ops)[*num_ops - 2] = (*ops)[*num_ops - 1];
	(*num_ops)--;
	*ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 1) * sizeof (slang_operation),
		*num_ops * sizeof (slang_operation));
	if (*ops == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	return 1;
}

static int is_constructor_name (const char *name, slang_struct_scope *structs)
{
	if (slang_type_specifier_type_from_string (name) != slang_spec_void)
		return 1;
	return slang_struct_scope_find (structs, name, 1) != NULL;
}

static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope,
	slang_struct_scope *structs, slang_function_scope *funcs)
{
	slang_operation *ops = NULL;
	unsigned int num_ops = 0;
	int number;

	while (*C->I != OP_END)
	{
		slang_operation *op;
		const unsigned int op_code = *C->I++;
		ops = (slang_operation *) slang_alloc_realloc (ops,
			num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation));
		if (ops == NULL)
		{
			slang_info_log_memory (C->L);
			return 0;
		}
		op = ops + num_ops;
		if (!slang_operation_construct_a (op))
		{
			slang_info_log_memory (C->L);
			return 0;
		}

⌨️ 快捷键说明

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