|
|
|
@@ -29,10 +29,10 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "imports.h"
|
|
|
|
|
#include "grammar_mesa.h"
|
|
|
|
|
#include "slang_compile.h"
|
|
|
|
|
#include "slang_preprocess.h"
|
|
|
|
|
#include "slang_storage.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.
|
|
|
|
@@ -131,8 +131,8 @@ int slang_translation_unit_construct2 (slang_translation_unit *unit, slang_assem
|
|
|
|
|
unit->machine = mach;
|
|
|
|
|
unit->free_machine = 0;
|
|
|
|
|
unit->atom_pool = atoms;
|
|
|
|
|
unit->free_atom_pool = 0;
|
|
|
|
|
slang_export_data_table_ctr (&unit->exp_data);
|
|
|
|
|
unit->free_atom_pool = 0;
|
|
|
|
|
slang_export_data_table_ctr (&unit->exp_data);
|
|
|
|
|
slang_export_code_table_ctr (&unit->exp_code);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
@@ -149,17 +149,17 @@ void slang_translation_unit_destruct (slang_translation_unit *unit)
|
|
|
|
|
}
|
|
|
|
|
if (unit->free_global_pool)
|
|
|
|
|
slang_alloc_free (unit->global_pool);
|
|
|
|
|
if (unit->free_machine)
|
|
|
|
|
{
|
|
|
|
|
if (unit->free_machine)
|
|
|
|
|
{
|
|
|
|
|
slang_machine_dtr (unit->machine);
|
|
|
|
|
slang_alloc_free (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_data_table_dtr (&unit->exp_data);
|
|
|
|
|
slang_export_code_table_ctr (&unit->exp_code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -353,62 +353,62 @@ static int check_revision (slang_parse_ctx *C)
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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 */
|
|
|
|
@@ -416,24 +416,24 @@ static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var,
|
|
|
|
|
#define FIELD_NEXT 1
|
|
|
|
|
#define FIELD_ARRAY 2
|
|
|
|
|
|
|
|
|
|
static GLboolean parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var,
|
|
|
|
|
static 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))
|
|
|
|
|
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))
|
|
|
|
|
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;
|
|
|
|
|
if (!parse_array_len (C, O, &var->array_len))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return GL_FALSE;
|
|
|
|
@@ -517,7 +517,7 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *
|
|
|
|
|
{
|
|
|
|
|
slang_type_specifier_dtr (&sp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
slang_type_specifier_dtr (&sp);
|
|
|
|
|
}
|
|
|
|
|
while (*C->I++ != FIELD_NONE);
|
|
|
|
@@ -1310,28 +1310,28 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
|
|
|
|
|
|
|
|
|
|
/* 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, ¶m->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, ¶m->array_len))
|
|
|
|
|
{
|
|
|
|
|
slang_type_specifier p;
|
|
|
|
|
|
|
|
|
|
slang_type_specifier_ctr (&p);
|
|
|
|
|
if (!slang_type_specifier_copy (&p, ¶m->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, ¶m->array_len))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* calculate the parameter size */
|
|
|
|
|
if (!calculate_var_size (C, O, param))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
|
|
|
|
|
/* TODO: allocate the local address here? */
|
|
|
|
|
return 1;
|
|
|
|
@@ -1695,14 +1695,14 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
|
|
|
|
|
#if 0
|
|
|
|
|
case VARIABLE_ARRAY_UNKNOWN:
|
|
|
|
|
/* unsized array - mark it as array and copy the specifier to the array element */
|
|
|
|
|
if (!convert_to_array (C, var, &type->specifier))
|
|
|
|
|
if (!convert_to_array (C, var, &type->specifier))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case VARIABLE_ARRAY_EXPLICIT:
|
|
|
|
|
if (!convert_to_array (C, var, &type->specifier))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
if (!parse_array_len (C, O, &var->array_len))
|
|
|
|
|
if (!convert_to_array (C, var, &type->specifier))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
if (!parse_array_len (C, O, &var->array_len))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
@@ -1712,7 +1712,7 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
|
|
|
|
|
/* allocate global address space for a variable with a known size */
|
|
|
|
|
if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_len == 0))
|
|
|
|
|
{
|
|
|
|
|
if (!calculate_var_size (C, O, var))
|
|
|
|
|
if (!calculate_var_size (C, O, var))
|
|
|
|
|
return GL_FALSE;
|
|
|
|
|
var->address = slang_var_pool_alloc (O->global_pool, var->size);
|
|
|
|
|
}
|
|
|
|
@@ -2094,12 +2094,7 @@ static int compile (grammar *id, slang_translation_unit *builtin_units, int *com
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined(USE_X86_ASM) || defined(SLANG_X86)
|
|
|
|
|
/* XXX */
|
|
|
|
|
GLboolean _slang_x86_codegen (slang_machine *, slang_assembly_file *, GLuint);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit_type type,
|
|
|
|
|
slang_info_log *log)
|
|
|
|
@@ -2129,24 +2124,24 @@ int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit
|
|
|
|
|
slang_translation_unit_destruct (&builtin_units[i]);
|
|
|
|
|
}*/
|
|
|
|
|
if (id != 0)
|
|
|
|
|
grammar_destroy (id);
|
|
|
|
|
|
|
|
|
|
if (!success)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
unit->exp_data.atoms = unit->atom_pool;
|
|
|
|
|
if (!_slang_build_export_data_table (&unit->exp_data, &unit->globals))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
unit->exp_code.atoms = unit->atom_pool;
|
|
|
|
|
if (!_slang_build_export_code_table (&unit->exp_code, &unit->functions, unit))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
#if defined(USE_X86_ASM) || defined(SLANG_X86)
|
|
|
|
|
/* XXX: lookup the @main label */
|
|
|
|
|
if (!_slang_x86_codegen (unit->machine, unit->assembly, unit->exp_code.entries[0].address))
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
grammar_destroy (id);
|
|
|
|
|
|
|
|
|
|
if (!success)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
unit->exp_data.atoms = unit->atom_pool;
|
|
|
|
|
if (!_slang_build_export_data_table (&unit->exp_data, &unit->globals))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
unit->exp_code.atoms = unit->atom_pool;
|
|
|
|
|
if (!_slang_build_export_code_table (&unit->exp_code, &unit->functions, unit))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
#if defined(USE_X86_ASM) || defined(SLANG_X86)
|
|
|
|
|
/* XXX: lookup the @main label */
|
|
|
|
|
if (!_slang_x86_codegen (unit->machine, unit->assembly, unit->exp_code.entries[0].address))
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|