Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 10 files changed
  • 0 comments
  • 1 contributor
Dec 12, 2011
Werner Almesberger 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 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 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 compiler/parser.y: suppress "unused variable 'state'" warning 3ec9fde
Werner Almesberger 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
@@ -88,6 +88,7 @@ bandfilters.h: bandfilters.sce
88 88
 compiler/parser.h: compiler/parser.c
89 89
 obj/compiler/scanner.o: compiler/parser.h
90 90
 obj/compiler/parser_helper.o: compiler/parser.h
  91
+obj/compiler/fpvm.o: compiler/parser.h
91 92
 obj/compiler/unique.o: compiler/fnp.inc
92 93
 
93 94
 # boot images for Milkymist One
11  src/compiler/compiler.c
@@ -443,13 +443,12 @@ static bool init_pvv(struct compiler_sc *sc)
443 443
 	fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
444 444
 
445 445
 	fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
446  
-	#define A(dest, val) \
447  
-	    if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
448  
-	A("x", "i2f(_Xi)*_hmeshsize");
449  
-	A("y", "i2f(_Yi)*_vmeshsize");
450  
-	A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
  446
+	if(!fpvm_chunk(&sc->pvv_fragment,
  447
+	    "x = i2f(_Xi)*_hmeshsize\n"
  448
+	    "y = i2f(_Yi)*_vmeshsize\n"
  449
+	    "rad = sqrt(sqr(x-0.5)+sqr(y-0.5))"))
  450
+		goto fail_assign;
451 451
 	/* TODO: generate ang */
452  
-	#undef A
453 452
 	fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_ALL);
454 453
 
455 454
 	return true;
18  src/compiler/fpvm.c
@@ -21,6 +21,7 @@
21 21
 #include <fpvm/ast.h>
22 22
 
23 23
 #include "unique.h"
  24
+#include "parser.h"
24 25
 #include "parser_helper.h"
25 26
 #include "fpvm.h"
26 27
 
@@ -44,19 +45,26 @@ void fpvm_init(struct fpvm_fragment *fragment, int vector_mode)
44 45
 int fpvm_assign(struct fpvm_fragment *fragment, const char *dest,
45 46
     const char *expr)
46 47
 {
47  
-	struct ast_node *n;
  48
+	union parser_comm comm;
48 49
 	int res;
49 50
 
50  
-	n = fpvm_parse(expr);
51  
-	if(n == NULL) {
  51
+	if (!fpvm_parse(expr, TOK_START_EXPR, &comm)) {
52 52
 		snprintf(fragment->last_error, FPVM_MAXERRLEN, "Parse error");
53 53
 		return 0;
54 54
 	}
55 55
 
56 56
 	dest = unique(dest);
57 57
 
58  
-	res = fpvm_do_assign(fragment, dest, n);
59  
-	fpvm_parse_free(n);
  58
+	res = fpvm_do_assign(fragment, dest, comm.parseout);
  59
+	fpvm_parse_free(comm.parseout);
60 60
 
61 61
 	return res;
62 62
 }
  63
+
  64
+
  65
+int fpvm_chunk(struct fpvm_fragment *fragment, const char *chunk)
  66
+{
  67
+	union parser_comm comm = { .fragment = fragment };
  68
+
  69
+	return fpvm_parse(chunk, TOK_START_ASSIGN, &comm);
  70
+}
2  src/compiler/fpvm.h
@@ -32,4 +32,6 @@ void fpvm_init(struct fpvm_fragment *fragment, int vector_mode);
32 32
 int fpvm_assign(struct fpvm_fragment *fragment, const char *dest,
33 33
     const char *expr);
34 34
 
  35
+int fpvm_chunk(struct fpvm_fragment *fragment, const char *chunk);
  36
+
35 37
 #endif /* __FPVM_H */
29  src/compiler/parser.y
@@ -22,7 +22,9 @@
22 22
 	#include <malloc.h>
23 23
 	#include <math.h>
24 24
 	#include "fpvm/ast.h"
  25
+	#include "fpvm/fpvm.h"
25 26
 	#include "parser_itf.h"
  27
+	#include "parser_helper.h"
26 28
 	#include "parser.h"
27 29
 
28 30
 
@@ -73,18 +75,33 @@
73 75
 }
74 76
 
75 77
 %start_symbol start
76  
-%extra_argument {struct ast_node **parseout}
  78
+%extra_argument {struct parser_state *state}
77 79
 %token_type {struct id *}
78 80
 
79  
-%token_destructor { free($$); }
  81
+%token_destructor {
  82
+	free($$);
  83
+	(void) state;	/* suppress unused variable warning */
  84
+}
80 85
 
81  
-%type start {struct ast_node *}
82 86
 %type node {struct ast_node *}
83 87
 %destructor node { free($$); }
84 88
 
85  
-start(S) ::= node(N). {
86  
-	S = N;
87  
-	*parseout = S;
  89
+start ::= TOK_START_EXPR node(N). {
  90
+	state->comm->parseout = N;
  91
+	state->success = 1;
  92
+}
  93
+
  94
+start ::= TOK_START_ASSIGN assignments. {
  95
+	state->success = 1;
  96
+}
  97
+
  98
+assignments ::= assignments assignment.
  99
+
  100
+assignments ::= .
  101
+
  102
+assignment ::= ident(I) TOK_ASSIGN node(N). {
  103
+	fpvm_do_assign(state->comm->fragment, I->label, N);
  104
+	fpvm_parse_free(N);
88 105
 }
89 106
 
90 107
 node(N) ::= TOK_CONSTANT(C). {
22  src/compiler/parser_helper.c
@@ -20,20 +20,24 @@
20 20
 #include <fpvm/ast.h>
21 21
 
22 22
 #include "scanner.h"
  23
+#include "parser.h"
23 24
 #include "parser_itf.h"
24 25
 #include "parser_helper.h"
25 26
 
26  
-struct ast_node *fpvm_parse(const char *expr)
  27
+int fpvm_parse(const char *expr, int start_token, union parser_comm *comm)
27 28
 {
28 29
 	struct scanner *s;
  30
+	struct parser_state state = {
  31
+		.comm = comm,
  32
+		.success = 0,
  33
+	};
29 34
 	int tok;
30 35
 	struct id *identifier;
31 36
 	void *p;
32  
-	struct ast_node *ast;
33 37
 	
34 38
 	s = new_scanner((unsigned char *)expr);
35  
-	ast = NULL;
36 39
 	p = ParseAlloc(malloc);
  40
+	Parse(p, start_token, NULL, &state);
37 41
 	tok = scan(s);
38 42
 	while(tok != TOK_EOF) {
39 43
 		identifier = malloc(sizeof(struct id));
@@ -44,25 +48,25 @@ struct ast_node *fpvm_parse(const char *expr)
44 48
 		} else {
45 49
 			identifier->label = get_token(s);
46 50
 		}
47  
-		Parse(p, tok, identifier, &ast);
  51
+		Parse(p, tok, identifier, &state);
48 52
 		if(tok == TOK_ERROR) {
49 53
 			printf("FPVM: scan error\n");
50 54
 			ParseFree(p, free);
51 55
 			delete_scanner(s);
52  
-			return NULL;
  56
+			return 0;
53 57
 		}
54 58
 		tok = scan(s);
55 59
 	}
56  
-	Parse(p, TOK_EOF, NULL, &ast);
  60
+	Parse(p, TOK_EOF, NULL, &state);
57 61
 	ParseFree(p, free);
58 62
 	delete_scanner(s);
59 63
 
60  
-	if(ast == NULL) {
  64
+	if(!state.success) {
61 65
 		printf("FPVM: parse error\n");
62  
-		return NULL;
  66
+		return 0;
63 67
 	}
64 68
 
65  
-	return ast;
  69
+	return state.success;
66 70
 }
67 71
 
68 72
 void fpvm_parse_free(struct ast_node *node)
9  src/compiler/parser_helper.h
@@ -19,8 +19,15 @@
19 19
 #define __PARSER_HELPER_H
20 20
 
21 21
 #include <fpvm/ast.h>
  22
+#include <fpvm/fpvm.h>
22 23
 
23  
-struct ast_node *fpvm_parse(const char *expr);
  24
+union parser_comm {
  25
+	struct ast_node *parseout;
  26
+	struct fpvm_fragment *fragment;
  27
+};
  28
+
  29
+int fpvm_parse(const char *expr, int start_token,
  30
+    union parser_comm *comm);
24 31
 void fpvm_parse_free(struct ast_node *node);
25 32
 
26 33
 #endif /* __PARSER_HELPER_H */
13  src/compiler/parser_itf.h
@@ -18,6 +18,11 @@
18 18
 #ifndef __PARSER_ITF_H
19 19
 #define __PARSER_ITF_H
20 20
 
  21
+#include <fpvm/fpvm.h>
  22
+
  23
+#include "parser_helper.h"
  24
+
  25
+
21 26
 #define NDEBUG
22 27
 
23 28
 struct id {
@@ -26,8 +31,14 @@ struct id {
26 31
 	float constant;
27 32
 };
28 33
 
  34
+struct parser_state {
  35
+	int success;
  36
+	union parser_comm *comm;
  37
+};
  38
+
29 39
 void *ParseAlloc(void *(*mallocProc)(size_t));
30 40
 void ParseFree(void *p, void (*freeProc)(void*));
31  
-void Parse(void *yyp, int yymajor, struct id *yyminor, struct ast_node **p);
  41
+void Parse(void *yyp, int yymajor, struct id *yyminor,
  42
+    struct parser_state *state);
32 43
 
33 44
 #endif /* __PARSER_ITF_H */
3  src/compiler/scanner.re
@@ -57,7 +57,7 @@ int scan(struct scanner *s)
57 57
 	s->old_cursor = s->cursor;
58 58
 	
59 59
 	/*!re2c
60  
-		[\x20\r\t]		{ goto std; }
  60
+		[\x20\n\r\t]		{ goto std; }
61 61
 		[0-9]+			{ return TOK_CONSTANT; }
62 62
 		[0-9]* "." [0-9]*	{ return TOK_CONSTANT; }
63 63
 
@@ -90,6 +90,7 @@ int scan(struct scanner *s)
90 90
 		"("			{ return TOK_LPAREN; }
91 91
 		")"			{ return TOK_RPAREN; }
92 92
 		","			{ return TOK_COMMA; }
  93
+		"="			{ return TOK_ASSIGN; }
93 94
 		[\x00-\xff]		{ return TOK_ERROR; }
94 95
 	*/
95 96
 }
16  src/compiler/unique.c
@@ -84,12 +84,24 @@ static int cmp_n(const void *a, const void *b)
84 84
 }
85 85
 
86 86
 
  87
+/*
  88
+ * "isid" is not only a minor convenient enhancement, but it also shields us
  89
+ * from implementations of isalpha() that trigger compiler warnings if "c" is
  90
+ * a character.
  91
+ */
  92
+
  93
+static int isid(int c)
  94
+{
  95
+	return isalpha(c) || c == '_';
  96
+}
  97
+
  98
+
87 99
 const char *unique(const char *s)
88 100
 {
89 101
 	const char **res;
90 102
 	const char **walk;
91 103
 
92  
-	if(!isalnum(*s) && *s != '_')
  104
+	if(!isid(*s))
93 105
 		return s;
94 106
 	res = bsearch(s, well_known, sizeof(well_known)/sizeof(*well_known),
95 107
 	    sizeof(s), cmp);
@@ -112,7 +124,7 @@ const char *unique_n(const char *s, int n)
112 124
 	const char **res;
113 125
 	const char **walk;
114 126
 
115  
-	if(!isalnum(*s) && *s != '_')
  127
+	if(!isid(*s))
116 128
 		return s;
117 129
 	res = bsearch(&key, well_known, sizeof(well_known)/sizeof(*well_known),
118 130
 	    sizeof(s), cmp_n);

No commit comments for this range

Something went wrong with that request. Please try again.