diff options
Diffstat (limited to 'ir_reader.cpp')
-rw-r--r-- | ir_reader.cpp | 80 |
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) { |