summaryrefslogtreecommitdiff
path: root/ir_reader.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-04-10 01:45:08 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-28 18:14:54 -0700
commit3ea0582803ea3070a1856455137daef9ddd86cb9 (patch)
treeeac7d3351ff106b0d6909e0c45118671e0ed5466 /ir_reader.cpp
parent57944975427769b08e00f274ff4d9a3e9849a5a2 (diff)
ir_reader: Add support for reading conditionals: (if ...)
Diffstat (limited to 'ir_reader.cpp')
-rw-r--r--ir_reader.cpp80
1 files changed, 62 insertions, 18 deletions
diff --git a/ir_reader.cpp b/ir_reader.cpp
index d0c7c7080f..0c41fb1762 100644
--- a/ir_reader.cpp
+++ b/ir_reader.cpp
@@ -30,9 +30,12 @@
static void ir_read_error(s_expression *expr, const char *fmt, ...);
static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
+static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
+ s_expression *);
static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
s_expression *);
static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
+static ir_if *read_if(_mesa_glsl_parse_state *, s_list *);
static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
@@ -60,24 +63,7 @@ _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
_mesa_glsl_initialize_constructors(instructions, state);
_mesa_glsl_initialize_functions(instructions, state);
- // Read in a list of instructions
- s_list *list = SX_AS_LIST(expr);
- if (list == NULL) {
- ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
- state->error = true;
- return;
- }
-
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
- s_expression *sub = (s_expression*) it.get();
- ir_instruction *ir = read_instruction(state, sub);
- if (ir == NULL) {
- ir_read_error(sub, "Invalid instruction.\n");
- state->error = true;
- return;
- }
- instructions->push_tail(ir);
- }
+ read_instructions(state, instructions, expr);
}
static void
@@ -152,6 +138,31 @@ read_type(_mesa_glsl_parse_state *st, s_expression *expr)
}
+static void
+read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
+ s_expression *expr)
+{
+ // Read in a list of instructions
+ s_list *list = SX_AS_LIST(expr);
+ if (list == NULL) {
+ ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
+ st->error = true;
+ return;
+ }
+
+ foreach_iter(exec_list_iterator, it, list->subexpressions) {
+ s_expression *sub = (s_expression*) it.get();
+ ir_instruction *ir = read_instruction(st, sub);
+ if (ir == NULL) {
+ ir_read_error(sub, "Invalid instruction.\n");
+ st->error = true;
+ return;
+ }
+ instructions->push_tail(ir);
+ }
+}
+
+
static ir_instruction *
read_instruction(_mesa_glsl_parse_state *st, s_expression *expr)
{
@@ -168,6 +179,8 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr)
ir_instruction *inst = NULL;
if (strcmp(tag->value(), "declare") == 0)
inst = read_declaration(st, list);
+ else if (strcmp(tag->value(), "if") == 0)
+ inst = read_if(st, list);
else if (strcmp(tag->value(), "return") == 0)
inst = read_return(st, list);
else
@@ -247,6 +260,37 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)
}
+static ir_if *
+read_if(_mesa_glsl_parse_state *st, s_list *list)
+{
+ if (list->length() != 4) {
+ ir_read_error(list, "expected (if <condition> (<then> ...) "
+ "(<else> ...))");
+ return NULL;
+ }
+
+ s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
+ ir_rvalue *condition = read_rvalue(st, cond_expr);
+ if (condition == NULL) {
+ ir_read_error(list, "when reading condition of (if ...)");
+ return NULL;
+ }
+
+ s_expression *then_expr = (s_expression*) cond_expr->next;
+ s_expression *else_expr = (s_expression*) then_expr->next;
+
+ ir_if *iff = new ir_if(condition);
+
+ read_instructions(st, &iff->then_instructions, then_expr);
+ read_instructions(st, &iff->else_instructions, else_expr);
+ if (st->error) {
+ delete iff;
+ iff = NULL;
+ }
+ return iff;
+}
+
+
static ir_return *
read_return(_mesa_glsl_parse_state *st, s_list *list)
{