d3dcompiler: Parse variable initializers, basic expressions.

This commit is contained in:
Matteo Bruni 2012-06-07 00:19:04 +02:00 committed by Alexandre Julliard
parent 3275cca970
commit 887ef49419
3 changed files with 276 additions and 0 deletions

View File

@ -33,6 +33,8 @@
#include "d3dcompiler.h"
#include <assert.h>
/*
* This doesn't belong here, but for some functions it is possible to return that value,
* see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
@ -681,6 +683,7 @@ struct hlsl_struct_field
enum hlsl_ir_node_type
{
HLSL_IR_VAR = 0,
HLSL_IR_CONSTANT,
};
struct hlsl_ir_node
@ -719,6 +722,24 @@ struct hlsl_ir_var
struct hlsl_var_allocation *allocation;
};
struct hlsl_ir_constant
{
struct hlsl_ir_node node;
union
{
union
{
unsigned u[16];
int i[16];
float f[16];
double d[16];
BOOL b[16];
} value;
struct hlsl_ir_constant *array_elements;
struct list *struct_elements;
} v;
};
struct hlsl_scope
{
struct list entry;
@ -758,6 +779,12 @@ extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN;
void hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN;
static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_CONSTANT);
return CONTAINING_RECORD(node, struct hlsl_ir_constant, node);
}
BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN;
struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN;
void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
@ -777,6 +804,8 @@ const char *debug_base_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
void free_instr_list(struct list *list) DECLSPEC_HIDDEN;
#define MAKE_TAG(ch0, ch1, ch2, ch3) \

View File

@ -121,8 +121,10 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
struct hlsl_type *type;
INT intval;
FLOAT floatval;
BOOL boolval;
char *name;
DWORD modifiers;
struct hlsl_ir_node *instr;
struct list *list;
struct parse_variable_def *variable_def;
}
@ -233,13 +235,33 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%token <name> STRING
%token <floatval> C_FLOAT
%token <intval> C_INTEGER
%type <boolval> boolean
%type <type> base_type
%type <type> type
%type <list> complex_initializer
%type <list> initializer_expr_list
%type <instr> initializer_expr
%type <modifiers> var_modifiers
%type <instr> expr
%type <intval> array
%type <name> semantic
%type <variable_def> variable_def
%type <list> variables_def
%type <instr> primary_expr
%type <instr> postfix_expr
%type <instr> unary_expr
%type <instr> mul_expr
%type <instr> add_expr
%type <instr> shift_expr
%type <instr> relational_expr
%type <instr> equality_expr
%type <instr> bitand_expr
%type <instr> bitxor_expr
%type <instr> bitor_expr
%type <instr> logicand_expr
%type <instr> logicor_expr
%type <instr> conditional_expr
%type <instr> assignment_expr
%%
hlsl_prog: /* empty */
@ -337,6 +359,7 @@ declaration: var_modifiers type variables_def ';'
if (v->initializer)
{
FIXME("Variable with an initializer.\n");
free_instr_list(v->initializer);
}
if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
@ -375,11 +398,26 @@ variable_def: any_identifier array semantic
$$->array_size = $2;
$$->semantic = $3;
}
| any_identifier array semantic '=' complex_initializer
{
TRACE("Declaration with initializer.\n");
$$ = d3dcompiler_alloc(sizeof(*$$));
$$->name = $1;
$$->array_size = $2;
$$->semantic = $3;
$$->initializer = $5;
}
array: /* Empty */
{
$$ = 0;
}
| '[' expr ']'
{
FIXME("Array.\n");
$$ = 0;
free_instr($2);
}
var_modifiers: /* Empty */
{
@ -430,6 +468,166 @@ var_modifiers: /* Empty */
$$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
}
complex_initializer: initializer_expr
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
list_add_head($$, &$1->entry);
}
| '{' initializer_expr_list '}'
{
$$ = $2;
}
initializer_expr: assignment_expr
{
$$ = $1;
}
initializer_expr_list: initializer_expr
{
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
list_add_head($$, &$1->entry);
}
| initializer_expr_list ',' initializer_expr
{
$$ = $1;
list_add_tail($$, &$3->entry);
}
boolean: KW_TRUE
{
$$ = TRUE;
}
| KW_FALSE
{
$$ = FALSE;
}
primary_expr: C_FLOAT
{
struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
if (!c)
{
ERR("Out of memory.\n");
return -1;
}
c->node.type = HLSL_IR_CONSTANT;
c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
c->v.value.f[0] = $1;
$$ = &c->node;
}
| C_INTEGER
{
struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
if (!c)
{
ERR("Out of memory.\n");
return -1;
}
c->node.type = HLSL_IR_CONSTANT;
c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
c->v.value.i[0] = $1;
$$ = &c->node;
}
| boolean
{
struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
if (!c)
{
ERR("Out of memory.\n");
return -1;
}
c->node.type = HLSL_IR_CONSTANT;
c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
c->v.value.b[0] = $1;
$$ = &c->node;
}
| '(' expr ')'
{
$$ = $2;
}
postfix_expr: primary_expr
{
$$ = $1;
}
unary_expr: postfix_expr
{
$$ = $1;
}
mul_expr: unary_expr
{
$$ = $1;
}
add_expr: mul_expr
{
$$ = $1;
}
shift_expr: add_expr
{
$$ = $1;
}
relational_expr: shift_expr
{
$$ = $1;
}
equality_expr: relational_expr
{
$$ = $1;
}
bitand_expr: equality_expr
{
$$ = $1;
}
bitxor_expr: bitand_expr
{
$$ = $1;
}
bitor_expr: bitxor_expr
{
$$ = $1;
}
logicand_expr: bitor_expr
{
$$ = $1;
}
logicor_expr: logicand_expr
{
$$ = $1;
}
conditional_expr: logicor_expr
{
$$ = $1;
}
assignment_expr: conditional_expr
{
$$ = $1;
}
expr: assignment_expr
{
$$ = $1;
}
| expr ',' assignment_expr
{
FIXME("Comma expression\n");
}
%%
struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)

View File

@ -950,6 +950,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
const char *names[] =
{
"HLSL_IR_VAR",
"HLSL_IR_CONSTANT",
};
if (type > sizeof(names) / sizeof(names[0]))
@ -975,3 +976,51 @@ void free_hlsl_type(struct hlsl_type *type)
}
d3dcompiler_free(type);
}
void free_instr_list(struct list *list)
{
struct hlsl_ir_node *node, *next_node;
if (!list)
return;
LIST_FOR_EACH_ENTRY_SAFE(node, next_node, list, struct hlsl_ir_node, entry)
free_instr(node);
}
static void free_ir_constant(struct hlsl_ir_constant *constant)
{
struct hlsl_type *type = constant->node.data_type;
unsigned int i;
struct hlsl_ir_constant *field, *next_field;
switch (type->type)
{
case HLSL_CLASS_ARRAY:
for (i = 0; i < type->e.array.elements_count; ++i)
free_ir_constant(&constant->v.array_elements[i]);
d3dcompiler_free(constant->v.array_elements);
break;
case HLSL_CLASS_STRUCT:
LIST_FOR_EACH_ENTRY_SAFE(field, next_field, constant->v.struct_elements, struct hlsl_ir_constant, node.entry)
free_ir_constant(field);
break;
default:
break;
}
d3dcompiler_free(constant);
}
void free_instr(struct hlsl_ir_node *node)
{
switch (node->type)
{
case HLSL_IR_VAR:
/* These are freed later on from the scopes. */
break;
case HLSL_IR_CONSTANT:
free_ir_constant(constant_from_node(node));
break;
default:
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
}
}