Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 6 commits
  • 9 files changed
  • 0 comments
  • 1 contributor
Dec 30, 2011
Werner Almesberger parser.y: added section titles to improve readability b933013
Werner Almesberger compiler: recognize ==, <, and > as aliases for equal, above, below cdc9ffe
Werner Almesberger compiler: rename op_not to op_negate
Furthermore, show the unary minus as  (- x)  instead of  (! x)  in
debugging/test output.

Note that this requires an update for the corresponding change in
milkymist.git
62da9eb
Werner Almesberger compiler: add unary ! operator (basic support only) 369310a
Werner Almesberger compiler: if(!a, b, c) now gets converted to if(a, c, b)
This removes the unary not code generation wouldn't be able to handle
from the AST.
cb733ac
Werner Almesberger compiler: added relational operators !=, <=, and >=
They are implemented with unary nots, so we can only generate code when
they are used in a condition.
35aef26
2  src/compiler/compiler.c
@@ -554,7 +554,7 @@ static const char *assign_default(struct parser_comm *comm,
554 554
 	case op_constant:
555 555
 		v = node->contents.constant;
556 556
 		break;
557  
-	case op_not:
  557
+	case op_negate:
558 558
 		if(node->contents.branches.a->op == op_constant) {
559 559
 			v = -node->contents.branches.a->contents.constant;
560 560
 			break;
98  src/compiler/parser.y
@@ -142,6 +142,12 @@
142 142
 	static struct ast_node *conditional(struct ast_node *a,
143 143
 	    struct ast_node *b, struct ast_node *c)
144 144
 	{
  145
+		if(a->op == op_not) {
  146
+			struct ast_node *next = a->contents.branches.a;
  147
+
  148
+			parse_free_one(a);
  149
+			return node_op(op_if, "if", next, c, b);
  150
+		}
145 151
 		if(a->op != op_constant)
146 152
 			return node_op(op_if, "if", a, b, c);
147 153
 		if(a->contents.constant) {
@@ -175,6 +181,8 @@
175 181
 
176 182
 %type expr {struct ast_node *}
177 183
 %type cond_expr {struct ast_node *}
  184
+%type equal_expr {struct ast_node *}
  185
+%type rel_expr {struct ast_node *}
178 186
 %type add_expr {struct ast_node *}
179 187
 %type mult_expr {struct ast_node *}
180 188
 %type unary_expr {struct ast_node *}
@@ -182,6 +190,8 @@
182 190
 
183 191
 %destructor expr { free($$); }
184 192
 %destructor cond_expr { free($$); }
  193
+%destructor equal_expr { free($$); }
  194
+%destructor rel_expr { free($$); }
185 195
 %destructor add_expr { free($$); }
186 196
 %destructor multexpr { free($$); }
187 197
 %destructor unary_expr { free($$); }
@@ -202,6 +212,10 @@ start ::= TOK_START_ASSIGN sections. {
202 212
 	state->success = 1;
203 213
 }
204 214
 
  215
+
  216
+/* ----- Sections and assignments ------------------------------------------ */
  217
+
  218
+
205 219
 sections ::= assignments.
206 220
 sections ::= assignments per_frame_label assignments.
207 221
 sections ::= assignments per_frame_label assignments per_vertex_label
@@ -278,18 +292,63 @@ opt_semi ::= opt_semi TOK_SEMI.
278 292
 
279 293
 opt_semi ::= .
280 294
 
  295
+
  296
+/* ----- Operators --------------------------------------------------------- */
  297
+
  298
+
281 299
 expr(N) ::= cond_expr(A). {
282 300
 	N = A;
283 301
 }
284 302
 
285  
-cond_expr(N) ::= add_expr(A). {
  303
+cond_expr(N) ::= equal_expr(A). {
286 304
 	N = A;
287 305
 }
288 306
 
289  
-cond_expr(N) ::= add_expr(A) TOK_QUESTION expr(B) TOK_COLON cond_expr(C). {
  307
+cond_expr(N) ::= equal_expr(A) TOK_QUESTION expr(B) TOK_COLON cond_expr(C). {
290 308
 	N = conditional(A, B, C);
291 309
 }
292 310
 
  311
+equal_expr(N) ::= rel_expr(A). {
  312
+	N = A;
  313
+}
  314
+
  315
+equal_expr(N) ::= equal_expr(A) TOK_EQ rel_expr(B). {
  316
+	FOLD_BINARY(N, op_equal, "equal", A, B, a == b);
  317
+}
  318
+
  319
+equal_expr(N) ::= equal_expr(A) TOK_NE rel_expr(B). {
  320
+	struct ast_node *tmp;
  321
+
  322
+	FOLD_BINARY(tmp, op_equal, "equal", A, B, a == b);
  323
+	FOLD_UNARY(N, op_not, "!", tmp, !a);
  324
+}
  325
+
  326
+rel_expr(N) ::= add_expr(A). {
  327
+	N = A;
  328
+}
  329
+
  330
+rel_expr(N) ::= rel_expr(A) TOK_LT add_expr(B). {
  331
+	FOLD_BINARY(N, op_below, "below", A, B, a < b);
  332
+}
  333
+
  334
+rel_expr(N) ::= rel_expr(A) TOK_GT add_expr(B). {
  335
+	FOLD_BINARY(N, op_above, "above", A, B, a > b);
  336
+}
  337
+
  338
+rel_expr(N) ::= rel_expr(A) TOK_LE add_expr(B). {
  339
+	struct ast_node *tmp;
  340
+
  341
+	FOLD_BINARY(tmp, op_above, "above", A, B, a > b);
  342
+	FOLD_UNARY(N, op_not, "!", tmp, !a);
  343
+}
  344
+
  345
+rel_expr(N) ::= rel_expr(A) TOK_GE add_expr(B). {
  346
+	struct ast_node *tmp;
  347
+
  348
+	FOLD_BINARY(tmp, op_below, "below", A, B, a < b);
  349
+	FOLD_UNARY(N, op_not, "!", tmp, !a);
  350
+}
  351
+
293 352
 add_expr(N) ::= mult_expr(A). {
294 353
 	N = A;
295 354
 }
@@ -323,9 +382,17 @@ unary_expr(N) ::= primary_expr(A). {
323 382
 }
324 383
 
325 384
 unary_expr(N) ::= TOK_MINUS unary_expr(A). {
326  
-	FOLD_UNARY(N, op_not, "!", A, -a);
  385
+	FOLD_UNARY(N, op_negate, "-", A, -a);
327 386
 }
328 387
 
  388
+unary_expr(N) ::= TOK_NOT unary_expr(A). {
  389
+	FOLD_UNARY(N, op_not, "!", A, !a);
  390
+}
  391
+
  392
+
  393
+/* ----- Unary functions --------------------------------------------------- */
  394
+
  395
+
329 396
 primary_expr(N) ::= unary_misc(I) TOK_LPAREN expr(A) TOK_RPAREN. {
330 397
 	N = node(I->token, I->label, A, NULL, NULL);
331 398
 	free(I);
@@ -336,6 +403,10 @@ primary_expr(N) ::= TOK_SQR(I) TOK_LPAREN expr(A) TOK_RPAREN. {
336 403
 	free(I);
337 404
 }
338 405
 
  406
+
  407
+/* ----- Binary functions -------------------------------------------------- */
  408
+
  409
+
339 410
 primary_expr(N) ::= binary_misc(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
340 411
     TOK_RPAREN. {
341 412
 	N = node(I->token, I->label, A, B, NULL);
@@ -372,12 +443,20 @@ primary_expr(N) ::= TOK_MIN(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
372 443
 	free(I);
373 444
 }
374 445
 
  446
+
  447
+/* ----- Trinary functions ------------------------------------------------- */
  448
+
  449
+
375 450
 primary_expr(N) ::= TOK_IF(I) TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_COMMA
376 451
     expr(C) TOK_RPAREN. {
377 452
 	N = conditional(A, B, C);
378 453
 	free(I);
379 454
 }
380 455
 
  456
+
  457
+/* ----- Primary expressions ----------------------------------------------- */
  458
+
  459
+
381 460
 primary_expr(N) ::= TOK_LPAREN expr(A) TOK_RPAREN. {
382 461
 	N = A;
383 462
 }
@@ -392,6 +471,19 @@ primary_expr(N) ::= ident(I). {
392 471
 	free(I);
393 472
 }
394 473
 
  474
+
  475
+/* ----- Identifiers ------------------------------------------------------- */
  476
+
  477
+/*
  478
+ * Function names are not reserved words. If not followed by an opening
  479
+ * parenthesis, they become regular identifiers.
  480
+ *
  481
+ * {u,bi,ter}nary are identifiers that have an individual rule, e.g., because
  482
+ * they have function-specific code for constant folding. {u,bi,ter}nary_misc
  483
+ * are identifiers the parser treats as generic functions, without knowing
  484
+ * anything about their semantics.
  485
+ */
  486
+
395 487
 ident(O) ::= TOK_IDENT(I).	{ O = I; }
396 488
 ident(O) ::= unary(I).		{ O = I; }
397 489
 ident(O) ::= unary_misc(I).	{ O = I; }
5  src/compiler/parser_helper.c
@@ -143,6 +143,11 @@ const char *parse(const char *expr, int start_token, struct parser_comm *comm)
143 143
 	return error;
144 144
 }
145 145
 
  146
+void parse_free_one(struct ast_node *node)
  147
+{
  148
+	free(node);
  149
+}
  150
+
146 151
 void parse_free(struct ast_node *node)
147 152
 {
148 153
 	if(node == NULL) return;
7  src/compiler/parser_helper.h
@@ -21,6 +21,12 @@
21 21
 #include <fpvm/ast.h>
22 22
 #include <fpvm/fpvm.h>
23 23
 
  24
+
  25
+/* virtual operation - for use inside the parser only */
  26
+enum {
  27
+	op_not  = op_vops+1,
  28
+};
  29
+
24 30
 struct compiler_sc;
25 31
 
26 32
 struct parser_comm {
@@ -40,6 +46,7 @@ struct parser_comm {
40 46
 };
41 47
 
42 48
 const char *parse(const char *expr, int start_token, struct parser_comm *comm);
  49
+void parse_free_one(struct ast_node *node);
43 50
 void parse_free(struct ast_node *node);
44 51
 
45 52
 #endif /* __PARSER_HELPER_H */
7  src/compiler/ptest/ptest.c
@@ -110,8 +110,8 @@ static void dump_ast(const struct ast_node *ast)
110 110
         case op_quake:
111 111
 		op("quake", ast);
112 112
 		break;
113  
-	case op_not:
114  
-		op("!", ast);
  113
+	case op_negate:
  114
+		op("-", ast);
115 115
 		break;
116 116
 	case op_sqr:
117 117
 		op("sqr", ast);
@@ -131,6 +131,9 @@ static void dump_ast(const struct ast_node *ast)
131 131
         case op_int:
132 132
 		op("int", ast);
133 133
 		break;
  134
+	case op_not:
  135
+		op("!", ast);
  136
+		break;
134 137
 	default:
135 138
 		abort();
136 139
 	}
7  src/compiler/scanner.re
@@ -138,6 +138,13 @@ int scan(struct scanner *s)
138 138
 		<N>","			{ return TOK_COMMA; }
139 139
 		<N>"?"			{ return TOK_QUESTION; }
140 140
 		<N>":"			{ return TOK_COLON; }
  141
+		<N>"!"			{ return TOK_NOT; }
  142
+		<N>"=="			{ return TOK_EQ; }
  143
+		<N>"!="			{ return TOK_NE; }
  144
+		<N>"<"			{ return TOK_LT; }
  145
+		<N>">"			{ return TOK_GT; }
  146
+		<N>"<="			{ return TOK_LE; }
  147
+		<N>">="			{ return TOK_GE; }
141 148
 
142 149
 		<N,FNAME1>"="		{ if (YYGETCONDITION() == yycFNAME1)
143 150
 						YYSETCONDITION(yycFNAME2);
103  src/compiler/test/not
... ...
@@ -0,0 +1,103 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "not: !a" << EOF
  7
+x = !a
  8
+EOF
  9
+expect <<EOF
  10
+x = (! a)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest_fail "not: !a (try to generate code)" -c << EOF
  16
+per_frame: wave_a = !a
  17
+EOF
  18
+expect <<EOF
  19
+FPVM, line 2: Operation not supported: ! near 'EOF'
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "not: !0" << EOF
  25
+x = !0
  26
+EOF
  27
+expect <<EOF
  28
+x = 1
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "not: !1" << EOF
  34
+x = !1
  35
+EOF
  36
+expect <<EOF
  37
+x = 0
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "not: !a*b" << EOF
  43
+x = !a*b
  44
+EOF
  45
+expect <<EOF
  46
+x = (* (! a) b)
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "not: -!a" << EOF
  52
+x = -!a
  53
+EOF
  54
+expect <<EOF
  55
+x = (- (! a))
  56
+EOF
  57
+
  58
+#------------------------------------------------------------------------------
  59
+
  60
+ptest "not: !-b" << EOF
  61
+x = !-b
  62
+EOF
  63
+expect <<EOF
  64
+x = (! (- b))
  65
+EOF
  66
+
  67
+#------------------------------------------------------------------------------
  68
+
  69
+ptest "not: if (!a, b, c)" << EOF
  70
+x = if (!a, b, c)
  71
+EOF
  72
+expect <<EOF
  73
+x = (if a c b)
  74
+EOF
  75
+
  76
+#------------------------------------------------------------------------------
  77
+
  78
+ptest "not: !a ? b : c" << EOF
  79
+x = !a ? b : c
  80
+EOF
  81
+expect <<EOF
  82
+x = (if a c b)
  83
+EOF
  84
+
  85
+#------------------------------------------------------------------------------
  86
+
  87
+ptest "not: !0 ? b : c" << EOF
  88
+x = !0 ? b : c
  89
+EOF
  90
+expect <<EOF
  91
+x = b
  92
+EOF
  93
+
  94
+#------------------------------------------------------------------------------
  95
+
  96
+ptest "not: !1 ? b : c" << EOF
  97
+x = !1 ? b : c
  98
+EOF
  99
+expect <<EOF
  100
+x = c
  101
+EOF
  102
+
  103
+###############################################################################
16  src/compiler/test/prec
@@ -61,7 +61,7 @@ ptest "precedence: x = -a*b" <<EOF
61 61
 x = -a*b
62 62
 EOF
63 63
 expect <<EOF
64  
-x = (* (! a) b)
  64
+x = (* (- a) b)
65 65
 EOF
66 66
 
67 67
 #------------------------------------------------------------------------------
@@ -70,7 +70,7 @@ ptest "precedence: x = a/b" <<EOF
70 70
 x = -a/b
71 71
 EOF
72 72
 expect <<EOF
73  
-x = (/ (! a) b)
  73
+x = (/ (- a) b)
74 74
 EOF
75 75
 
76 76
 #------------------------------------------------------------------------------
@@ -79,7 +79,7 @@ ptest "precedence: x = a%b" <<EOF
79 79
 x = -a%b
80 80
 EOF
81 81
 expect <<EOF
82  
-x = (% (! a) b)
  82
+x = (% (- a) b)
83 83
 EOF
84 84
 
85 85
 #------------------------------------------------------------------------------
@@ -88,7 +88,7 @@ ptest "precedence: x = -sin(a)" <<EOF
88 88
 x = -sin(a)
89 89
 EOF
90 90
 expect <<EOF
91  
-x = (! (sin a))
  91
+x = (- (sin a))
92 92
 EOF
93 93
 
94 94
 #------------------------------------------------------------------------------
@@ -97,7 +97,7 @@ ptest "precedence: x = -max(a, b)" <<EOF
97 97
 x = -max(a, b)
98 98
 EOF
99 99
 expect <<EOF
100  
-x = (! (max a b))
  100
+x = (- (max a b))
101 101
 EOF
102 102
 
103 103
 #------------------------------------------------------------------------------
@@ -106,7 +106,7 @@ ptest "precedence: x = -if(a, b, c)" <<EOF
106 106
 x = -if(a, b, c)
107 107
 EOF
108 108
 expect <<EOF
109  
-x = (! (if a b c))
  109
+x = (- (if a b c))
110 110
 EOF
111 111
 
112 112
 #------------------------------------------------------------------------------
@@ -115,7 +115,7 @@ ptest "precedence: x = -(a+b)" <<EOF
115 115
 x = -(a+b)
116 116
 EOF
117 117
 expect <<EOF
118  
-x = (! (+ a b))
  118
+x = (- (+ a b))
119 119
 EOF
120 120
 
121 121
 #------------------------------------------------------------------------------
@@ -124,7 +124,7 @@ ptest "precedence: x = a--b" <<EOF
124 124
 x = a--b
125 125
 EOF
126 126
 expect <<EOF
127  
-x = (- a (! b))
  127
+x = (- a (- b))
128 128
 EOF
129 129
 
130 130
 ###############################################################################
214  src/compiler/test/relop
... ...
@@ -0,0 +1,214 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "relop: a == b" << EOF
  7
+x = a == b
  8
+EOF
  9
+expect <<EOF
  10
+x = (equal a b)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "relop: a < b" << EOF
  16
+x = a < b
  17
+EOF
  18
+expect <<EOF
  19
+x = (below a b)
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "relop: a > b" << EOF
  25
+x = a > b
  26
+EOF
  27
+expect <<EOF
  28
+x = (above a b)
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "relop: fold ==" << EOF
  34
+x = 1 == 2
  35
+y = 2 == 2
  36
+z = 3 == 2
  37
+EOF
  38
+expect <<EOF
  39
+x = 0
  40
+y = 1
  41
+z = 0
  42
+EOF
  43
+
  44
+#------------------------------------------------------------------------------
  45
+
  46
+ptest "relop: fold <" << EOF
  47
+x = 1 < 2
  48
+y = 2 < 2
  49
+z = 3 < 2
  50
+EOF
  51
+expect <<EOF
  52
+x = 1
  53
+y = 0
  54
+z = 0
  55
+EOF
  56
+
  57
+#------------------------------------------------------------------------------
  58
+
  59
+ptest "relop: fold >" << EOF
  60
+x = 1 > 2
  61
+y = 2 > 2
  62
+z = 3 > 2
  63
+EOF
  64
+expect <<EOF
  65
+x = 0
  66
+y = 0
  67
+z = 1
  68
+EOF
  69
+
  70
+#------------------------------------------------------------------------------
  71
+
  72
+ptest "relop: a == b ? c : d" << EOF
  73
+x = a == b ? c : d
  74
+EOF
  75
+expect <<EOF
  76
+x = (if (equal a b) c d)
  77
+EOF
  78
+
  79
+#------------------------------------------------------------------------------
  80
+
  81
+ptest "relop: a ? b : c == d" << EOF
  82
+x = a ? b : c == d
  83
+EOF
  84
+expect <<EOF
  85
+x = (if a b (equal c d))
  86
+EOF
  87
+
  88
+#------------------------------------------------------------------------------
  89
+
  90
+ptest "relop: a < b == c > d" << EOF
  91
+x = a < b == c > d
  92
+EOF
  93
+expect <<EOF
  94
+x = (equal (below a b) (above c d))
  95
+EOF
  96
+
  97
+#------------------------------------------------------------------------------
  98
+
  99
+ptest "relop: a+b < c-d" << EOF
  100
+x = a+b < c-d
  101
+EOF
  102
+expect <<EOF
  103
+x = (below (+ a b) (- c d))
  104
+EOF
  105
+
  106
+#------------------------------------------------------------------------------
  107
+
  108
+ptest "relop: a-b > c+d" << EOF
  109
+x = a-b > c+d
  110
+EOF
  111
+expect <<EOF
  112
+x = (above (- a b) (+ c d))
  113
+EOF
  114
+
  115
+#------------------------------------------------------------------------------
  116
+
  117
+ptest "relop: a != b" << EOF
  118
+x = a != b
  119
+EOF
  120
+expect <<EOF
  121
+x = (! (equal a b))
  122
+EOF
  123
+
  124
+#------------------------------------------------------------------------------
  125
+
  126
+ptest "relop: a <= b" << EOF
  127
+x = a <= b
  128
+EOF
  129
+expect <<EOF
  130
+x = (! (above a b))
  131
+EOF
  132
+
  133
+#------------------------------------------------------------------------------
  134
+
  135
+ptest "relop: a >= b" << EOF
  136
+x = a >= b
  137
+EOF
  138
+expect <<EOF
  139
+x = (! (below a b))
  140
+EOF
  141
+
  142
+#------------------------------------------------------------------------------
  143
+
  144
+ptest "relop: a < b != c >= d" << EOF
  145
+x = a < b != c >= d
  146
+EOF
  147
+expect <<EOF
  148
+x = (! (equal (below a b) (! (below c d))))
  149
+EOF
  150
+
  151
+#------------------------------------------------------------------------------
  152
+
  153
+ptest "relop: a+b <= c-d" << EOF
  154
+x = a+b <= c-d
  155
+EOF
  156
+expect <<EOF
  157
+x = (! (above (+ a b) (- c d)))
  158
+EOF
  159
+
  160
+#------------------------------------------------------------------------------
  161
+
  162
+ptest "relop: a-b >= c+d" << EOF
  163
+x = a-b >= c+d
  164
+EOF
  165
+expect <<EOF
  166
+x = (! (below (- a b) (+ c d)))
  167
+EOF
  168
+
  169
+#------------------------------------------------------------------------------
  170
+
  171
+ptest "relop: a != b ? c : d" << EOF
  172
+x = a != b ? c : d
  173
+EOF
  174
+expect <<EOF
  175
+x = (if (equal a b) d c)
  176
+EOF
  177
+
  178
+#------------------------------------------------------------------------------
  179
+
  180
+ptest "relop: a <= b ? c : d" << EOF
  181
+x = a <= b ? c : d
  182
+EOF
  183
+expect <<EOF
  184
+x = (if (above a b) d c)
  185
+EOF
  186
+
  187
+#------------------------------------------------------------------------------
  188
+
  189
+ptest "relop: a >= b ? c : d" << EOF
  190
+x = a >= b ? c : d
  191
+EOF
  192
+expect <<EOF
  193
+x = (if (below a b) d c)
  194
+EOF
  195
+
  196
+#------------------------------------------------------------------------------
  197
+
  198
+ptest "relop: 1 != 2 ? c : d" << EOF
  199
+x = 1 != 2 ? c : d
  200
+EOF
  201
+expect <<EOF
  202
+x = c
  203
+EOF
  204
+
  205
+#------------------------------------------------------------------------------
  206
+
  207
+ptest "relop: 2 != 2 ? c : d" << EOF
  208
+x = 2 != 2 ? c : d
  209
+EOF
  210
+expect <<EOF
  211
+x = d
  212
+EOF
  213
+
  214
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.