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

📄 slang_compile.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Mesa 3-D graphics library
 * Version:  6.3
 *
 * Copyright (C) 2005  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_utility.h"
#include "slang_compile.h"
#include "slang_preprocess.h"
#include "slang_storage.h"
#include "slang_assemble.h"
#include "slang_execute.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.
*/

static void slang_variable_construct (slang_variable *);
static int slang_variable_copy (slang_variable *, const slang_variable *);
static void slang_struct_destruct (slang_struct *);
static int slang_struct_equal (const slang_struct *, const slang_struct *);
static void slang_variable_destruct (slang_variable *);

/* slang_type_specifier_type */

/* these must match with slang_type_specifier_type enum */
static const char *type_specifier_type_names[] = {
	"void",
	"bool",
	"bvec2",
	"bvec3",
	"bvec4",
	"int",
	"ivec2",
	"ivec3",
	"ivec4",
	"float",
	"vec2",
	"vec3",
	"vec4",
	"mat2",
	"mat3",
	"mat4",
	"sampler1D",
	"sampler2D",
	"sampler3D",
	"samplerCube",
	"sampler1DShadow",
	"sampler2DShadow",
	NULL
};

slang_type_specifier_type slang_type_specifier_type_from_string (const char *name)
{
	const char **p = type_specifier_type_names;
	while (*p != NULL)
	{
		if (slang_string_compare (*p, name) == 0)
			return (slang_type_specifier_type) (p - type_specifier_type_names);
		p++;
	}
	return slang_spec_void;
}

/* slang_type_specifier */

void slang_type_specifier_construct (slang_type_specifier *spec)
{
	spec->type = slang_spec_void;
	spec->_struct = NULL;
	spec->_array = NULL;
}

void slang_type_specifier_destruct (slang_type_specifier *spec)
{
	if (spec->_struct != NULL)
	{
		slang_struct_destruct (spec->_struct);
		slang_alloc_free (spec->_struct);
	}
	if (spec->_array != NULL)
	{
		slang_type_specifier_destruct (spec->_array);
		slang_alloc_free (spec->_array);
	}
}

int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
{
	slang_type_specifier_destruct (x);
	slang_type_specifier_construct (x);
	x->type = y->type;
	if (x->type == slang_spec_struct)
	{
		x->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
		if (x->_struct == NULL)
			return 0;
		if (!slang_struct_construct_a (x->_struct))
		{
			slang_alloc_free (x->_struct);
			x->_struct = NULL;
			return 0;
		}
		return slang_struct_copy (x->_struct, y->_struct);
	}
	if (x->type == slang_spec_array)
	{
		x->_array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
		if (x->_array == NULL)
			return 0;
		slang_type_specifier_construct (x->_array);
		return slang_type_specifier_copy (x->_array, y->_array);
	}
	return 1;
}

int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
{
	if (x->type != y->type)
		return 0;
	if (x->type == slang_spec_struct)
		return slang_struct_equal (x->_struct, y->_struct);
	if (x->type == slang_spec_array)
		return slang_type_specifier_equal (x->_array, y->_array);
	return 1;
}

/* slang_fully_specified_type */

static void slang_fully_specified_type_construct (slang_fully_specified_type *type)
{
	type->qualifier = slang_qual_none;
	slang_type_specifier_construct (&type->specifier);
}

static void slang_fully_specified_type_destruct (slang_fully_specified_type *type)
{
	slang_type_specifier_destruct (&type->specifier);
}

static int slang_fully_specified_type_copy (slang_fully_specified_type *x,
	const slang_fully_specified_type *y)
{
	slang_fully_specified_type_construct (x);
	slang_fully_specified_type_destruct (x);
	x->qualifier = y->qualifier;
	return slang_type_specifier_copy (&x->specifier, &y->specifier);
}

/* slang_variable_scope */

static void slang_variable_scope_construct (slang_variable_scope *scope)
{
	scope->variables = NULL;
	scope->num_variables = 0;
	scope->outer_scope = NULL;
}

static void slang_variable_scope_destruct (slang_variable_scope *scope)
{
	unsigned int i;
	for (i = 0; i < scope->num_variables; i++)
		slang_variable_destruct (scope->variables + i);
	slang_alloc_free (scope->variables);
}

static int slang_variable_scope_copy (slang_variable_scope *x, const slang_variable_scope *y)
{
	unsigned int i;
	slang_variable_scope_destruct (x);
	slang_variable_scope_construct (x);
	x->variables = (slang_variable *) slang_alloc_malloc (y->num_variables * sizeof (
		slang_variable));
	if (x->variables == NULL)
		return 0;
	x->num_variables = y->num_variables;
	for (i = 0; i < x->num_variables; i++)
		slang_variable_construct (x->variables + i);
	for (i = 0; i < x->num_variables; i++)
		if (!slang_variable_copy (x->variables + i, y->variables + i))
			return 0;
	x->outer_scope = y->outer_scope;
	return 1;
}

/* slang_operation */

int slang_operation_construct_a (slang_operation *oper)
{
	oper->type = slang_oper_none;
	oper->children = NULL;
	oper->num_children = 0;
	oper->literal = (float) 0;
	oper->identifier = NULL;
	oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
	if (oper->locals == NULL)
		return 0;
	slang_variable_scope_construct (oper->locals);
	return 1;
}

void slang_operation_destruct (slang_operation *oper)
{
	unsigned int i;
	for (i = 0; i < oper->num_children; i++)
		slang_operation_destruct (oper->children + i);
	slang_alloc_free (oper->children);
	slang_alloc_free (oper->identifier);
	slang_variable_scope_destruct (oper->locals);
	slang_alloc_free (oper->locals);
}

static int slang_operation_copy (slang_operation *x, const slang_operation *y)
{
	unsigned int i;
	for (i = 0; i < x->num_children; i++)
		slang_operation_destruct (x->children + i);
	slang_alloc_free (x->children);
	x->num_children = 0;
	slang_alloc_free (x->identifier);
	x->identifier = NULL;
	slang_variable_scope_destruct (x->locals);
	slang_variable_scope_construct (x->locals);

	x->type = y->type;
	x->children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof (
		slang_operation));
	if (x->children == NULL)
		return 0;
	for (i = 0; i < y->num_children; i++)
		if (!slang_operation_construct_a (x->children + i))
		{
			unsigned int j;
			for (j = 0; j < i; j++)
				slang_operation_destruct (x->children + j);
			slang_alloc_free (x->children);
			x->children = NULL;
			return 0;
		}
	x->num_children = y->num_children;
	for (i = 0; i < x->num_children; i++)
		if (!slang_operation_copy (x->children + i, y->children + i))
			return 0;
	x->literal = y->literal;
	if (y->identifier != NULL)
	{
		x->identifier = slang_string_duplicate (y->identifier);
		if (x->identifier == NULL)
			return 0;
	}
	if (!slang_variable_scope_copy (x->locals, y->locals))
		return 0;
	return 1;
}

/* slang_variable */

static void slang_variable_construct (slang_variable *var)
{
	slang_fully_specified_type_construct (&var->type);
	var->name = NULL;
	var->array_size = NULL;
	var->initializer = NULL;
	var->address = ~0;
}

static void slang_variable_destruct (slang_variable *var)
{
	slang_fully_specified_type_destruct (&var->type);
	slang_alloc_free (var->name);
	if (var->array_size != NULL)
	{
		slang_operation_destruct (var->array_size);
		slang_alloc_free (var->array_size);
	}
	if (var->initializer != NULL)
	{
		slang_operation_destruct (var->initializer);
		slang_alloc_free (var->initializer);
	}
}

static int slang_variable_copy (slang_variable *x, const slang_variable *y)
{
	slang_variable_destruct (x);
	slang_variable_construct (x);
	if (!slang_fully_specified_type_copy (&x->type, &y->type))
		return 0;
	if (y->name != NULL)
	{
		x->name = slang_string_duplicate (y->name);
		if (x->name == NULL)
			return 0;
	}
	if (y->array_size != NULL)
	{
		x->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
		if (x->array_size == NULL)
			return 0;
		if (!slang_operation_construct_a (x->array_size))
		{
			slang_alloc_free (x->array_size);
			x->array_size = NULL;
			return 0;
		}
		if (!slang_operation_copy (x->array_size, y->array_size))
			return 0;
	}
	if (y->initializer != NULL)
	{
		x->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
		if (x->initializer == NULL)
			return 0;
		if (!slang_operation_construct_a (x->initializer))
		{
			slang_alloc_free (x->initializer);
			x->initializer = NULL;
			return 0;
		}
		if (!slang_operation_copy (x->initializer, y->initializer))
			return 0;
	}
	return 1;
}

slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all)
{
	unsigned int i;
	for (i = 0; i < scope->num_variables; i++)
		if (slang_string_compare (name, scope->variables[i].name) == 0)
			return scope->variables + i;
	if (all && scope->outer_scope != NULL)
		return _slang_locate_variable (scope->outer_scope, name, 1);
	return NULL;
}

/* slang_struct_scope */

static void slang_struct_scope_construct (slang_struct_scope *scope)
{
	scope->structs = NULL;
	scope->num_structs = 0;
	scope->outer_scope = NULL;
}

static void slang_struct_scope_destruct (slang_struct_scope *scope)
{
	unsigned int i;
	for (i = 0; i < scope->num_structs; i++)
		slang_struct_destruct (scope->structs + i);
	slang_alloc_free (scope->structs);
}

static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y)
{
	unsigned int i;
	slang_struct_scope_destruct (x);
	slang_struct_scope_construct (x);
	x->structs = (slang_struct *) slang_alloc_malloc (y->num_structs * sizeof (slang_struct));
	if (x->structs == NULL)
		return 0;
	x->num_structs = y->num_structs;
	for (i = 0; i < x->num_structs; i++)
	{
		unsigned int j;
		if (!slang_struct_construct_a (x->structs + i))
		{
			for (j = 0; j < i; j++)
				slang_struct_destruct (x->structs + j);
			slang_alloc_free (x->structs);
			x->structs = NULL;
			return 0;
		}
	}
	for (i = 0; i < x->num_structs; i++)
		if (!slang_struct_copy (x->structs + i, y->structs + i))
			return 0;
	x->outer_scope = y->outer_scope;
	return 1;
}

slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name, int all_scopes)
{
	unsigned int i;
	for (i = 0; i < stru->num_structs; i++)
		if (slang_string_compare (name, stru->structs[i].name) == 0)
			return stru->structs + i;
	if (all_scopes && stru->outer_scope != NULL)
		return slang_struct_scope_find (stru->outer_scope, name, 1);
	return NULL;
}

/* slang_struct */

int slang_struct_construct_a (slang_struct *stru)
{
	stru->name = NULL;
	stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
	if (stru->fields == NULL)
		return 0;
	slang_variable_scope_construct (stru->fields);
	stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope));
	if (stru->structs == NULL)
	{
		slang_variable_scope_destruct (stru->fields);
		slang_alloc_free (stru->fields);
		return 0;
	}
	slang_struct_scope_construct (stru->structs);
	return 1;
}

static void slang_struct_destruct (slang_struct *stru)
{
	slang_alloc_free (stru->name);
	slang_variable_scope_destruct (stru->fields);
	slang_alloc_free (stru->fields);
	slang_struct_scope_destruct (stru->structs);
	slang_alloc_free (stru->structs);
}

int slang_struct_copy (slang_struct *x, const slang_struct *y)
{
	slang_alloc_free (x->name);
	x->name = NULL;
	slang_variable_scope_destruct (x->fields);
	slang_variable_scope_construct (x->fields);
	slang_struct_scope_destruct (x->structs);
	slang_struct_scope_construct (x->structs);
	if (y->name != NULL)
	{
		x->name = slang_string_duplicate (y->name);
		if (x->name == NULL)
			return 0;
	}
	if (!slang_variable_scope_copy (x->fields, y->fields))
		return 0;
	if (!slang_struct_scope_copy (x->structs, y->structs))
		return 0;
	return 1;
}

⌨️ 快捷键说明

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