Commit 79c6ce0a authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dcompiler: Parse "if/else" statement.

parent e3a2e3a1
......@@ -706,6 +706,7 @@ enum hlsl_ir_node_type
HLSL_IR_DEREF,
HLSL_IR_EXPR,
HLSL_IR_FUNCTION_DECL,
HLSL_IR_IF,
HLSL_IR_JUMP,
HLSL_IR_SWIZZLE,
};
......@@ -755,6 +756,14 @@ struct hlsl_ir_function_decl
struct list *body;
};
struct hlsl_ir_if
{
struct hlsl_ir_node node;
struct hlsl_ir_node *condition;
struct list *then_instrs;
struct list *else_instrs;
};
struct hlsl_ir_assignment
{
struct hlsl_ir_node node;
......@@ -939,6 +948,12 @@ struct parse_variable_def
struct list *initializer;
};
struct parse_if_body
{
struct list *then_instrs;
struct list *else_instrs;
};
enum parse_unary_op
{
UNARY_OP_PLUS,
......@@ -1043,6 +1058,12 @@ static inline struct hlsl_ir_constructor *constructor_from_node(const struct hls
return CONTAINING_RECORD(node, struct hlsl_ir_constructor, node);
}
static inline struct hlsl_ir_if *if_from_node(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_IF);
return CONTAINING_RECORD(node, struct hlsl_ir_if, 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;
......
......@@ -358,6 +358,7 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
%locations
%error-verbose
%expect 1
%union
{
......@@ -373,6 +374,7 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
struct hlsl_ir_function_decl *function;
struct parse_parameter parameter;
struct parse_variable_def *variable_def;
struct parse_if_body if_body;
enum parse_unary_op unary_op;
enum parse_assign_op assign_op;
}
......@@ -498,12 +500,14 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
%type <list> statement_list
%type <list> compound_statement
%type <list> jump_statement
%type <list> selection_statement
%type <function> func_declaration
%type <function> func_prototype
%type <parameter> parameter
%type <name> semantic
%type <variable_def> variable_def
%type <list> variables_def
%type <if_body> if_body
%type <instr> primary_expr
%type <instr> postfix_expr
%type <instr> unary_expr
......@@ -994,6 +998,7 @@ statement: declaration_statement
| expr_statement
| compound_statement
| jump_statement
| selection_statement
/* FIXME: add rule for return with no value */
jump_statement: KW_RETURN expr ';'
......@@ -1019,6 +1024,41 @@ jump_statement: KW_RETURN expr ';'
list_add_tail($$, &jump->node.entry);
}
selection_statement: KW_IF '(' expr ')' if_body
{
struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
if (!instr)
{
ERR("Out of memory\n");
return -1;
}
instr->node.type = HLSL_IR_IF;
set_location(&instr->node.loc, &@1);
instr->condition = $3;
instr->then_instrs = $5.then_instrs;
instr->else_instrs = $5.else_instrs;
if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
{
hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
instr->node.loc.col, HLSL_LEVEL_ERROR,
"if condition requires a scalar");
}
$$ = d3dcompiler_alloc(sizeof(*$$));
list_init($$);
list_add_head($$, &instr->node.entry);
}
if_body: statement
{
$$.then_instrs = $1;
$$.else_instrs = NULL;
}
| statement KW_ELSE statement
{
$$.then_instrs = $1;
$$.else_instrs = $3;
}
expr_statement: ';'
{
$$ = d3dcompiler_alloc(sizeof(*$$));
......
......@@ -1742,6 +1742,7 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
"HLSL_IR_DEREF",
"HLSL_IR_EXPR",
"HLSL_IR_FUNCTION_DECL",
"HLSL_IR_IF",
"HLSL_IR_JUMP",
"HLSL_IR_SWIZZLE",
};
......@@ -1753,6 +1754,17 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
static void debug_dump_instr(const struct hlsl_ir_node *instr);
static void debug_dump_instr_list(const struct list *list)
{
struct hlsl_ir_node *instr;
LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
{
debug_dump_instr(instr);
TRACE("\n");
}
}
static void debug_dump_ir_var(const struct hlsl_ir_var *var)
{
if (var->modifiers)
......@@ -1997,6 +2009,21 @@ static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
}
}
static void debug_dump_ir_if(const struct hlsl_ir_if *if_node)
{
TRACE("if (");
debug_dump_instr(if_node->condition);
TRACE(")\n{\n");
debug_dump_instr_list(if_node->then_instrs);
TRACE("}\n");
if (if_node->else_instrs)
{
TRACE("else\n{\n");
debug_dump_instr_list(if_node->else_instrs);
TRACE("}\n");
}
}
static void debug_dump_instr(const struct hlsl_ir_node *instr)
{
switch (instr->type)
......@@ -2022,22 +2049,14 @@ static void debug_dump_instr(const struct hlsl_ir_node *instr)
case HLSL_IR_JUMP:
debug_dump_ir_jump(jump_from_node(instr));
break;
case HLSL_IR_IF:
debug_dump_ir_if(if_from_node(instr));
break;
default:
TRACE("No dump function for %s\n", debug_node_type(instr->type));
}
}
static void debug_dump_instr_list(const struct list *list)
{
struct hlsl_ir_node *instr;
LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
{
debug_dump_instr(instr);
TRACE("\n");
}
}
void debug_dump_ir_function(const struct hlsl_ir_function_decl *func)
{
struct hlsl_ir_var *param;
......@@ -2159,6 +2178,14 @@ static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
d3dcompiler_free(assignment);
}
static void free_ir_if(struct hlsl_ir_if *if_node)
{
free_instr(if_node->condition);
free_instr_list(if_node->then_instrs);
free_instr_list(if_node->else_instrs);
d3dcompiler_free(if_node);
}
static void free_ir_jump(struct hlsl_ir_jump *jump)
{
if (jump->type == HLSL_IR_JUMP_RETURN)
......@@ -2191,6 +2218,9 @@ void free_instr(struct hlsl_ir_node *node)
case HLSL_IR_ASSIGNMENT:
free_ir_assignment(assignment_from_node(node));
break;
case HLSL_IR_IF:
free_ir_if(if_from_node(node));
break;
case HLSL_IR_JUMP:
free_ir_jump(jump_from_node(node));
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment