summaryrefslogtreecommitdiff
path: root/ir_reader.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2010-04-21 18:14:06 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-28 18:14:54 -0700
commit8df335d7f9ab8b3699c312f2b4b42be2e8eeba27 (patch)
tree3516c65e0230d0e9db171eafb93af355d7945e8e /ir_reader.cpp
parent09cad1339d8e6eebe5b13d95a9e1d2a1da2fce29 (diff)
ir_reader: Preliminary work toward reading functions.
Diffstat (limited to 'ir_reader.cpp')
-rw-r--r--ir_reader.cpp61
1 files changed, 36 insertions, 25 deletions
diff --git a/ir_reader.cpp b/ir_reader.cpp
index e14f5c8..44fbb33 100644
--- a/ir_reader.cpp
+++ b/ir_reader.cpp
@@ -33,9 +33,10 @@ static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
s_expression *);
-static void read_prototypes(_mesa_glsl_parse_state *, exec_list *, s_list *);
-static ir_function_signature *read_prototype(_mesa_glsl_parse_state *,
- s_list *);
+static ir_function *read_function(_mesa_glsl_parse_state *, s_list *,
+ bool skip_body);
+static ir_function_signature *read_function_sig(_mesa_glsl_parse_state *,
+ s_list *, bool skip_body);
static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
s_expression *, ir_loop *);
@@ -175,36 +176,34 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
if (tag == NULL || strcmp(tag->value(), "function") != 0)
continue; // not a (function ...); ignore it.
- read_prototypes(st, instructions, sub);
- if (st->error)
+ ir_function *f = read_function(st, sub, true);
+ if (f == NULL)
return;
+ instructions->push_tail(f);
}
}
-static void
-read_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
- s_list *list)
+static ir_function *
+read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
{
if (list->length() < 3) {
ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
- return;
+ return NULL;
}
s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
if (name == NULL) {
ir_read_error(st, list, "Expected (function <name> ...)");
- return;
+ return NULL;
}
- ir_function *f = new ir_function(name->value());
- bool added = st->symbols->add_function(name->value(), f);
- if (!added) {
- ir_read_error(st, list, "Function %s already exists.", name->value());
- return;
+ ir_function *f = st->symbols->get_function(name->value());
+ if (f == NULL) {
+ f = new ir_function(name->value());
+ bool added = st->symbols->add_function(name->value(), f);
+ assert(added);
}
- instructions->push_tail(f);
-
exec_list_iterator it = list->subexpressions.iterator();
it.next(); // skip "function" tag
it.next(); // skip function name
@@ -212,25 +211,26 @@ read_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
s_list *siglist = SX_AS_LIST(it.get());
if (siglist == NULL) {
ir_read_error(st, list, "Expected (function (signature ...) ...)");
- return;
+ return NULL;
}
s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
ir_read_error(st, siglist, "Expected (signature ...)");
- return;
+ return NULL;
}
- ir_function_signature *sig = read_prototype(st, siglist);
+ ir_function_signature *sig = read_function_sig(st, siglist, skip_body);
if (sig == NULL)
- return;
+ return NULL;
f->add_signature(sig);
}
+ return f;
}
static ir_function_signature *
-read_prototype(_mesa_glsl_parse_state *st, s_list *list)
+read_function_sig(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
{
if (list->length() != 4) {
ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
@@ -244,9 +244,10 @@ read_prototype(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
s_list *paramlist = SX_AS_LIST(type_expr->next);
- if (paramlist == NULL) {
- ir_read_error(st, list, "Expected (signature %s (parameters ...) ...)",
- return_type->name);
+ s_list *body_list = SX_AS_LIST(paramlist->next);
+ if (paramlist == NULL || body_list == NULL) {
+ ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
+ "(<instruction> ...))");
return NULL;
}
s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
@@ -255,8 +256,11 @@ read_prototype(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
+ // FINISHME: Don't create a new one! Look for the existing prototype first
ir_function_signature *sig = new ir_function_signature(return_type);
+ st->symbols->push_scope();
+
exec_list_iterator it = paramlist->subexpressions.iterator();
for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
s_list *decl = SX_AS_LIST(it.get());
@@ -269,6 +273,11 @@ read_prototype(_mesa_glsl_parse_state *st, s_list *list)
sig->parameters.push_tail(var);
}
+ if (!skip_body)
+ read_instructions(st, &sig->body, body_list, NULL);
+
+ st->symbols->pop_scope();
+
return sig;
}
@@ -326,6 +335,8 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
inst = read_loop(st, list);
} else if (strcmp(tag->value(), "return") == 0) {
inst = read_return(st, list);
+ } else if (strcmp(tag->value(), "function") == 0) {
+ inst = read_function(st, list, false);
} else {
inst = read_rvalue(st, list);
if (inst == NULL)