Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: m-labs/flickernoise
base: 63ef1c2
...
head fork: m-labs/flickernoise
compare: d1bdf36
  • 5 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
Commits on Dec 12, 2011
@wpwrak wpwrak compiler/: introduce parser start state
We can use this later for step-wise migration towards a parser that
handles the complete patch, not just an expression at a time.
fe680b4
@wpwrak wpwrak compiler: directly process assignments
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.
e20654f
@wpwrak wpwrak compiler: make init_pvv use assignments in FNP notation, as a proof o…
…f concept

This patch converts init_pvv from using fpvm_assign to using a string
that contains assignment to be handled by the parser. This is strictly
a proof of concept, since manually embedding code this way is ugly.
3fc3cee
@wpwrak wpwrak compiler/parser.y: suppress "unused variable 'state'" warning 3ec9fde
@wpwrak wpwrak compiler/unique.c: introduce function isid(), mainly to get rid of wa…
…rnings

The isalpha() in newlib triggers a gcc warning if used with a char as
input. One way to work around this is to simply pass an int, which is
how POSIX defines isalpha anyway.
d1bdf36
View
1  src/Makefile
@@ -88,6 +88,7 @@ bandfilters.h: bandfilters.sce
compiler/parser.h: compiler/parser.c
obj/compiler/scanner.o: compiler/parser.h
obj/compiler/parser_helper.o: compiler/parser.h
+obj/compiler/fpvm.o: compiler/parser.h
obj/compiler/unique.o: compiler/fnp.inc
# boot images for Milkymist One
View
11 src/compiler/compiler.c
@@ -443,13 +443,12 @@ static bool init_pvv(struct compiler_sc *sc)
fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
- #define A(dest, val) \
- if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
- A("x", "i2f(_Xi)*_hmeshsize");
- A("y", "i2f(_Yi)*_vmeshsize");
- A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
+ if(!fpvm_chunk(&sc->pvv_fragment,
+ "x = i2f(_Xi)*_hmeshsize\n"
+ "y = i2f(_Yi)*_vmeshsize\n"
+ "rad = sqrt(sqr(x-0.5)+sqr(y-0.5))"))
+ goto fail_assign;
/* TODO: generate ang */
- #undef A
fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_ALL);
return true;
View
18 src/compiler/fpvm.c
@@ -21,6 +21,7 @@
#include <fpvm/ast.h>
#include "unique.h"
+#include "parser.h"
#include "parser_helper.h"
#include "fpvm.h"
@@ -44,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);
- 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);
+}
View
2  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 */
View
29 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,33 @@
}
%start_symbol start
-%extra_argument {struct ast_node **parseout}
+%extra_argument {struct parser_state *state}
%token_type {struct id *}
-%token_destructor { free($$); }
+%token_destructor {
+ free($$);
+ (void) state; /* suppress unused variable warning */
+}
-%type start {struct ast_node *}
%type node {struct ast_node *}
%destructor node { free($$); }
-start(S) ::= 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). {
View
22 src/compiler/parser_helper.c
@@ -20,20 +20,24 @@
#include <fpvm/ast.h>
#include "scanner.h"
+#include "parser.h"
#include "parser_itf.h"
#include "parser_helper.h"
-struct ast_node *fpvm_parse(const char *expr)
+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);
- ast = NULL;
p = ParseAlloc(malloc);
+ Parse(p, start_token, NULL, &state);
tok = scan(s);
while(tok != TOK_EOF) {
identifier = malloc(sizeof(struct id));
@@ -44,25 +48,25 @@ struct ast_node *fpvm_parse(const char *expr)
} 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)
View
9 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);
+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 */
View
13 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 */
View
3  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; }
*/
}
View
16 src/compiler/unique.c
@@ -84,12 +84,24 @@ static int cmp_n(const void *a, const void *b)
}
+/*
+ * "isid" is not only a minor convenient enhancement, but it also shields us
+ * from implementations of isalpha() that trigger compiler warnings if "c" is
+ * a character.
+ */
+
+static int isid(int c)
+{
+ return isalpha(c) || c == '_';
+}
+
+
const char *unique(const char *s)
{
const char **res;
const char **walk;
- if(!isalnum(*s) && *s != '_')
+ if(!isid(*s))
return s;
res = bsearch(s, well_known, sizeof(well_known)/sizeof(*well_known),
sizeof(s), cmp);
@@ -112,7 +124,7 @@ const char *unique_n(const char *s, int n)
const char **res;
const char **walk;
- if(!isalnum(*s) && *s != '_')
+ if(!isid(*s))
return s;
res = bsearch(&key, well_known, sizeof(well_known)/sizeof(*well_known),
sizeof(s), cmp_n);

No commit comments for this range

Something went wrong with that request. Please try again.