d3dcompiler: Parse variable initializers, basic expressions.
This commit is contained in:
parent
3275cca970
commit
887ef49419
|
@ -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) \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue