There are two changes:
- instead of calling fpvm_do_assign directly, use a callback
- support for pre_frame, per_vertex, and per_pixel prefixes
---
src/compiler/fpvm.c | 31 +++++++++++++++++++++++++++----
src/compiler/parser.y | 31 ++++++++++++++++++++++++++-----
src/compiler/parser_helper.c | 2 +-
src/compiler/parser_helper.h | 16 ++++++++++++----
src/compiler/parser_itf.h | 2 +-
src/compiler/ptest/ptest.c | 30 ++++++++++++++++++++----------
src/compiler/scanner.re | 4 ++++
src/compiler/test/prefix | 33 +++++++++++++++++++++++++++++++++
8 files changed, 124 insertions(+), 25 deletions(-)
create mode 100755 src/compiler/test/prefix
diff --git a/src/compiler/fpvm.c b/src/compiler/fpvm.c
index 3bdd701..fa1187d 100644
--- a/src/compiler/fpvm.c
+++ b/src/compiler/fpvm.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <fpvm/fpvm.h>
#include <fpvm/ast.h>
@@ -46,7 +47,7 @@ void fpvm_init(struct fpvm_fragment *fragment, int
vector_mode)
int fpvm_assign(struct fpvm_fragment *fragment, const char *dest,
const char *expr)
{
- union parser_comm comm;
+ struct parser_comm comm;
const char *error;
int res;
@@ -59,16 +60,38 @@ int fpvm_assign(struct fpvm_fragment *fragment, const char
*dest,
dest = unique(dest);
- res = fpvm_do_assign(fragment, dest, comm.parseout);
- fpvm_parse_free(comm.parseout);
+ res = fpvm_do_assign(fragment, dest, comm.u.parseout);
+ fpvm_parse_free(comm.u.parseout);
return res;
}
+static const char *assign_default(struct parser_comm *comm,
+ const char *label, struct ast_node *node)
+{
+ if(fpvm_do_assign(comm->u.fragment, label, node))
+ return NULL;
+ else
+ return strdup(fpvm_get_last_error(comm->u.fragment));
+}
+
+
+static const char *assign_unsupported(struct parser_comm *comm,
+ const char *label, struct ast_node *node)
+{
+ return strdup("assignment mode not supported yet");
+}
+
+
int fpvm_chunk(struct fpvm_fragment *fragment, const char *chunk)
{
- union parser_comm comm = { .fragment = fragment };
+ struct parser_comm comm = {
+ .u.fragment = fragment,
+ .assign_default = assign_default,
+ .assign_per_frame = assign_unsupported,
+ .assign_per_vertex = assign_unsupported,
+ };
const char *error;
error = fpvm_parse(chunk, TOK_START_ASSIGN, &comm);
diff --git a/src/compiler/parser.y b/src/compiler/parser.y
index 2875fd5..6363cc6 100644
--- a/src/compiler/parser.y
+++ b/src/compiler/parser.y
@@ -31,6 +31,9 @@
struct yyParser;
static void yy_parse_failed(struct yyParser *yypParser);
+ typedef const char *(*assign_callback)(struct parser_comm *comm,
+ const char *label, struct ast_node *node);
+
const enum ast_op tok2op[] = {
[TOK_IDENT] = op_ident,
[TOK_CONSTANT] = op_constant,
@@ -95,13 +98,16 @@
%type node {struct ast_node *}
%destructor node { free($$); }
+
+%type context {assign_callback}
+
%syntax_error {
syntax_error(state);
yy_parse_failed(yypParser);
}
start ::= TOK_START_EXPR node(N). {
- state->comm->parseout = N;
+ state->comm->u.parseout = N;
state->success = 1;
}
@@ -113,10 +119,9 @@ assignments ::= assignments assignment.
assignments ::= .
-assignment ::= ident(I) TOK_ASSIGN node(N) opt_semi. {
- if(!fpvm_do_assign(state->comm->fragment, I->label, N)) {
- state->error =
- strdup(fpvm_get_last_error(state->comm->fragment));
+assignment ::= context(C) ident(I) TOK_ASSIGN node(N) opt_semi. {
+ state->error = C(state->comm, I->label, N);
+ if(state->error) {
syntax_error(state);
yy_parse_failed(yypParser);
return;
@@ -124,6 +129,22 @@ assignment ::= ident(I) TOK_ASSIGN node(N) opt_semi. {
fpvm_parse_free(N);
}
+context(C) ::= . {
+ C = state->comm->assign_default;
+}
+
+context(C) ::= TOK_PER_FRAME TOK_ASSIGN. {
+ C = state->comm->assign_per_frame;
+}
+
+context(C) ::= TOK_PER_VERTEX TOK_ASSIGN. {
+ C = state->comm->assign_per_vertex;
+}
+
+context(C) ::= TOK_PER_PIXEL TOK_ASSIGN. {
+ C = state->comm->assign_per_vertex;
+}
+
opt_semi ::= opt_semi TOK_SEMI.
opt_semi ::= .
diff --git a/src/compiler/parser_helper.c b/src/compiler/parser_helper.c
index 4976e85..a7824a0 100644
--- a/src/compiler/parser_helper.c
+++ b/src/compiler/parser_helper.c
@@ -64,7 +64,7 @@ static const char *alloc_printf(const char *fmt, ...)
}
const char *fpvm_parse(const char *expr, int start_token,
- union parser_comm *comm)
+ struct parser_comm *comm)
{
struct scanner *s;
struct parser_state state = {
diff --git a/src/compiler/parser_helper.h b/src/compiler/parser_helper.h
index 8b4babe..a139da2 100644
--- a/src/compiler/parser_helper.h
+++ b/src/compiler/parser_helper.h
@@ -21,13 +21,21 @@
#include <fpvm/ast.h>
#include <fpvm/fpvm.h>
-union parser_comm {
- struct ast_node *parseout;
- struct fpvm_fragment *fragment;
+struct parser_comm {
+ union {
+ struct ast_node *parseout;
+ struct fpvm_fragment *fragment;
+ } u;
+ const char *(*assign_default)(struct parser_comm *comm,
+ const char *label, struct ast_node *node);
+ const char *(*assign_per_frame)(struct parser_comm *comm,
+ const char *label, struct ast_node *node);
+ const char *(*assign_per_vertex)(struct parser_comm *comm,
+ const char *label, struct ast_node *node);
};
const char *fpvm_parse(const char *expr, int start_token,
- union parser_comm *comm);
+ struct parser_comm *comm);
void fpvm_parse_free(struct ast_node *node);
#endif /* __PARSER_HELPER_H */
diff --git a/src/compiler/parser_itf.h b/src/compiler/parser_itf.h
index 57c84c1..a3cd934 100644
--- a/src/compiler/parser_itf.h
+++ b/src/compiler/parser_itf.h
@@ -34,7 +34,7 @@ struct id {
struct parser_state {
int success;
- union parser_comm *comm;
+ struct parser_comm *comm;
const char *error; /* malloc'ed error message or NULL */
const char *error_label;/* details about the failing token */
int error_lineno;
diff --git a/src/compiler/ptest/ptest.c b/src/compiler/ptest/ptest.c
index c89fc68..7a005f5 100644
--- a/src/compiler/ptest/ptest.c
+++ b/src/compiler/ptest/ptest.c
@@ -141,19 +141,24 @@ const char *fpvm_get_last_error(struct fpvm_fragment
*fragment)
}
-int fpvm_do_assign(struct fpvm_fragment *fragment, const char *dest,
- struct ast_node *ast)
+static const char *assign_default(struct parser_comm *comm,
+ const char *label, struct ast_node *node)
{
- if (fail) {
- snprintf(fragment->last_error, FPVM_MAXERRLEN, "%s", fail);
- return 0;
- }
+ if (fail)
+ return strdup(fail);
if (!quiet) {
- printf("%s = ", dest);
- dump_ast(ast);
+ printf("%s = ", label);
+ dump_ast(node);
putchar('\n');
}
- return 1;
+ return NULL;
+}
+
+
+static const char *assign_unsupported(struct parser_comm *comm,
+ const char *label, struct ast_node *node)
+{
+ return strdup("assignment mode not supported yet");
}
@@ -199,7 +204,12 @@ int main(int argc, char **argv)
int c;
const char *buf;
struct fpvm_fragment fragment;
- union parser_comm comm = { .fragment = &fragment };
+ struct parser_comm comm = {
+ .u.fragment = &fragment,
+ .assign_default = assign_default,
+ .assign_per_frame = assign_unsupported,
+ .assign_per_vertex = assign_unsupported,
+ };
const char *error;
while ((c = getopt(argc, argv, "f:q")) != EOF)
diff --git a/src/compiler/scanner.re b/src/compiler/scanner.re
index af15c18..60e0fca 100644
--- a/src/compiler/scanner.re
+++ b/src/compiler/scanner.re
@@ -109,6 +109,10 @@ int scan(struct scanner *s)
"sqrt" { return TOK_SQRT; }
"tsign" { return TOK_TSIGN; }
+ "per_frame" { return TOK_PER_FRAME; }
+ "per_vertex" { return TOK_PER_VERTEX; }
+ "per_pixel" { return TOK_PER_PIXEL; }
+
[a-zA-Z_0-9]+ { return TOK_IDENT; }
"+" { return TOK_PLUS; }
diff --git a/src/compiler/test/prefix b/src/compiler/test/prefix
new file mode 100755
index 0000000..518764a
--- /dev/null
+++ b/src/compiler/test/prefix
@@ -0,0 +1,33 @@
+#!/bin/sh
+. ./Common
+
+# WORK IN PROGRESS
+
+###############################################################################
+
+ptest_fail "prefix: per_frame=x = a+b" <<EOF
+per_frame=x = a+b
+EOF
+expect <<EOF
+FPVM, line 1, near "b": assignment mode not supported yet
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "prefix: per_vertex= x = a+b" <<EOF
+per_vertex = x = a+b
+EOF
+expect <<EOF
+FPVM, line 1, near "b": assignment mode not supported yet
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "prefix: per_pixel=x = a+b" <<EOF
+per_pixel=x = a+b
+EOF
+expect <<EOF
+FPVM, line 1, near "b": assignment mode not supported yet
+EOF
+
+###############################################################################
--
1.7.1
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode