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

📄 slang_compile.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
		num_ops++;
		op->locals->outer_scope = scope;
		switch (op_code)
		{
		case OP_PUSH_VOID:
			op->type = slang_oper_void;
			break;
		case OP_PUSH_BOOL:
			op->type = slang_oper_literal_bool;
			if (!parse_number (C, &number))
				return 0;
			op->literal = (float) number;
			break;
		case OP_PUSH_INT:
			op->type = slang_oper_literal_int;
			if (!parse_number (C, &number))
				return 0;
			op->literal = (float) number;
			break;
		case OP_PUSH_FLOAT:
			op->type = slang_oper_literal_float;
			if (!parse_float (C, &op->literal))
				return 0;
			break;
		case OP_PUSH_IDENTIFIER:
			op->type = slang_oper_identifier;
			if (!parse_identifier (C, &op->identifier))
				return 0;
			break;
		case OP_SEQUENCE:
			op->type = slang_oper_sequence;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_ASSIGN:
			op->type = slang_oper_assign;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_ADDASSIGN:
			op->type = slang_oper_addassign;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_SUBASSIGN:
			op->type = slang_oper_subassign;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_MULASSIGN:
			op->type = slang_oper_mulassign;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_DIVASSIGN:
			op->type = slang_oper_divassign;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		/*case OP_MODASSIGN:*/
		/*case OP_LSHASSIGN:*/
		/*case OP_RSHASSIGN:*/
		/*case OP_ORASSIGN:*/
		/*case OP_XORASSIGN:*/
		/*case OP_ANDASSIGN:*/
		case OP_SELECT:
			op->type = slang_oper_select;
			if (!handle_trinary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_LOGICALOR:
			op->type = slang_oper_logicalor;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_LOGICALXOR:
			op->type = slang_oper_logicalxor;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_LOGICALAND:
			op->type = slang_oper_logicaland;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		/*case OP_BITOR:*/
		/*case OP_BITXOR:*/
		/*case OP_BITAND:*/
		case OP_EQUAL:
			op->type = slang_oper_equal;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_NOTEQUAL:
			op->type = slang_oper_notequal;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_LESS:
			op->type = slang_oper_less;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_GREATER:
			op->type = slang_oper_greater;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_LESSEQUAL:
			op->type = slang_oper_lessequal;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_GREATEREQUAL:
			op->type = slang_oper_greaterequal;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		/*case OP_LSHIFT:*/
		/*case OP_RSHIFT:*/
		case OP_ADD:
			op->type = slang_oper_add;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_SUBTRACT:
			op->type = slang_oper_subtract;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_MULTIPLY:
			op->type = slang_oper_multiply;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_DIVIDE:
			op->type = slang_oper_divide;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		/*case OP_MODULUS:*/
		case OP_PREINCREMENT:
			op->type = slang_oper_preincrement;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_PREDECREMENT:
			op->type = slang_oper_predecrement;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_PLUS:
			op->type = slang_oper_plus;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_MINUS:
			op->type = slang_oper_minus;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_NOT:
			op->type = slang_oper_not;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		/*case OP_COMPLEMENT:*/
		case OP_SUBSCRIPT:
			op->type = slang_oper_subscript;
			if (!handle_binary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_CALL:
			op->type = slang_oper_call;
			if (!parse_identifier (C, &op->identifier))
				return 0;
			while (*C->I != OP_END)
				if (!parse_child_operation (C, op, 0, scope, structs, funcs))
					return 0;
			C->I++;
			if (!C->parsing_builtin &&
				!slang_function_scope_find_by_name (funcs, op->identifier, 1) &&
				!is_constructor_name (op->identifier, structs))
			{
				slang_info_log_error (C->L, "%s: undeclared function name", op->identifier);
				return 0;
			}
			break;
		case OP_FIELD:
			op->type = slang_oper_field;
			if (!parse_identifier (C, &op->identifier))
				return 0;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_POSTINCREMENT:
			op->type = slang_oper_postincrement;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		case OP_POSTDECREMENT:
			op->type = slang_oper_postdecrement;
			if (!handle_unary_expression (C, op, &ops, &num_ops))
				return 0;
			break;
		default:
			return 0;
		}
	}
	C->I++;
	*oper = *ops;
	slang_alloc_free (ops);
	return 1;
}

/* parameter qualifier */
#define PARAM_QUALIFIER_IN 0
#define PARAM_QUALIFIER_OUT 1
#define PARAM_QUALIFIER_INOUT 2

/* function parameter array presence */
#define PARAMETER_ARRAY_NOT_PRESENT 0
#define PARAMETER_ARRAY_PRESENT 1

static int parse_parameter_declaration (slang_parse_ctx *C, slang_variable *param,
	slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
	slang_storage_aggregate agg;
	if (!parse_type_qualifier (C, &param->type.qualifier))
		return 0;
	switch (*C->I++)
	{
	case PARAM_QUALIFIER_IN:
		if (param->type.qualifier != slang_qual_const && param->type.qualifier != slang_qual_none)
		{
			slang_info_log_error (C->L, "invalid type qualifier");
			return 0;
		}
		break;
	case PARAM_QUALIFIER_OUT:
		if (param->type.qualifier == slang_qual_none)
			param->type.qualifier = slang_qual_out;
		else
		{
			slang_info_log_error (C->L, "invalid type qualifier");
			return 0;
		}
		break;
	case PARAM_QUALIFIER_INOUT:
		if (param->type.qualifier == slang_qual_none)
			param->type.qualifier = slang_qual_inout;
		else
		{
			slang_info_log_error (C->L, "invalid type qualifier");
			return 0;
		}
		break;
	default:
		return 0;
	}
	if (!parse_type_specifier (C, &param->type.specifier, structs, scope, funcs))
		return 0;
	if (!parse_identifier (C, &param->name))
		return 0;
	if (*C->I++ == PARAMETER_ARRAY_PRESENT)
	{
		param->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
		if (param->array_size == NULL)
		{
			slang_info_log_memory (C->L);
			return 0;
		}
		if (!slang_operation_construct_a (param->array_size))
		{
			slang_alloc_free (param->array_size);
			param->array_size = NULL;
			slang_info_log_memory (C->L);
			return 0;
		}
		if (!parse_expression (C, param->array_size, scope, structs, funcs))
			return 0;
	}
	slang_storage_aggregate_construct (&agg);
	if (!_slang_aggregate_variable (&agg, &param->type.specifier, param->array_size, funcs,
		structs))
	{
		slang_storage_aggregate_destruct (&agg);
		return 0;
	}
	slang_storage_aggregate_destruct (&agg);
	return 1;
}

/* function type */
#define FUNCTION_ORDINARY 0
#define FUNCTION_CONSTRUCTOR 1
#define FUNCTION_OPERATOR 2

/* function parameter */
#define PARAMETER_NONE 0
#define PARAMETER_NEXT 1

/* operator type */
#define OPERATOR_ASSIGN 1
#define OPERATOR_ADDASSIGN 2
#define OPERATOR_SUBASSIGN 3
#define OPERATOR_MULASSIGN 4
#define OPERATOR_DIVASSIGN 5
/*#define OPERATOR_MODASSIGN 6*/
/*#define OPERATOR_LSHASSIGN 7*/
/*#define OPERATOR_RSHASSIGN 8*/
/*#define OPERATOR_ANDASSIGN 9*/
/*#define OPERATOR_XORASSIGN 10*/
/*#define OPERATOR_ORASSIGN 11*/
#define OPERATOR_LOGICALXOR 12
/*#define OPERATOR_BITOR 13*/
/*#define OPERATOR_BITXOR 14*/
/*#define OPERATOR_BITAND 15*/
#define OPERATOR_EQUAL 16
#define OPERATOR_NOTEQUAL 17
#define OPERATOR_LESS 18
#define OPERATOR_GREATER 19
#define OPERATOR_LESSEQUAL 20
#define OPERATOR_GREATEREQUAL 21
/*#define OPERATOR_LSHIFT 22*/
/*#define OPERATOR_RSHIFT 23*/
#define OPERATOR_MULTIPLY 24
#define OPERATOR_DIVIDE 25
/*#define OPERATOR_MODULUS 26*/
#define OPERATOR_INCREMENT 27
#define OPERATOR_DECREMENT 28
#define OPERATOR_PLUS 29
#define OPERATOR_MINUS 30
/*#define OPERATOR_COMPLEMENT 31*/
#define OPERATOR_NOT 32

static const struct {
	unsigned int o_code;
	const char *o_name;
} operator_names[] = {
	{ OPERATOR_INCREMENT, "++" },
	{ OPERATOR_ADDASSIGN, "+=" },
	{ OPERATOR_PLUS, "+" },
	{ OPERATOR_DECREMENT, "--" },
	{ OPERATOR_SUBASSIGN, "-=" },
	{ OPERATOR_MINUS, "-" },
	{ OPERATOR_NOTEQUAL, "!=" },
	{ OPERATOR_NOT, "!" },
	{ OPERATOR_MULASSIGN, "*=" },
	{ OPERATOR_MULTIPLY, "*" },
	{ OPERATOR_DIVASSIGN, "/=" },
	{ OPERATOR_DIVIDE, "/" },
	{ OPERATOR_LESSEQUAL, "<=" },
	/*{ OPERATOR_LSHASSIGN, "<<=" },*/
	/*{ OPERATOR_LSHIFT, "<<" },*/
	{ OPERATOR_LESS, "<" },
	{ OPERATOR_GREATEREQUAL, ">=" },
	/*{ OPERATOR_RSHASSIGN, ">>=" },*/
	/*{ OPERATOR_RSHIFT, ">>" },*/
	{ OPERATOR_GREATER, ">" },
	{ OPERATOR_EQUAL, "==" },
	{ OPERATOR_ASSIGN, "=" },
	/*{ OPERATOR_MODASSIGN, "%=" },*/
	/*{ OPERATOR_MODULUS, "%" },*/
	/*{ OPERATOR_ANDASSIGN, "&=" },*/
	/*{ OPERATOR_BITAND, "&" },*/
	/*{ OPERATOR_ORASSIGN, "|=" },*/
	/*{ OPERATOR_BITOR, "|" },*/
	/*{ OPERATOR_COMPLEMENT, "~" },*/
	/*{ OPERATOR_XORASSIGN, "^=" },*/
	{ OPERATOR_LOGICALXOR, "^^" }/*,*/
	/*{ OPERATOR_BITXOR, "^" }*/
};

static int parse_operator_name (slang_parse_ctx *C, char **pname)
{
	unsigned int i;
	for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
		if (operator_names[i].o_code == (unsigned int) (*C->I))
		{
			*pname = slang_string_duplicate (operator_names[i].o_name);
			if (*pname == NULL)
			{
				slang_info_log_memory (C->L);
				return 0;
			}
			C->I++;
			return 1;
		}
	return 0;
}

static int parse_function_prototype (slang_parse_ctx *C, slang_function *func,
	slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
	if (!parse_fully_specified_type (C, &func->header.type, structs, scope, funcs))
		return 0;
	switch (*C->I++)
	{
	case FUNCTION_ORDINARY:
		func->kind = slang_func_ordinary;
		if (!parse_identifier (C, &func->header.name))
			return 0;
		break;
	case FUNCTION_CONSTRUCTOR:
		func->kind = slang_func_constructor;
		if (func->header.type.specifier.type == slang_spec_struct)
			return 0;
		func->header.name = slang_string_duplicate (
			type_specifier_type_names[func->header.type.specifier.type]);
		if (func->header.name == NULL)
		{
			slang_info_log_memory (C->L);
			return 0;
		}
		break;
	case FUNCTION_OPERATOR:
		func->kind = slang_func_operator;
		if (!parse_operator_name (C, &func->header.name))
			return 0;
		break;
	default:
		return 0;
	}
	func->parameters->outer_scope = scope;
	while (*C->I++ == PARAMETER_NEXT)
	{
		func->parameters->variables = (slang_variable *) slang_alloc_realloc (
			func->parameters->variables,
			func->parameters->num_variables * sizeof (slang_variable),
			(func->parameters->num_variables + 1) * sizeof (slang_variable));
		if (func->parameters->variables == NULL)
		{
			slang_info_log_memory (C->L);
			return 0;
		}
		slang_variable_construct (func->parameters->variables + func->parameters->num_variables);
		func->parameters->num_variables++;
		if (!parse_parameter_declaration (C, func->parameters->variables +
			func->parameters->num_variables - 1, structs, scope, funcs))
			return 0;
	}
	func->param_count = func->parameters->num_variables;
	return 1;
}

static int parse_function_definition (slang_parse_ctx *C, slang_function *func,
	slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs)
{
	if (!parse_function_prototype (C, func, structs, scope, funcs))
		return 0;
	func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
	if (func->body == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	if (!slang_operation_construct_a (func->body))
	{
		slang_alloc_free (func->body);
		func->body = NULL;
		slang_info_log_memory (C->L);
		return 0;
	}
	if (!parse_statement (C, func->body, func->parameters, structs, funcs))
		return 0;
	return 1;
}

/* init declarator list */

⌨️ 快捷键说明

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