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

📄 slang_compile.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				return 0;			break;		case OP_SUBASSIGN:			op->type = slang_oper_subassign;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_MULASSIGN:			op->type = slang_oper_mulassign;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_DIVASSIGN:			op->type = slang_oper_divassign;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				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_nary_expression (C, op, &ops, &num_ops, 3))				return 0;			break;		case OP_LOGICALOR:			op->type = slang_oper_logicalor;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_LOGICALXOR:			op->type = slang_oper_logicalxor;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_LOGICALAND:			op->type = slang_oper_logicaland;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		/*case OP_BITOR:*/		/*case OP_BITXOR:*/		/*case OP_BITAND:*/		case OP_EQUAL:			op->type = slang_oper_equal;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_NOTEQUAL:			op->type = slang_oper_notequal;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_LESS:			op->type = slang_oper_less;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_GREATER:			op->type = slang_oper_greater;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_LESSEQUAL:			op->type = slang_oper_lessequal;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_GREATEREQUAL:			op->type = slang_oper_greaterequal;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		/*case OP_LSHIFT:*/		/*case OP_RSHIFT:*/		case OP_ADD:			op->type = slang_oper_add;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_SUBTRACT:			op->type = slang_oper_subtract;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_MULTIPLY:			op->type = slang_oper_multiply;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_DIVIDE:			op->type = slang_oper_divide;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		/*case OP_MODULUS:*/		case OP_PREINCREMENT:			op->type = slang_oper_preincrement;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_PREDECREMENT:			op->type = slang_oper_predecrement;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_PLUS:			op->type = slang_oper_plus;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_MINUS:			op->type = slang_oper_minus;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_NOT:			op->type = slang_oper_not;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		/*case OP_COMPLEMENT:*/		case OP_SUBSCRIPT:			op->type = slang_oper_subscript;			if (!handle_nary_expression (C, op, &ops, &num_ops, 2))				return 0;			break;		case OP_CALL:			op->type = slang_oper_call;			op->a_id = parse_identifier (C);			if (op->a_id == SLANG_ATOM_NULL)				return 0;			while (*C->I != OP_END)				if (!parse_child_operation (C, O, op, 0))					return 0;			C->I++;			if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))			{				const char *id;				id = slang_atom_pool_id (C->atoms, op->a_id);				if (!is_constructor_name (id, op->a_id, O->structs))				{					slang_info_log_error (C->L, "%s: undeclared function name", id);					return 0;				}			}			break;		case OP_FIELD:			op->type = slang_oper_field;			op->a_id = parse_identifier (C);			if (op->a_id == SLANG_ATOM_NULL)				return 0;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_POSTINCREMENT:			op->type = slang_oper_postincrement;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				return 0;			break;		case OP_POSTDECREMENT:			op->type = slang_oper_postdecrement;			if (!handle_nary_expression (C, op, &ops, &num_ops, 1))				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 1static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,	slang_variable *param){	/* parse and validate the parameter's type qualifiers (there can be two at most) because	 * not all combinations are valid */	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;	}	/* parse parameter's type specifier and name */	if (!parse_type_specifier (C, O, &param->type.specifier))		return 0;	param->a_name = parse_identifier (C);	if (param->a_name == SLANG_ATOM_NULL)		return 0;	/* if the parameter is an array, parse its size (the size must be explicitly defined */	if (*C->I++ == PARAMETER_ARRAY_PRESENT)	{		slang_type_specifier p;		slang_type_specifier_ctr (&p);		if (!slang_type_specifier_copy (&p, &param->type.specifier))		{			slang_type_specifier_dtr (&p);			return GL_FALSE;		}		if (!convert_to_array (C, param, &p))		{			slang_type_specifier_dtr (&p);			return GL_FALSE;		}		slang_type_specifier_dtr (&p);		if (!parse_array_len (C, O, &param->array_len))			return GL_FALSE;	}	/* calculate the parameter size */	if (!calculate_var_size (C, O, param))		return GL_FALSE;	/* TODO: allocate the local address here? */	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_ADDASSIGN 1#define OPERATOR_SUBASSIGN 2#define OPERATOR_MULASSIGN 3#define OPERATOR_DIVASSIGN 4/*#define OPERATOR_MODASSIGN 5*//*#define OPERATOR_LSHASSIGN 6*//*#define OPERATOR_RSHASSIGN 7*//*#define OPERATOR_ANDASSIGN 8*//*#define OPERATOR_XORASSIGN 9*//*#define OPERATOR_ORASSIGN 10*/#define OPERATOR_LOGICALXOR 11/*#define OPERATOR_BITOR 12*//*#define OPERATOR_BITXOR 13*//*#define OPERATOR_BITAND 14*/#define OPERATOR_LESS 15#define OPERATOR_GREATER 16#define OPERATOR_LESSEQUAL 17#define OPERATOR_GREATEREQUAL 18/*#define OPERATOR_LSHIFT 19*//*#define OPERATOR_RSHIFT 20*/#define OPERATOR_MULTIPLY 21#define OPERATOR_DIVIDE 22/*#define OPERATOR_MODULUS 23*/#define OPERATOR_INCREMENT 24#define OPERATOR_DECREMENT 25#define OPERATOR_PLUS 26#define OPERATOR_MINUS 27/*#define OPERATOR_COMPLEMENT 28*/#define OPERATOR_NOT 29static 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_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_MODASSIGN, "%=" },*/	/*{ OPERATOR_MODULUS, "%" },*/	/*{ OPERATOR_ANDASSIGN, "&=" },*/	/*{ OPERATOR_BITAND, "&" },*/	/*{ OPERATOR_ORASSIGN, "|=" },*/	/*{ OPERATOR_BITOR, "|" },*/	/*{ OPERATOR_COMPLEMENT, "~" },*/	/*{ OPERATOR_XORASSIGN, "^=" },*/	{ OPERATOR_LOGICALXOR, "^^" },	/*{ OPERATOR_BITXOR, "^" }*/};static slang_atom parse_operator_name (slang_parse_ctx *C){	unsigned int i;	for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)	{		if (operator_names[i].o_code == (unsigned int) (*C->I))		{			slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name);			if (atom == SLANG_ATOM_NULL)			{				slang_info_log_memory (C->L);				return 0;			}			C->I++;			return atom;		}	}	return 0;}static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func){	/* parse function type and name */	if (!parse_fully_specified_type (C, O, &func->header.type))		return 0;	switch (*C->I++)	{	case FUNCTION_ORDINARY:		func->kind = slang_func_ordinary;		func->header.a_name = parse_identifier (C);		if (func->header.a_name == SLANG_ATOM_NULL)			return 0;		break;	case FUNCTION_CONSTRUCTOR:		func->kind = slang_func_constructor;		if (func->header.type.specifier.type == slang_spec_struct)			return 0;		func->header.a_name = slang_atom_pool_atom (C->atoms,			slang_type_specifier_type_to_string (func->header.type.specifier.type));		if (func->header.a_name == SLANG_ATOM_NULL)		{			slang_info_log_memory (C->L);			return 0;		}		break;	case FUNCTION_OPERATOR:		func->kind = slang_func_operator;		func->header.a_name = parse_operator_name (C);		if (func->header.a_name == SLANG_ATOM_NULL)			return 0;		break;	default:		return 0;	}	/* parse function parameters */	while (*C->I++ == PARAMETER_NEXT)	{		slang_variable *p;		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;		}		p = &func->parameters->variables[func->parameters->num_variables];		if (!slang_variable_construct (p))			return 0;		func->parameters->num_variables++;		if (!parse_parameter_declaration (C, O, p))			return 0;	}	/* function formal parameters and local variables share the same scope, so save	 * the information about param count in a seperate place	 * also link the scope to the global variable scope so when a given identifier is not	 * found here, the search process continues in the global space */	func->param_count = func->parameters->num_variables;	func->parameters->outer_scope = O->vars;	return 1;}static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func){	slang_output_ctx o = *O;	if (!parse_function_prototype (C, O, func))		return 0;	/* create function's body operation */	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 (func->body))	{		slang_alloc_free (func->body);		func->body = NULL;		slang_info_log_memory (C->L);		return 0;	}	/* to parse the body the parse context is modified in order to capture parsed variables	 * into function's local variable scope */	C->global_scope = 0;	o.vars = func->parameters;	if (!parse_statement (C, &o, func->body))		return 0;	C->global_scope = 1;	return 1;}static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var){	slang_assembly_file_restore_point point;	slang_machine mach;	slang_assembly_local_info save_local = A->local;	slang_operation op_id, op_assign;	GLboolean result;	/* save the current assembly */	if (!slang_assembly_file_restore_point_save (A->file, &point))		return GL_FALSE;	/* setup the machine */	mach = *A->mach;	mach.ip = A->file->count;	/* allocate local storage for expression */	A->local.ret_size = 0;	A->local.addr_tmp = 0;	A->local.swizzle_tmp = 4;	if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))		return GL_FALSE;	if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))		return GL_FALSE;	/* construct the left side of assignment */	if (!slang_operation_construct (&op_id))		return GL_FALSE;	op_id.type = slang_oper_identifier;	op_id.a_id = var->a_name;	/* put the variable into operation's scope */	op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));	if (op_id.locals->variables == NULL)	{		slang_operation_destruct (&op_id);		return GL_FALSE;	}	op_id.locals->num_variables = 1;	op_id.locals->variables[0] = *var;	/* construct the assignment expression */	if (!slang_operation_construct (&op_assign))	{		op_id.locals->num_variables = 0;		slang_operation_destruct (&op_id);		return GL_FALSE;	}	op_assign.type = slang_oper_assign;	op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));	if (op_assign.children == NULL)	{		slang_operation_destruct (&op_assign);		op_id.locals->num_variables = 0;		slang_operation_destruct (&op_id);		return GL_FALSE;	}	op_assign.num_children = 2;	op_assign.children[0] = op_id;	op_assign.children[1] = *var->initializer;	/* insert the actual expression */	result = _slang_assemble_operation (A, &op_assign, slang_ref_forbid);	/* carefully destroy the operations */	op_assign.num_children = 0;	slang_alloc_free (op_assign.children);	op_assign.children = NULL;	slang_operation_destruct (&op_assign);	op_id.locals->num_variables = 0;	slang_operation_destruct (&op_id);	if (!result)		return GL_FALSE;	if (!slang_assembly_file_push (A->file, slang_asm_exit))		return GL_FALSE;	/* execute the expression */	if (!_slang_execute2 (A->file, &mach))		return GL_FALSE;

⌨️ 快捷键说明

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