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

📄 slang_compile.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
#define DECLARATOR_NONE 0
#define DECLARATOR_NEXT 1

/* variable declaration */
#define VARIABLE_NONE 0
#define VARIABLE_IDENTIFIER 1
#define VARIABLE_INITIALIZER 2
#define VARIABLE_ARRAY_EXPLICIT 3
#define VARIABLE_ARRAY_UNKNOWN 4

static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specified_type *type,
	slang_variable_scope *vars, slang_struct_scope *structs, slang_function_scope *funcs)
{
	slang_variable *var;

	if (*C->I++ == VARIABLE_NONE)
		return 1;
	vars->variables = (slang_variable *) slang_alloc_realloc (vars->variables,
		vars->num_variables * sizeof (slang_variable),
		(vars->num_variables + 1) * sizeof (slang_variable));
	if (vars->variables == NULL)
	{
		slang_info_log_memory (C->L);
		return 0;
	}
	var = vars->variables + vars->num_variables;
	vars->num_variables++;
	slang_variable_construct (var);
	var->type.qualifier = type->qualifier;
	if (!parse_identifier (C, &var->name))
		return 0;
	switch (*C->I++)
	{
	case VARIABLE_NONE:
		if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
			return 0;
		break;
	case VARIABLE_INITIALIZER:
		if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
			return 0;
		var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
		if (var->initializer == NULL)
		{
			slang_info_log_memory (C->L);
			return 0;
		}
		if (!slang_operation_construct_a (var->initializer))
		{
			slang_alloc_free (var->initializer);
			var->initializer = NULL;
			slang_info_log_memory (C->L);
			return 0;
		}
		if (!parse_expression (C, var->initializer, vars, structs, funcs))
			return 0;
		break;
	case VARIABLE_ARRAY_UNKNOWN:
		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 0;
		}
		slang_type_specifier_construct (var->type.specifier._array);
		if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier))
			return 0;
		break;
	case VARIABLE_ARRAY_EXPLICIT:
		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 0;
		}
		slang_type_specifier_construct (var->type.specifier._array);
		if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier))
			return 0;
		var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
		if (var->array_size == NULL)
		{
			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_info_log_memory (C->L);
			return 0;
		}
		if (!parse_expression (C, var->array_size, vars, structs, funcs))
			return 0;
		break;
	default:
		return 0;
	}
	if (!(var->type.specifier.type == slang_spec_array && var->array_size == NULL))
	{
		slang_storage_aggregate agg;

		slang_storage_aggregate_construct (&agg);
		if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, funcs,
			structs))
		{
			slang_storage_aggregate_destruct (&agg);
			return 0;
		}
		slang_storage_aggregate_destruct (&agg);
	}
	return 1;
}

static int parse_init_declarator_list (slang_parse_ctx *C, slang_variable_scope *vars,
	slang_struct_scope *structs, slang_function_scope *funcs)
{
	slang_fully_specified_type type;

	slang_fully_specified_type_construct (&type);
	if (!parse_fully_specified_type (C, &type, structs, vars, funcs))
	{
		slang_fully_specified_type_destruct (&type);
		return 0;
	}
	do
	{
		if (!parse_init_declarator (C, &type, vars, structs, funcs))
		{
			slang_fully_specified_type_destruct (&type);
			return 0;
		}
	}
	while (*C->I++ == DECLARATOR_NEXT);
	slang_fully_specified_type_destruct (&type);
	return 1;
}

static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scope *structs,
	slang_function_scope *funcs, slang_variable_scope *scope, slang_function **parsed_func_ret)
{
	slang_function parsed_func, *found_func;

	/* parse function definition/declaration */
	slang_function_construct (&parsed_func);
	if (definition)
	{
		if (!parse_function_definition (C, &parsed_func, structs, scope, funcs))
		{
			slang_function_destruct (&parsed_func);
			return 0;
		}
	}
	else
	{
		if (!parse_function_prototype (C, &parsed_func, structs, scope, funcs))
		{
			slang_function_destruct (&parsed_func);
			return 0;
		}
	}

	/* find a function with a prototype matching the parsed one - only the current scope
	is being searched to allow built-in function overriding */
	found_func = slang_function_scope_find (funcs, &parsed_func, 0);
	if (found_func == NULL)
	{
		/* add the parsed function to the function list */
		funcs->functions = (slang_function *) slang_alloc_realloc (funcs->functions,
			funcs->num_functions * sizeof (slang_function), (funcs->num_functions + 1) * sizeof (
			slang_function));
		if (funcs->functions == NULL)
		{
			slang_info_log_memory (C->L);
			slang_function_destruct (&parsed_func);
			return 0;
		}
		funcs->functions[funcs->num_functions] = parsed_func;
		funcs->num_functions++;

		/* return the newly parsed function */
		*parsed_func_ret = funcs->functions + funcs->num_functions - 1;
	}
	else
	{
		/* TODO: check function return type qualifiers and specifiers */
		if (definition)
		{
			/* destroy the existing function declaration and replace it with the new one */
			if (found_func->body != NULL)
			{
				slang_info_log_error (C->L, "%s: function already has a body",
					parsed_func.header.name);
				slang_function_destruct (&parsed_func);
				return 0;
			}
			slang_function_destruct (found_func);
			*found_func = parsed_func;
		}
		else
		{
			/* another declaration of the same function prototype - ignore it */
			slang_function_destruct (&parsed_func);
		}

		/* return the found function */
		*parsed_func_ret = found_func;
	}

	/* assemble the parsed function */
	if (definition)
	{
static int x = 0;
static
		slang_assembly_file file;
		slang_assembly_name_space space;
x++;
if (x == 1)
		slang_assembly_file_construct (&file);
		space.funcs = funcs;
		space.structs = structs;
		space.vars = scope;
if (x == 1)
xxx_first (&file);
		(**parsed_func_ret).address = file.count;
		if (!_slang_assemble_function (&file, *parsed_func_ret, &space))
		{
			slang_assembly_file_destruct (&file);
			return 0;
		}
if (slang_string_compare ("main", (**parsed_func_ret).header.name) == 0)
{
xxx_prolog (&file, (**parsed_func_ret).address);
_slang_execute (&file);
slang_assembly_file_destruct (&file);
exit (0);
}
	}
	return 1;
}

/* declaration */
#define DECLARATION_FUNCTION_PROTOTYPE 1
#define DECLARATION_INIT_DECLARATOR_LIST 2

static int parse_declaration (slang_parse_ctx *C, slang_variable_scope *scope,
	slang_struct_scope *structs, slang_function_scope *funcs)
{
	slang_function *dummy_func;

	switch (*C->I++)
	{
	case DECLARATION_INIT_DECLARATOR_LIST:
		if (!parse_init_declarator_list (C, scope, structs, funcs))
			return 0;
		break;
	case DECLARATION_FUNCTION_PROTOTYPE:
		if (!parse_function (C, 0, structs, funcs, scope, &dummy_func))
			return 0;
		break;
	default:
		return 0;
	}
	return 1;
}

/* external declaration */
#define EXTERNAL_NULL 0
#define EXTERNAL_FUNCTION_DEFINITION 1
#define EXTERNAL_DECLARATION 2

static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *unit)
{
	while (*C->I != EXTERNAL_NULL)
	{
		slang_function *func;

		switch (*C->I++)
		{
		case EXTERNAL_FUNCTION_DEFINITION:
			if (!parse_function (C, 1, &unit->structs, &unit->functions, &unit->globals, &func))
				return 0;
			break;
		case EXTERNAL_DECLARATION:
			if (!parse_declaration (C, &unit->globals, &unit->structs, &unit->functions))
				return 0;
			break;
		default:
			return 0;
		}
	}
	C->I++;
	return 1;
}

static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type,
	slang_info_log *log, slang_translation_unit *builtins)
{
	slang_parse_ctx C;

	/* set-up parse context */
	C.I = prod;
	C.L = log;
	C.parsing_builtin = builtins == NULL;

	if (!check_revision (&C))
		return 0;

	/* create translation unit object */
	slang_translation_unit_construct (unit);
	unit->type = type;

	if (builtins != NULL)
	{
		/* link to built-in functions */
		builtins[1].functions.outer_scope = &builtins[0].functions;
		builtins[2].functions.outer_scope = &builtins[1].functions;
		unit->functions.outer_scope = &builtins[2].functions;

		/* link to built-in variables - core unit does not define any */
		builtins[2].globals.outer_scope = &builtins[1].globals;
		unit->globals.outer_scope = &builtins[2].globals;

		/* link to built-in structure typedefs - only in common unit */
		unit->structs.outer_scope = &builtins[1].structs;
	}

	/* parse translation unit */
	if (!parse_translation_unit (&C, unit))
	{
		slang_translation_unit_destruct (unit);
		return 0;
	}

	return 1;
}

static int compile_with_grammar (grammar id, const char *source, slang_translation_unit *unit,
	slang_unit_type type, slang_info_log *log, slang_translation_unit *builtins)
{
	byte *prod;
	unsigned int size, start, version;

	/* retrieve version */
	if (!_slang_preprocess_version (source, &version, &start, log))
		return 0;

	/* check the syntax */
	if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536))
	{
		char buf[1024];
		unsigned int pos;
		grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
		slang_info_log_error (log, buf);
		return 0;
	}

	if (!compile_binary (prod, unit, type, log, builtins))
	{
		grammar_alloc_free (prod);
		return 0;
	}

	grammar_alloc_free (prod);
	return 1;
}

static const char *slang_shader_syn =
#include "library/slang_shader_syn.h"
;
/*
static const byte slang_core_gc_bin[] = {
#include "library/slang_core_gc_bin.h"
};*/
static const byte slang_core_gc[] = {
#include "library/slang_core_gc.h"
};

static const byte slang_common_builtin_gc_bin[] = {
#include "library/slang_common_builtin_gc_bin.h"
};

static const byte slang_fragment_builtin_gc_bin[] = {
#include "library/slang_fragment_builtin_gc_bin.h"
};

static const byte slang_vertex_builtin_gc_bin[] = {
#include "library/slang_vertex_builtin_gc_bin.h"
};

int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit_type type,
	slang_info_log *log)
{
	grammar id;
	slang_translation_unit builtin_units[3];
	slang_translation_unit *builtins = NULL;

	/* load slang grammar */
	id = grammar_load_from_text ((const byte *) slang_shader_syn);
	if (id == 0)
	{
		char buf[1024];
		unsigned int pos;
		grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
		slang_info_log_error (log, buf);
		return 0;
	}

	/* set shader type - the syntax is slightly different for different shaders */
	if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin)
		grammar_set_reg8 (id, (const byte *) "shader_type", 1);
	else
		grammar_set_reg8 (id, (const byte *) "shader_type", 2);

	/* enable language extensions */
	grammar_set_reg8 (id, (const byte *) "parsing_builtin", 1);

	/* if parsing user-specified shader, load built-in library */
	if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
	{
		/*if (!compile_binary (slang_core_gc_bin, builtin_units,
			slang_unit_fragment_builtin, log, NULL))*/
		if (!compile_with_grammar (id, (const char*) slang_core_gc, builtin_units, slang_unit_fragment_builtin,
			log, NULL))
		{
			grammar_destroy (id);
			return 0;
		}
		if (!compile_binary (slang_common_builtin_gc_bin, builtin_units + 1,
			slang_unit_fragment_builtin, log, NULL))
		{
			slang_translation_unit_destruct (builtin_units);
			grammar_destroy (id);
			return 0;
		}
		if (type == slang_unit_fragment_shader)
		{
			if (!compile_binary (slang_fragment_builtin_gc_bin, builtin_units + 2,
				slang_unit_fragment_builtin, log, NULL))
			{
				slang_translation_unit_destruct (builtin_units);
				slang_translation_unit_destruct (builtin_units + 1);
				grammar_destroy (id);
				return 0;
			}
		}
		else if (type == slang_unit_vertex_shader)
		{
			if (!compile_binary (slang_vertex_builtin_gc_bin, builtin_units + 2,
				slang_unit_vertex_builtin, log, NULL))
			{
				slang_translation_unit_destruct (builtin_units);
				slang_translation_unit_destruct (builtin_units + 1);
				grammar_destroy (id);
				return 0;
			}
		}

		/* disable language extensions */
		grammar_set_reg8 (id, (const byte *) "parsing_builtin", 0);
		builtins = builtin_units;
	}

	/* compile the actual shader - pass-in built-in library for external shader */
	if (!compile_with_grammar (id, source, unit, type, log, builtins))
	{
		if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
		{

⌨️ 快捷键说明

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