diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2010-04-12 14:27:39 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-04-28 18:14:54 -0700 |
commit | 451381c220f145ac27a177c955dde30a9618fd00 (patch) | |
tree | b19f59bc119096c769ee49a8e7fd95c35a550b0b /ir_reader.cpp | |
parent | 46ef8f19d76b33446c2ce6e7f1379bd348fe7fe4 (diff) |
ir_reader: Add support for reading (var_ref ...) and (array_ref ...)
Diffstat (limited to 'ir_reader.cpp')
-rw-r--r-- | ir_reader.cpp | 85 |
1 files changed, 79 insertions, 6 deletions
diff --git a/ir_reader.cpp b/ir_reader.cpp index 9eadce2119..ee849a8c91 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -43,6 +43,9 @@ static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *); static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *); static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *); static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_array_ref(_mesa_glsl_parse_state *, s_list *); +static ir_dereference *read_record_ref(_mesa_glsl_parse_state *, s_list *); void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, @@ -327,18 +330,24 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) } ir_rvalue *rvalue = NULL; - if (strcmp(tag->value(), "swiz") == 0) + if (strcmp(tag->value(), "swiz") == 0) { rvalue = read_swizzle(st, list); - else if (strcmp(tag->value(), "assign") == 0) + } else if (strcmp(tag->value(), "assign") == 0) { rvalue = read_assignment(st, list); - else if (strcmp(tag->value(), "expression") == 0) + } else if (strcmp(tag->value(), "expression") == 0) { rvalue = read_expression(st, list); // FINISHME: ir_call - // FINISHME: dereference - else if (strcmp(tag->value(), "constant") == 0) + } else if (strcmp(tag->value(), "constant") == 0) { rvalue = read_constant(st, list); - else + } else if (strcmp(tag->value(), "var_ref") == 0) { + rvalue = read_var_ref(st, list); + } else if (strcmp(tag->value(), "array_ref") == 0) { + rvalue = read_array_ref(st, list); + } else if (strcmp(tag->value(), "record_ref") == 0) { + rvalue = read_record_ref(st, list); + } else { ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value()); + } return rvalue; } @@ -557,3 +566,67 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list) } return NULL; // should not be reached } + +static ir_instruction * +read_dereferencable(_mesa_glsl_parse_state *st, s_expression *expr) +{ + // Read the subject of a dereference - either a variable name or a swizzle + s_symbol *var_name = SX_AS_SYMBOL(expr); + if (var_name != NULL) { + ir_variable *var = st->symbols->get_variable(var_name->value()); + if (var == NULL) { + ir_read_error(expr, "undeclared variable: %s", var_name->value()); + } + return var; + } else { + // Hopefully a (swiz ...) + s_list *list = SX_AS_LIST(expr); + if (list != NULL && !list->subexpressions.is_empty()) { + s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head); + if (tag != NULL && strcmp(tag->value(), "swiz") == 0) + return read_swizzle(st, list); + } + } + ir_read_error(expr, "expected variable name or (swiz ...)"); + return NULL; +} + +static ir_dereference * +read_var_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + if (list->length() != 2) { + ir_read_error(list, "expected (var_ref <variable name or (swiz)>)"); + return NULL; + } + s_expression *subj_expr = (s_expression*) list->subexpressions.head->next; + ir_instruction *subject = read_dereferencable(st, subj_expr); + if (subject == NULL) + return NULL; + return new ir_dereference(subject); +} + +static ir_dereference * +read_array_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + if (list->length() != 3) { + ir_read_error(list, "expected (array_ref <variable name or (swiz)> " + "<rvalue>)"); + return NULL; + } + + s_expression *subj_expr = (s_expression*) list->subexpressions.head->next; + ir_instruction *subject = read_dereferencable(st, subj_expr); + if (subject == NULL) + return NULL; + + s_expression *idx_expr = (s_expression*) subj_expr->next; + ir_rvalue *idx = read_rvalue(st, idx_expr); + return new ir_dereference(subject, idx); +} + +static ir_dereference * +read_record_ref(_mesa_glsl_parse_state *st, s_list *list) +{ + ir_read_error(list, "FINISHME: record refs not yet supported."); + return NULL; +} |