d3dcompiler: Parse variable initializers, basic expressions.
This commit is contained in:
parent
3275cca970
commit
887ef49419
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "d3dcompiler.h"
|
#include "d3dcompiler.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This doesn't belong here, but for some functions it is possible to return that value,
|
* 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
|
* 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
|
enum hlsl_ir_node_type
|
||||||
{
|
{
|
||||||
HLSL_IR_VAR = 0,
|
HLSL_IR_VAR = 0,
|
||||||
|
HLSL_IR_CONSTANT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hlsl_ir_node
|
struct hlsl_ir_node
|
||||||
|
@ -719,6 +722,24 @@ struct hlsl_ir_var
|
||||||
struct hlsl_var_allocation *allocation;
|
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 hlsl_scope
|
||||||
{
|
{
|
||||||
struct list entry;
|
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;
|
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;
|
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;
|
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;
|
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_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
|
||||||
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
|
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
|
||||||
void free_hlsl_type(struct hlsl_type *type) 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) \
|
#define MAKE_TAG(ch0, ch1, ch2, ch3) \
|
||||||
|
|
|
@ -121,8 +121,10 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||||
struct hlsl_type *type;
|
struct hlsl_type *type;
|
||||||
INT intval;
|
INT intval;
|
||||||
FLOAT floatval;
|
FLOAT floatval;
|
||||||
|
BOOL boolval;
|
||||||
char *name;
|
char *name;
|
||||||
DWORD modifiers;
|
DWORD modifiers;
|
||||||
|
struct hlsl_ir_node *instr;
|
||||||
struct list *list;
|
struct list *list;
|
||||||
struct parse_variable_def *variable_def;
|
struct parse_variable_def *variable_def;
|
||||||
}
|
}
|
||||||
|
@ -233,13 +235,33 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||||
%token <name> STRING
|
%token <name> STRING
|
||||||
%token <floatval> C_FLOAT
|
%token <floatval> C_FLOAT
|
||||||
%token <intval> C_INTEGER
|
%token <intval> C_INTEGER
|
||||||
|
%type <boolval> boolean
|
||||||
%type <type> base_type
|
%type <type> base_type
|
||||||
%type <type> type
|
%type <type> type
|
||||||
|
%type <list> complex_initializer
|
||||||
|
%type <list> initializer_expr_list
|
||||||
|
%type <instr> initializer_expr
|
||||||
%type <modifiers> var_modifiers
|
%type <modifiers> var_modifiers
|
||||||
|
%type <instr> expr
|
||||||
%type <intval> array
|
%type <intval> array
|
||||||
%type <name> semantic
|
%type <name> semantic
|
||||||
%type <variable_def> variable_def
|
%type <variable_def> variable_def
|
||||||
%type <list> variables_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 */
|
hlsl_prog: /* empty */
|
||||||
|
@ -337,6 +359,7 @@ declaration: var_modifiers type variables_def ';'
|
||||||
if (v->initializer)
|
if (v->initializer)
|
||||||
{
|
{
|
||||||
FIXME("Variable with an initializer.\n");
|
FIXME("Variable with an initializer.\n");
|
||||||
|
free_instr_list(v->initializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
|
if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
|
||||||
|
@ -375,11 +398,26 @@ variable_def: any_identifier array semantic
|
||||||
$$->array_size = $2;
|
$$->array_size = $2;
|
||||||
$$->semantic = $3;
|
$$->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 */
|
array: /* Empty */
|
||||||
{
|
{
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
| '[' expr ']'
|
||||||
|
{
|
||||||
|
FIXME("Array.\n");
|
||||||
|
$$ = 0;
|
||||||
|
free_instr($2);
|
||||||
|
}
|
||||||
|
|
||||||
var_modifiers: /* Empty */
|
var_modifiers: /* Empty */
|
||||||
{
|
{
|
||||||
|
@ -430,6 +468,166 @@ var_modifiers: /* Empty */
|
||||||
$$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
|
$$ = 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)
|
struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
|
||||||
|
|
|
@ -950,6 +950,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
|
||||||
const char *names[] =
|
const char *names[] =
|
||||||
{
|
{
|
||||||
"HLSL_IR_VAR",
|
"HLSL_IR_VAR",
|
||||||
|
"HLSL_IR_CONSTANT",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type > sizeof(names) / sizeof(names[0]))
|
if (type > sizeof(names) / sizeof(names[0]))
|
||||||
|
@ -975,3 +976,51 @@ void free_hlsl_type(struct hlsl_type *type)
|
||||||
}
|
}
|
||||||
d3dcompiler_free(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue