summaryrefslogtreecommitdiff
path: root/ir_reader.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-04-12 14:27:39 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-28 18:14:54 -0700
commit451381c220f145ac27a177c955dde30a9618fd00 (patch)
treeb19f59bc119096c769ee49a8e7fd95c35a550b0b /ir_reader.cpp
parent46ef8f19d76b33446c2ce6e7f1379bd348fe7fe4 (diff)
ir_reader: Add support for reading (var_ref ...) and (array_ref ...)
Diffstat (limited to 'ir_reader.cpp')
-rw-r--r--ir_reader.cpp85
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;
+}