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

📄 slang_compile.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file slang_compile.c * slang front-end compiler * \author Michal Krol */#include "imports.h"#include "grammar_mesa.h"#include "slang_compile.h"#include "slang_preprocess.h"#include "slang_storage.h"/* * This is a straightforward implementation of the slang front-end compiler. * Lots of error-checking functionality is missing but every well-formed shader source should * compile successfully and execute as expected. However, some semantically ill-formed shaders * may be accepted resulting in undefined behaviour. *//* slang_var_pool */static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size){	GLuint addr;	addr = pool->next_addr;	pool->next_addr += size;	return addr;}/* slang_translation_unit */int slang_translation_unit_construct (slang_translation_unit *unit){	unit->assembly = (slang_assembly_file *) slang_alloc_malloc (sizeof (slang_assembly_file));	if (unit->assembly == NULL)		return 0;	if (!slang_assembly_file_construct (unit->assembly))	{		slang_alloc_free (unit->assembly);		return 0;	}	unit->global_pool = (slang_var_pool *) slang_alloc_malloc (sizeof (slang_var_pool));	if (unit->global_pool == NULL)	{		slang_assembly_file_destruct (unit->assembly);		slang_alloc_free (unit->assembly);		return 0;	}	unit->global_pool->next_addr = 0;	unit->machine = (slang_machine *) slang_alloc_malloc (sizeof (slang_machine));	if (unit->machine == NULL)	{		slang_alloc_free (unit->global_pool);		slang_assembly_file_destruct (unit->assembly);		slang_alloc_free (unit->assembly);		return 0;	}	slang_machine_ctr (unit->machine);	unit->atom_pool = (slang_atom_pool *) slang_alloc_malloc (sizeof (slang_atom_pool));	if (unit->atom_pool == NULL)	{		slang_alloc_free (unit->machine);		slang_alloc_free (unit->global_pool);		slang_assembly_file_destruct (unit->assembly);		slang_alloc_free (unit->assembly);		return 0;	}	slang_atom_pool_construct (unit->atom_pool);	if (!slang_translation_unit_construct2 (unit, unit->assembly, unit->global_pool, unit->machine,			unit->atom_pool))	{		slang_alloc_free (unit->atom_pool);		slang_alloc_free (unit->machine);		slang_alloc_free (unit->global_pool);		slang_assembly_file_destruct (unit->assembly);		slang_alloc_free (unit->assembly);		return 0;	}	unit->free_assembly = 1;	unit->free_global_pool = 1;	unit->free_machine = 1;	unit->free_atom_pool = 1;	return 1;}int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assembly_file *file,	slang_var_pool *pool, struct slang_machine_ *mach, slang_atom_pool *atoms){	if (!slang_variable_scope_construct (&unit->globals))		return 0;	if (!slang_function_scope_construct (&unit->functions))	{		slang_variable_scope_destruct (&unit->globals);		return 0;	}	if (!slang_struct_scope_construct (&unit->structs))	{		slang_variable_scope_destruct (&unit->globals);		slang_function_scope_destruct (&unit->functions);		return 0;	}	unit->assembly = file;	unit->free_assembly = 0;	unit->global_pool = pool;	unit->free_global_pool = 0;	unit->machine = mach;	unit->free_machine = 0;	unit->atom_pool = atoms;	unit->free_atom_pool = 0;	slang_export_data_table_ctr (&unit->exp_data);	slang_export_code_table_ctr (&unit->exp_code);	return 1;}void slang_translation_unit_destruct (slang_translation_unit *unit){	slang_variable_scope_destruct (&unit->globals);	slang_function_scope_destruct (&unit->functions);	slang_struct_scope_destruct (&unit->structs);	if (unit->free_assembly)	{		slang_assembly_file_destruct (unit->assembly);		slang_alloc_free (unit->assembly);	}	if (unit->free_global_pool)		slang_alloc_free (unit->global_pool);	if (unit->free_machine)	{		slang_machine_dtr (unit->machine);		slang_alloc_free (unit->machine);	}	if (unit->free_atom_pool)	{		slang_atom_pool_destruct (unit->atom_pool);		slang_alloc_free (unit->atom_pool);	}	slang_export_data_table_dtr (&unit->exp_data);	slang_export_code_table_ctr (&unit->exp_code);}/* slang_info_log */static char *out_of_memory = "error: out of memory\n";void slang_info_log_construct (slang_info_log *log){	log->text = NULL;	log->dont_free_text = 0;}void slang_info_log_destruct (slang_info_log *log){	if (!log->dont_free_text)		slang_alloc_free (log->text);}static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg){	unsigned int new_size;	if (log->dont_free_text)		return 0;	new_size = slang_string_length (prefix) + 3 + slang_string_length (msg);	if (log->text != NULL)	{		unsigned int text_len = slang_string_length (log->text);		log->text = (char *) slang_alloc_realloc (log->text, text_len + 1, new_size + text_len + 1);	}	else	{		log->text = (char *) slang_alloc_malloc (new_size + 1);		if (log->text != NULL)			log->text[0] = '\0';	}	if (log->text == NULL)		return 0;	slang_string_concat (log->text, prefix);	slang_string_concat (log->text, ": ");	slang_string_concat (log->text, msg);	slang_string_concat (log->text, "\n");	return 1;}int slang_info_log_error (slang_info_log *log, const char *msg, ...){	va_list va;	char buf[1024];	va_start (va, msg);	_mesa_vsprintf (buf, msg, va);	if (slang_info_log_message (log, "error", buf))		return 1;	slang_info_log_memory (log);	va_end (va);	return 0;}int slang_info_log_warning (slang_info_log *log, const char *msg, ...){	va_list va;	char buf[1024];	va_start (va, msg);	_mesa_vsprintf (buf, msg, va);	if (slang_info_log_message (log, "warning", buf))		return 1;	slang_info_log_memory (log);	va_end (va);	return 0;}void slang_info_log_memory (slang_info_log *log){	if (!slang_info_log_message (log, "error", "out of memory"))	{		log->dont_free_text = 1;		log->text = out_of_memory;	}}/* slang_parse_ctx */typedef struct slang_parse_ctx_{	const byte *I;	slang_info_log *L;	int parsing_builtin;	int global_scope;	slang_atom_pool *atoms;} slang_parse_ctx;/* slang_output_ctx */typedef struct slang_output_ctx_{	slang_variable_scope *vars;	slang_function_scope *funs;	slang_struct_scope *structs;	slang_assembly_file *assembly;	slang_var_pool *global_pool;	slang_machine *machine;} slang_output_ctx;/* _slang_compile() */static void parse_identifier_str (slang_parse_ctx *C, char **id){	*id = (char *) C->I;	C->I += _mesa_strlen (*id) + 1;}static slang_atom parse_identifier (slang_parse_ctx *C){	const char *id;		id = (const char *) C->I;	C->I += _mesa_strlen (id) + 1;	return slang_atom_pool_atom (C->atoms, id);}static int parse_number (slang_parse_ctx *C, int *number){	const int radix = (int) (*C->I++);	*number = 0;	while (*C->I != '\0')	{		int digit;		if (*C->I >= '0' && *C->I <= '9')			digit = (int) (*C->I - '0');		else if (*C->I >= 'A' && *C->I <= 'Z')			digit = (int) (*C->I - 'A') + 10;		else			digit = (int) (*C->I - 'a') + 10;		*number = *number * radix + digit;		C->I++;	}	C->I++;	if (*number > 65535)		slang_info_log_warning (C->L, "%d: literal integer overflow", *number);	return 1;}static int parse_float (slang_parse_ctx *C, float *number){	char *integral = NULL;	char *fractional = NULL;	char *exponent = NULL;	char *whole = NULL;	parse_identifier_str (C, &integral);	parse_identifier_str (C, &fractional);	parse_identifier_str (C, &exponent);	whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +		_mesa_strlen (exponent) + 3) * sizeof (char)));	if (whole == NULL)	{		slang_info_log_memory (C->L);		return 0;	}	slang_string_copy (whole, integral);	slang_string_concat (whole, ".");	slang_string_concat (whole, fractional);	slang_string_concat (whole, "E");	slang_string_concat (whole, exponent);	*number = (float) (_mesa_strtod(whole, (char **)NULL));	slang_alloc_free (whole);	return 1;}/* revision number - increment after each change affecting emitted output */#define REVISION 3static int check_revision (slang_parse_ctx *C){	if (*C->I != REVISION)	{		slang_info_log_error (C->L, "internal compiler error");		return 0;	}	C->I++;	return 1;}static int parse_statement (slang_parse_ctx *, slang_output_ctx *, slang_operation *);static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *);static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *);static GLboolean parse_array_len (slang_parse_ctx *C, slang_output_ctx *O, GLuint *len){	slang_operation array_size;	slang_assembly_name_space space;	GLboolean result;	if (!slang_operation_construct (&array_size))		return GL_FALSE;	if (!parse_expression (C, O, &array_size))	{		slang_operation_destruct (&array_size);		return GL_FALSE;	}	space.funcs = O->funs;	space.structs = O->structs;	space.vars = O->vars;	result = _slang_evaluate_int (O->assembly, O->machine, &space, &array_size, len, C->atoms);	slang_operation_destruct (&array_size);	return result;}static GLboolean calculate_var_size (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var){	slang_storage_aggregate agg;	if (!slang_storage_aggregate_construct (&agg))		return GL_FALSE;	if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_len, O->funs, O->structs,			O->vars, O->machine, O->assembly, C->atoms))	{		slang_storage_aggregate_destruct (&agg);		return GL_FALSE;	}	var->size = _slang_sizeof_aggregate (&agg);	slang_storage_aggregate_destruct (&agg);	return GL_TRUE;}static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var,	const slang_type_specifier *sp){	/* sized array - mark it as array, copy the specifier to the array element and	 * parse the expression */	var->type.specifier.type = slang_spec_array;	var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (		slang_type_specifier));	if (var->type.specifier._array == NULL)	{		slang_info_log_memory (C->L);		return GL_FALSE;	}	slang_type_specifier_ctr (var->type.specifier._array);	return slang_type_specifier_copy (var->type.specifier._array, sp);}/* structure field */#define FIELD_NONE 0#define FIELD_NEXT 1#define FIELD_ARRAY 2static GLboolean parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var,	const slang_type_specifier *sp){	var->a_name = parse_identifier (C);	if (var->a_name == SLANG_ATOM_NULL)		return GL_FALSE;	switch (*C->I++)	{	case FIELD_NONE:		if (!slang_type_specifier_copy (&var->type.specifier, sp))			return GL_FALSE;		break;	case FIELD_ARRAY:		if (!convert_to_array (C, var, sp))			return GL_FALSE;		if (!parse_array_len (C, O, &var->array_len))			return GL_FALSE;		break;	default:		return GL_FALSE;	}	return calculate_var_size (C, O, var);}static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st,	slang_type_specifier *sp){	slang_output_ctx o = *O;	o.structs = st->structs;	if (!parse_type_specifier (C, &o, sp))		return 0;	do	{		slang_variable *var;		st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables,			st->fields->num_variables * sizeof (slang_variable),			(st->fields->num_variables + 1) * sizeof (slang_variable));		if (st->fields->variables == NULL)		{			slang_info_log_memory (C->L);			return 0;		}		var = &st->fields->variables[st->fields->num_variables];		if (!slang_variable_construct (var))			return 0;		st->fields->num_variables++;		if (!parse_struct_field_var (C, &o, var, sp))			return 0;	}	while (*C->I++ != FIELD_NONE);	return 1;}static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st){	slang_atom a_name;	const char *name;	/* parse struct name (if any) and make sure it is unique in current scope */	a_name = parse_identifier (C);	if (a_name == SLANG_ATOM_NULL)		return 0;	name = slang_atom_pool_id (C->atoms, a_name);	if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)	{		slang_info_log_error (C->L, "%s: duplicate type name", name);		return 0;	}	/* set-up a new struct */	*st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));	if (*st == NULL)	{		slang_info_log_memory (C->L);		return 0;	}	if (!slang_struct_construct (*st))	{		slang_alloc_free (*st);		*st = NULL;		slang_info_log_memory (C->L);		return 0;	}	(**st).a_name = a_name;	(**st).structs->outer_scope = O->structs;	/* parse individual struct fields */	do	{		slang_type_specifier sp;		slang_type_specifier_ctr (&sp);		if (!parse_struct_field (C, O, *st, &sp))		{			slang_type_specifier_dtr (&sp);			return 0;		}		slang_type_specifier_dtr (&sp);	}	while (*C->I++ != FIELD_NONE);	/* if named struct, copy it to current scope */	if (name[0] != '\0')	{		slang_struct *s;		O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,			O->structs->num_structs * sizeof (slang_struct),			(O->structs->num_structs + 1) * sizeof (slang_struct));		if (O->structs->structs == NULL)		{			slang_info_log_memory (C->L);			return 0;		}		s = &O->structs->structs[O->structs->num_structs];

⌨️ 快捷键说明

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