This patch prepares the scanner and parser for directly processing
assignments. For this, the grammar is extended to include the
assignment operation (without fragment prefix), the communication
path into the parser is widened (from the parseout pointer to a
union), and error indication is slightly modified.
Note that error handling is still largely dysfunctional and will
need more work in the future.
---
src/compiler/fpvm.c | 17 ++++++++++++-----
src/compiler/fpvm.h | 2 ++
src/compiler/parser.y | 24 +++++++++++++++++++-----
src/compiler/parser_helper.c | 22 ++++++++++++----------
src/compiler/parser_helper.h | 9 ++++++++-
src/compiler/parser_itf.h | 13 ++++++++++++-
src/compiler/scanner.re | 3 ++-
7 files changed, 67 insertions(+), 23 deletions(-)
diff --git a/src/compiler/fpvm.c b/src/compiler/fpvm.c
index a6c3440..b6b75d6 100644
--- a/src/compiler/fpvm.c
+++ b/src/compiler/fpvm.c
@@ -45,19 +45,26 @@ void fpvm_init(struct fpvm_fragment *fragment, int
vector_mode)
int fpvm_assign(struct fpvm_fragment *fragment, const char *dest,
const char *expr)
{
- struct ast_node *n;
+ union parser_comm comm;
int res;
- n = fpvm_parse(expr, TOK_START_EXPR);
- if(n == NULL) {
+ if (!fpvm_parse(expr, TOK_START_EXPR, &comm)) {
snprintf(fragment->last_error, FPVM_MAXERRLEN, "Parse error");
return 0;
}
dest = unique(dest);
- res = fpvm_do_assign(fragment, dest, n);
- fpvm_parse_free(n);
+ res = fpvm_do_assign(fragment, dest, comm.parseout);
+ fpvm_parse_free(comm.parseout);
return res;
}
+
+
+int fpvm_chunk(struct fpvm_fragment *fragment, const char *chunk)
+{
+ union parser_comm comm = { .fragment = fragment };
+
+ return fpvm_parse(chunk, TOK_START_ASSIGN, &comm);
+}
diff --git a/src/compiler/fpvm.h b/src/compiler/fpvm.h
index 0a63d54..8a5aa5f 100644
--- a/src/compiler/fpvm.h
+++ b/src/compiler/fpvm.h
@@ -32,4 +32,6 @@ void fpvm_init(struct fpvm_fragment *fragment, int
vector_mode);
int fpvm_assign(struct fpvm_fragment *fragment, const char *dest,
const char *expr);
+int fpvm_chunk(struct fpvm_fragment *fragment, const char *chunk);
+
#endif /* __FPVM_H */
diff --git a/src/compiler/parser.y b/src/compiler/parser.y
index ca00e44..c7614ec 100644
--- a/src/compiler/parser.y
+++ b/src/compiler/parser.y
@@ -22,7 +22,9 @@
#include <malloc.h>
#include <math.h>
#include "fpvm/ast.h"
+ #include "fpvm/fpvm.h"
#include "parser_itf.h"
+ #include "parser_helper.h"
#include "parser.h"
@@ -73,18 +75,30 @@
}
%start_symbol start
-%extra_argument {struct ast_node **parseout}
+%extra_argument {struct parser_state *state}
%token_type {struct id *}
%token_destructor { free($$); }
-%type start {struct ast_node *}
%type node {struct ast_node *}
%destructor node { free($$); }
-start(S) ::= TOK_START_EXPR node(N). {
- S = N;
- *parseout = S;
+start ::= TOK_START_EXPR node(N). {
+ state->comm->parseout = N;
+ state->success = 1;
+}
+
+start ::= TOK_START_ASSIGN assignments. {
+ state->success = 1;
+}
+
+assignments ::= assignments assignment.
+
+assignments ::= .
+
+assignment ::= ident(I) TOK_ASSIGN node(N). {
+ fpvm_do_assign(state->comm->fragment, I->label, N);
+ fpvm_parse_free(N);
}
node(N) ::= TOK_CONSTANT(C). {
diff --git a/src/compiler/parser_helper.c b/src/compiler/parser_helper.c
index 86e4906..c5762db 100644
--- a/src/compiler/parser_helper.c
+++ b/src/compiler/parser_helper.c
@@ -24,18 +24,20 @@
#include "parser_itf.h"
#include "parser_helper.h"
-struct ast_node *fpvm_parse(const char *expr, int start_token)
+int fpvm_parse(const char *expr, int start_token, union parser_comm *comm)
{
struct scanner *s;
+ struct parser_state state = {
+ .comm = comm,
+ .success = 0,
+ };
int tok;
struct id *identifier;
void *p;
- struct ast_node *ast;
s = new_scanner((unsigned char *)expr);
p = ParseAlloc(malloc);
- Parse(p, start_token, NULL, &ast);
- ast = NULL;
+ Parse(p, start_token, NULL, &state);
tok = scan(s);
while(tok != TOK_EOF) {
identifier = malloc(sizeof(struct id));
@@ -46,25 +48,25 @@ struct ast_node *fpvm_parse(const char *expr, int
start_token)
} else {
identifier->label = get_token(s);
}
- Parse(p, tok, identifier, &ast);
+ Parse(p, tok, identifier, &state);
if(tok == TOK_ERROR) {
printf("FPVM: scan error\n");
ParseFree(p, free);
delete_scanner(s);
- return NULL;
+ return 0;
}
tok = scan(s);
}
- Parse(p, TOK_EOF, NULL, &ast);
+ Parse(p, TOK_EOF, NULL, &state);
ParseFree(p, free);
delete_scanner(s);
- if(ast == NULL) {
+ if(!state.success) {
printf("FPVM: parse error\n");
- return NULL;
+ return 0;
}
- return ast;
+ return state.success;
}
void fpvm_parse_free(struct ast_node *node)
diff --git a/src/compiler/parser_helper.h b/src/compiler/parser_helper.h
index 5915f7f..b4e72d5 100644
--- a/src/compiler/parser_helper.h
+++ b/src/compiler/parser_helper.h
@@ -19,8 +19,15 @@
#define __PARSER_HELPER_H
#include <fpvm/ast.h>
+#include <fpvm/fpvm.h>
-struct ast_node *fpvm_parse(const char *expr, int start_token);
+union parser_comm {
+ struct ast_node *parseout;
+ struct fpvm_fragment *fragment;
+};
+
+int fpvm_parse(const char *expr, int start_token,
+ union 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 895da5f..f36aab8 100644
--- a/src/compiler/parser_itf.h
+++ b/src/compiler/parser_itf.h
@@ -18,6 +18,11 @@
#ifndef __PARSER_ITF_H
#define __PARSER_ITF_H
+#include <fpvm/fpvm.h>
+
+#include "parser_helper.h"
+
+
#define NDEBUG
struct id {
@@ -26,8 +31,14 @@ struct id {
float constant;
};
+struct parser_state {
+ int success;
+ union parser_comm *comm;
+};
+
void *ParseAlloc(void *(*mallocProc)(size_t));
void ParseFree(void *p, void (*freeProc)(void*));
-void Parse(void *yyp, int yymajor, struct id *yyminor, struct ast_node **p);
+void Parse(void *yyp, int yymajor, struct id *yyminor,
+ struct parser_state *state);
#endif /* __PARSER_ITF_H */
diff --git a/src/compiler/scanner.re b/src/compiler/scanner.re
index 1362ab4..a267730 100644
--- a/src/compiler/scanner.re
+++ b/src/compiler/scanner.re
@@ -57,7 +57,7 @@ int scan(struct scanner *s)
s->old_cursor = s->cursor;
/*!re2c
- [\x20\r\t] { goto std; }
+ [\x20\n\r\t] { goto std; }
[0-9]+ { return TOK_CONSTANT; }
[0-9]* "." [0-9]* { return TOK_CONSTANT; }
@@ -90,6 +90,7 @@ int scan(struct scanner *s)
"(" { return TOK_LPAREN; }
")" { return TOK_RPAREN; }
"," { return TOK_COMMA; }
+ "=" { return TOK_ASSIGN; }
[\x00-\xff] { return TOK_ERROR; }
*/
}
--
1.7.1
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode