#ifndef AST_H
#define AST_H
-#include "main/simple_list.h"
#include "list.h"
#include "glsl_parser_extras.h"
struct YYLTYPE;
-class ast_node : public simple_node {
+class ast_node {
public:
virtual ~ast_node();
virtual void print(void) const;
unsigned column;
} location;
+ exec_node link;
+
protected:
ast_node(void);
};
* List of expressions for an \c ast_sequence or parameters for an
* \c ast_function_call
*/
- struct simple_node expressions;
+ exec_list expressions;
};
class ast_expression_bin : public ast_expression {
struct _mesa_glsl_parse_state *state);
int new_scope;
- struct simple_node statements;
+ exec_list statements;
};
class ast_declaration : public ast_node {
struct _mesa_glsl_parse_state *state);
char *name;
- struct simple_node declarations;
+ exec_list declarations;
};
struct _mesa_glsl_parse_state *state);
ast_fully_specified_type *type;
- struct simple_node declarations;
+ exec_list declarations;
/**
* Special flag for vertex shader "invariant" declarations.
int is_array;
ast_expression *array_size;
- static void parameters_to_hir(simple_node *ast_parameters,
+ static void parameters_to_hir(exec_list *ast_parameters,
bool formal, exec_list *ir_parameters,
struct _mesa_glsl_parse_state *state);
ast_fully_specified_type *return_type;
char *identifier;
- struct simple_node parameters;
+ exec_list parameters;
private:
/**
class ast_switch_statement : public ast_node {
public:
ast_expression *expression;
- struct simple_node statements;
+ exec_list statements;
};
class ast_iteration_statement : public ast_node {
static unsigned
process_parameters(exec_list *instructions, exec_list *actual_parameters,
- simple_node *parameters,
+ exec_list *parameters,
struct _mesa_glsl_parse_state *state)
{
- simple_node *ptr;
unsigned count = 0;
- foreach (ptr, parameters) {
- ir_rvalue *const result =
- ((ast_node *) ptr)->hir(instructions, state);
+ foreach_list (n, parameters) {
+ ast_node *const ast = exec_node_data(ast_node, n, link);
+ ir_rvalue *const result = ast->hir(instructions, state);
actual_parameters->push_tail(result);
count++;
static ir_rvalue *
match_function_by_name(exec_list *instructions, const char *name,
- YYLTYPE *loc, simple_node *parameters,
+ YYLTYPE *loc, exec_list *parameters,
struct _mesa_glsl_parse_state *state)
{
ir_function *f = state->symbols->get_function(name);
static ir_rvalue *
process_array_constructor(exec_list *instructions,
const glsl_type *constructor_type,
- YYLTYPE *loc, simple_node *parameters,
+ YYLTYPE *loc, exec_list *parameters,
struct _mesa_glsl_parse_state *state)
{
/* Array constructors come in two forms: sized and unsized. Sized array
unsigned nonmatrix_parameters = 0;
exec_list actual_parameters;
- assert(!is_empty_list(&this->expressions));
+ assert(!this->expressions.is_empty());
- simple_node *ptr;
- foreach (ptr, &this->expressions) {
+ foreach_list (n, &this->expressions) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
ir_rvalue *const result =
- ((ast_node *) ptr)->hir(instructions, state)->as_rvalue();
+ ast->hir(instructions, state)->as_rvalue();
/* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
*
void
_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
{
- struct simple_node *ptr;
-
_mesa_glsl_initialize_variables(instructions, state);
_mesa_glsl_initialize_constructors(instructions, state);
_mesa_glsl_initialize_functions(instructions, state);
state->current_function = NULL;
- foreach (ptr, & state->translation_unit) {
- ((ast_node *)ptr)->hir(instructions, state);
+ foreach_list (n, & state->translation_unit) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->hir(instructions, state);
}
}
};
ir_rvalue *result = NULL;
ir_rvalue *op[2];
- struct simple_node op_list;
const struct glsl_type *type = glsl_type::error_type;
bool error_emitted = false;
YYLTYPE loc;
loc = this->get_location();
- make_empty_list(& op_list);
switch (this->oper) {
case ast_assign: {
break;
case ast_sequence: {
- struct simple_node *ptr;
-
/* It should not be possible to generate a sequence in the AST without
* any expressions in it.
*/
- assert(!is_empty_list(&this->expressions));
+ assert(!this->expressions.is_empty());
/* The r-value of a sequence is the last expression in the sequence. If
* the other expressions in the sequence do not have side-effects (and
* therefore add instructions to the instruction list), they get dropped
* on the floor.
*/
- foreach (ptr, &this->expressions)
- result = ((ast_node *)ptr)->hir(instructions, state);
+ foreach_list (n, &this->expressions) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ result = ast->hir(instructions, state);
+ }
type = result->type;
ast_compound_statement::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
- struct simple_node *ptr;
-
-
if (new_scope)
state->symbols->push_scope();
- foreach (ptr, &statements)
- ((ast_node *)ptr)->hir(instructions, state);
+ foreach_list (n, &this->statements) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->hir(instructions, state);
+ }
if (new_scope)
state->symbols->pop_scope();
ast_declarator_list::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
- struct simple_node *ptr;
const struct glsl_type *decl_type;
const char *type_name = NULL;
ir_rvalue *result = NULL;
*/
decl_type = this->type->specifier->glsl_type(& type_name, state);
- if (is_empty_list(&this->declarations)) {
+ if (this->declarations.is_empty()) {
/* There are only two valid cases where the declaration list can be
* empty.
*
}
}
- foreach (ptr, &this->declarations) {
- struct ast_declaration *const decl = (struct ast_declaration * )ptr;
+ foreach_list (n, &this->declarations) {
+ ast_declaration *const decl = exec_node_data(ast_declaration, n, link);
const struct glsl_type *var_type;
struct ir_variable *var;
void
-ast_parameter_declarator::parameters_to_hir(struct simple_node *ast_parameters,
+ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
bool formal,
exec_list *ir_parameters,
_mesa_glsl_parse_state *state)
{
- struct simple_node *ptr;
ast_parameter_declarator *void_param = NULL;
unsigned count = 0;
- foreach (ptr, ast_parameters) {
- ast_parameter_declarator *param = (ast_parameter_declarator *)ptr;
+ foreach_list (n, ast_parameters) {
+ ast_parameter_declarator *param =
+ exec_node_data(ast_parameter_declarator, n, link);
param->formal_parameter = formal;
param->hir(ir_parameters, state);
ast_struct_specifier::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
- simple_node *ptr;
unsigned decl_count = 0;
/* Make an initial pass over the list of structure fields to determine how
* This means that we actually need to count the number of elements in the
* 'declarations' list in each of the elements.
*/
- foreach (ptr, & this->declarations) {
- ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
- simple_node *decl_ptr;
+ foreach_list (n, & this->declarations) {
+ ast_declarator_list *decl_list =
+ exec_node_data(ast_declarator_list, n, link);
- foreach (decl_ptr, & decl_list->declarations) {
+ foreach_list_const (decl_ptr, & decl_list->declarations) {
decl_count++;
}
}
malloc(sizeof(*fields) * decl_count);
unsigned i = 0;
- foreach (ptr, & this->declarations) {
- ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
- simple_node *decl_ptr;
+ foreach_list (n, & this->declarations) {
+ ast_declarator_list *decl_list =
+ exec_node_data(ast_declarator_list, n, link);
const char *type_name;
decl_list->type->specifier->hir(instructions, state);
const glsl_type *decl_type =
decl_list->type->specifier->glsl_type(& type_name, state);
- foreach (decl_ptr, & decl_list->declarations) {
- ast_declaration *const decl = (ast_declaration *) decl_ptr;
+ foreach_list (decl_node, & decl_list->declarations) {
+ ast_declaration *const decl =
+ exec_node_data(ast_declaration, decl_node, link);
const struct glsl_type *const field_type =
(decl->is_array)
? process_array_type(decl_type, decl->array_size, state)
external_declaration_list:
external_declaration
{
- insert_at_tail(& state->translation_unit,
- (struct simple_node *) $1);
+ state->translation_unit.push_tail(& $1->link);
}
| external_declaration_list external_declaration
{
- insert_at_tail(& state->translation_unit,
- (struct simple_node *) $2);
+ state->translation_unit.push_tail(& $2->link);
}
;
{
$$ = $1;
$$->set_location(yylloc);
- insert_at_tail(& $$->expressions, (struct simple_node *) $2);
+ $$->expressions.push_tail(& $2->link);
}
| function_call_header_with_parameters ',' assignment_expression
{
$$ = $1;
$$->set_location(yylloc);
- insert_at_tail(& $$->expressions, (struct simple_node *) $3);
+ $$->expressions.push_tail(& $3->link);
}
;
if ($1->oper != ast_sequence) {
$$ = new ast_expression(ast_sequence, NULL, NULL, NULL);
$$->set_location(yylloc);
- insert_at_tail(& $$->expressions, $1);
+ $$->expressions.push_tail(& $1->link);
} else {
$$ = $1;
}
- insert_at_tail(& $$->expressions, $3);
+ $$->expressions.push_tail(& $3->link);
}
;
function_header parameter_declaration
{
$$ = $1;
- insert_at_tail(& $$->parameters,
- (struct simple_node *) $2);
+ $$->parameters.push_tail(& $2->link);
}
| function_header_with_parameters ',' parameter_declaration
{
$$ = $1;
- insert_at_tail(& $$->parameters,
- (struct simple_node *) $3);
+ $$->parameters.push_tail(& $3->link);
}
;
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| init_declarator_list ',' IDENTIFIER '[' ']'
{
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| init_declarator_list ',' IDENTIFIER '[' constant_expression ']'
{
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer
{
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer
{
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| init_declarator_list ',' IDENTIFIER '=' initializer
{
decl->set_location(yylloc);
$$ = $1;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
;
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| fully_specified_type IDENTIFIER '[' ']'
{
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| fully_specified_type IDENTIFIER '[' constant_expression ']'
{
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| fully_specified_type IDENTIFIER '[' ']' '=' initializer
{
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer
{
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| fully_specified_type IDENTIFIER '=' initializer
{
$$ = new ast_declarator_list($1);
$$->set_location(yylloc);
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
| INVARIANT IDENTIFIER // Vertex only.
{
$$->set_location(yylloc);
$$->invariant = true;
- insert_at_tail(& $$->declarations,
- (struct simple_node *) decl);
+ $$->declarations.push_tail(&decl->link);
}
;
struct_declaration
{
$$ = (struct ast_node *) $1;
+ $1->link.self_link();
}
| struct_declaration_list struct_declaration
{
$$ = (struct ast_node *) $1;
- insert_at_tail((struct simple_node *) $$,
- (struct simple_node *) $2);
+ $$->link.insert_before(& $2->link);
}
;
$$ = new ast_declarator_list(type);
$$->set_location(yylloc);
- insert_at_tail((struct simple_node *) $2,
- & $$->declarations);
+ $$->declarations.push_degenerate_list_at_head(& $2->link);
}
;
struct_declarator_list:
struct_declarator
+ {
+ $$ = $1;
+ $1->link.self_link();
+ }
| struct_declarator_list ',' struct_declarator
{
$$ = $1;
- insert_at_tail((struct simple_node *) $$,
- (struct simple_node *) $3);
+ $$->link.insert_before(& $3->link);
}
;
}
$$ = $1;
- make_empty_list((struct simple_node *) $$);
+ $$->link.self_link();
}
| statement_list statement
{
assert($2 != NULL);
}
$$ = $1;
- insert_at_tail((struct simple_node *) $$,
- (struct simple_node *) $2);
+ $$->link.insert_before(& $2->link);
}
;
decl->set_location(yylloc);
declarator->set_location(yylloc);
- insert_at_tail(& declarator->declarations,
- (struct simple_node *) decl);
-
+ declarator->declarations.push_tail(&decl->link);
$$ = declarator;
}
;
ast_node::ast_node(void)
{
- make_empty_list(this);
+ /* empty */
}
void
ast_compound_statement::print(void) const
{
- const struct simple_node *ptr;
-
printf("{\n");
- foreach(ptr, & statements) {
- ((ast_node *)ptr)->print();
+ foreach_list_const(n, &this->statements) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
printf("}\n");
ast_node *statements)
{
this->new_scope = new_scope;
- make_empty_list(& this->statements);
if (statements != NULL) {
- /* This seems odd, but it works. The simple_list is,
- * basically, a circular list. insert_at_tail adds
- * the specified node to the list before the current
- * head.
- */
- insert_at_tail((struct simple_node *) statements,
- & this->statements);
+ this->statements.push_degenerate_list_at_head(&statements->link);
}
}
subexpressions[0]->print();
printf("( ");
- struct simple_node *ptr;
- foreach (ptr, &this->expressions) {
+ foreach_list_const (n, &this->expressions) {
printf(", ");
- ((ast_node *)ptr)->print();
+
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
printf(") ");
break;
case ast_sequence: {
- struct simple_node *ptr;
- struct simple_node *const head = first_elem(& expressions);
-
printf("( ");
- foreach (ptr, & expressions) {
- if (ptr != head)
+ foreach_list_const(n, & this->expressions) {
+ if (n != this->expressions.get_head())
printf(", ");
- ((ast_node *)ptr)->print();
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
printf(") ");
break;
this->subexpressions[0] = ex0;
this->subexpressions[1] = ex1;
this->subexpressions[2] = ex2;
- make_empty_list(& expressions);
}
void
ast_function::print(void) const
{
- struct simple_node *ptr;
-
return_type->print();
printf(" %s (", identifier);
- foreach(ptr, & parameters) {
- ((ast_node *)ptr)->print();
+ foreach_list_const(n, & this->parameters) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
printf(")");
ast_function::ast_function(void)
: is_definition(false), signature(NULL)
{
- make_empty_list(& parameters);
+ /* empty */
}
void
ast_declarator_list::print(void) const
{
- struct simple_node *head;
- struct simple_node *ptr;
-
assert(type || invariant);
if (type)
else
printf("invariant ");
- head = first_elem(& declarations);
- foreach (ptr, & declarations) {
- if (ptr != head)
+ foreach_list_const (ptr, & this->declarations) {
+ if (ptr != this->declarations.get_head())
printf(", ");
- ((ast_node *)ptr)->print();
+ ast_node *ast = exec_node_data(ast_node, ptr, link);
+ ast->print();
}
printf("; ");
ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
{
this->type = type;
- make_empty_list(& this->declarations);
}
void
void
ast_struct_specifier::print(void) const
{
- struct simple_node *ptr;
-
printf("struct %s { ", name);
- foreach (ptr, & declarations) {
- ((ast_node *)ptr)->print();
+ foreach_list_const(n, &this->declarations) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
printf("} ");
}
ast_node *declarator_list)
{
name = identifier;
-
- /* This seems odd, but it works. The simple_list is,
- * basically, a circular list. insert_at_tail adds
- * the specified node to the list before the current
- * head.
- */
- insert_at_tail((struct simple_node *) declarator_list,
- & declarations);
+ this->declarations.push_degenerate_list_at_head(&declarator_list->link);
}
struct _mesa_glsl_parse_state state;
char *shader;
size_t shader_len;
- struct simple_node *ptr;
exec_list instructions;
if (argc < 3) {
shader = load_text_file(argv[2], & shader_len);
state.scanner = NULL;
- make_empty_list(& state.translation_unit);
+ state.translation_unit.make_empty();
state.symbols = new glsl_symbol_table;
state.error = false;
state.temp_index = 0;
_mesa_glsl_parse(& state);
_mesa_glsl_lexer_dtor(& state);
- foreach (ptr, & state.translation_unit) {
- ((ast_node *)ptr)->print();
+ foreach_list_const(n, &state.translation_unit) {
+ ast_node *ast = exec_node_data(ast_node, n, link);
+ ast->print();
}
_mesa_ast_to_hir(&instructions, &state);
#define GLSL_PARSER_EXTRAS_H
#include <cstdlib>
-#include "main/simple_list.h"
#include "glsl_symbol_table.h"
enum _mesa_glsl_parser_targets {
struct _mesa_glsl_parse_state {
void *scanner;
- struct simple_node translation_unit;
+ exec_list translation_unit;
glsl_symbol_table *symbols;
unsigned language_version;