Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but 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
Werner Almesberger 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
Werner Almesberger 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
Werner Almesberger 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
Werner Almesberger wpwrak compiler/parser.y: suppress "unused variable 'state'" warning 3ec9fde
Werner Almesberger 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
1  src/Makefile
View
@@ -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
11 src/compiler/compiler.c
View
@@ -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;
18 src/compiler/fpvm.c
View
@@ -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);
+}
2  src/compiler/fpvm.h
View
@@ -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 */
29 src/compiler/parser.y
View
@@ -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). {
22 src/compiler/parser_helper.c
View
@@ -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)
9 src/compiler/parser_helper.h
View
@@ -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 */
13 src/compiler/parser_itf.h
View
@@ -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 */
3  src/compiler/scanner.re
View
@@ -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; }
*/
}
16 src/compiler/unique.c
View
@@ -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.