Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
Dec 30, 2011
Werner Almesberger compiler: rewrite grammar without precedence directives
This makes the grammar look like the ANSI C grammar in section A13
of K&R 2nd Ed., which will make it easy to add other elements with
C-like semantics.

Furthermore, not having precedences to fall back to makes sure the
parser generator will report every single ambiguity and will never
try to solve it on its own.

Last but not least, this also allows us to get rid of the TOK_NOT
pseudo-token.
271e366
Werner Almesberger compiler: added C-like ternary operator (conditional expressions) f8f0362
Werner Almesberger compiler: use node_op if we know the token
This minor optimization avoids an unnecessary mapping step.
a4da97c
Werner Almesberger compiler: simple constant folding for arithmetic operations 6ada203
Werner Almesberger compiler: fold also the remaining documented binary operators
That's above, below, equal, min, and max. I'm too lazy to fold the
undocumented tsign ;-) (It's currently only used in code generation
anyway.)
056b5ab
Werner Almesberger compiler: fold conditionals with constant condition as well 99ee0dd
Werner Almesberger compiler: fold unary operators - and sqr()
sqrt() could also be useful, but that would involve linking with libm,
which is scary. Maybe later.
01c5e10
223  src/compiler/parser.y
@@ -45,7 +45,7 @@
45 45
 
46 46
 	#define	IS_STYLE(which)						\
47 47
 		do {							\
48  
-			if (state->style == OTHER_STYLE_##which) {	\
  48
+			if(state->style == OTHER_STYLE_##which) {	\
49 49
 				FAIL;					\
50 50
 				return;					\
51 51
 			}						\
@@ -73,7 +73,6 @@
73 73
 		[TOK_IF]	= op_if,
74 74
 		[TOK_TSIGN]	= op_tsign,
75 75
 		[TOK_QUAKE]	= op_quake,
76  
-		[TOK_NOT]	= op_not,
77 76
 		[TOK_SQR]	= op_sqr,
78 77
 		[TOK_SQRT]	= op_sqrt,
79 78
 		[TOK_INVSQRT]	= op_invsqrt,
@@ -82,13 +81,13 @@
82 81
 		[TOK_INT]	= op_int,
83 82
 	};
84 83
 
85  
-	static struct ast_node *node(int token, const char *id,
  84
+	static struct ast_node *node_op(enum ast_op op, const char *id,
86 85
 	    struct ast_node *a, struct ast_node *b, struct ast_node *c)
87 86
 	{
88 87
 		struct ast_node *n;
89 88
 
90 89
 		n = malloc(sizeof(struct ast_node));
91  
-		n->op = tok2op[token];
  90
+		n->op = op;
92 91
 		n->label = id;
93 92
 		n->contents.branches.a = a;
94 93
 		n->contents.branches.b = b;
@@ -96,6 +95,66 @@
96 95
 		return n;
97 96
 	}
98 97
 
  98
+	static struct ast_node *node(int token, const char *id,
  99
+	    struct ast_node *a, struct ast_node *b, struct ast_node *c)
  100
+	{
  101
+		return node_op(tok2op[token], id, a, b, c);
  102
+	}
  103
+
  104
+	static struct ast_node *constant(float n)
  105
+	{
  106
+		struct ast_node *node;
  107
+
  108
+		node = node_op(op_constant, "", NULL, NULL, NULL);
  109
+		node->contents.constant = n;
  110
+		return node;
  111
+	}
  112
+
  113
+	#define FOLD_UNARY(res, ast_op, name, arg, expr)		\
  114
+		do {							\
  115
+			if((arg)->op == op_constant) {			\
  116
+				float a = (arg)->contents.constant;	\
  117
+									\
  118
+				res = constant(expr);			\
  119
+				parse_free(arg);			\
  120
+			} else {					\
  121
+				res = node_op(ast_op, name,		\
  122
+				    arg, NULL, NULL);			\
  123
+			}						\
  124
+		} while (0)
  125
+
  126
+	#define FOLD_BINARY(res, ast_op, name, arg_a, arg_b, expr)	\
  127
+		do {							\
  128
+			if((arg_a)->op == op_constant && 		\
  129
+			    (arg_b)->op == op_constant) {		\
  130
+				float a = (arg_a)->contents.constant;	\
  131
+				float b = (arg_b)->contents.constant;	\
  132
+									\
  133
+				res = constant(expr);			\
  134
+				parse_free(arg_a);			\
  135
+				parse_free(arg_b);			\
  136
+			} else {					\
  137
+				res = node_op(ast_op, name,		\
  138
+				     arg_a, arg_b, NULL); 		\
  139
+			}						\
  140
+		} while (0)
  141
+
  142
+	static struct ast_node *conditional(struct ast_node *a,
  143
+	    struct ast_node *b, struct ast_node *c)
  144
+	{
  145
+		if(a->op != op_constant)
  146
+			return node_op(op_if, "if", a, b, c);
  147
+		if(a->contents.constant) {
  148
+			parse_free(a);
  149
+			parse_free(c);
  150
+			return b;
  151
+		} else {
  152
+			parse_free(a);
  153
+			parse_free(b);
  154
+			return c;
  155
+		}
  156
+	}
  157
+
99 158
 	static void syntax_error(struct parser_state *state)
100 159
 	{
101 160
 		if(!state->error_label) {
@@ -114,8 +173,19 @@
114 173
 	(void) state;	/* suppress unused variable warning */
115 174
 }
116 175
 
117  
-%type node {struct ast_node *}
118  
-%destructor node { free($$); }
  176
+%type expr {struct ast_node *}
  177
+%type cond_expr {struct ast_node *}
  178
+%type add_expr {struct ast_node *}
  179
+%type mult_expr {struct ast_node *}
  180
+%type unary_expr {struct ast_node *}
  181
+%type primary_expr {struct ast_node *}
  182
+
  183
+%destructor expr { free($$); }
  184
+%destructor cond_expr { free($$); }
  185
+%destructor add_expr { free($$); }
  186
+%destructor multexpr { free($$); }
  187
+%destructor unary_expr { free($$); }
  188
+%destructor primary_expr { free($$); }
119 189
 
120 190
 %type context {assign_callback}
121 191
 
@@ -123,7 +193,7 @@
123 193
 	FAIL;
124 194
 }
125 195
 
126  
-start ::= TOK_START_EXPR node(N). {
  196
+start ::= TOK_START_EXPR expr(N). {
127 197
 	state->comm->u.parseout = N;
128 198
 	state->success = 1;
129 199
 }
@@ -152,7 +222,7 @@ assignments ::= assignments assignment.
152 222
 
153 223
 assignments ::= .
154 224
 
155  
-assignment ::= ident(I) TOK_ASSIGN node(N) opt_semi. {
  225
+assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
156 226
 	state->error = state->comm->assign_default(state->comm, I->label, N);
157 227
 	free(I);
158 228
 	if(state->error) {
@@ -208,88 +278,145 @@ opt_semi ::= opt_semi TOK_SEMI.
208 278
 
209 279
 opt_semi ::= .
210 280
 
211  
-node(N) ::= TOK_CONSTANT(C). {
212  
-	N = node(TOK_CONSTANT, "", NULL, NULL, NULL);
213  
-	N->contents.constant = C->constant;
214  
-	free(C);
  281
+expr(N) ::= cond_expr(A). {
  282
+	N = A;
215 283
 }
216 284
 
217  
-node(N) ::= ident(I). {
218  
-	N = node(I->token, I->label, NULL, NULL, NULL);
219  
-	free(I);
  285
+cond_expr(N) ::= add_expr(A). {
  286
+	N = A;
  287
+}
  288
+
  289
+cond_expr(N) ::= add_expr(A) TOK_QUESTION expr(B) TOK_COLON cond_expr(C). {
  290
+	N = conditional(A, B, C);
220 291
 }
221 292
 
222  
-%left TOK_PLUS TOK_MINUS.
223  
-%left TOK_MULTIPLY TOK_DIVIDE TOK_PERCENT.
224  
-%left TOK_NOT.
  293
+add_expr(N) ::= mult_expr(A). {
  294
+	N = A;
  295
+}
225 296
 
226  
-node(N) ::= node(A) TOK_PLUS node(B). {
227  
-	N = node(TOK_PLUS, "+", A, B, NULL);
  297
+add_expr(N) ::= add_expr(A) TOK_PLUS mult_expr(B). {
  298
+	FOLD_BINARY(N, op_plus, "+", A, B, a + b);
228 299
 }
229 300
 
230  
-node(N) ::= node(A) TOK_MINUS node(B). {
231  
-	N = node(TOK_MINUS, "-", A, B, NULL);
  301
+add_expr(N) ::= add_expr(A) TOK_MINUS mult_expr(B). {
  302
+	FOLD_BINARY(N, op_minus, "-", A, B, a - b);
232 303
 }
233 304
 
234  
-node(N) ::= node(A) TOK_MULTIPLY node(B). {
235  
-	N = node(TOK_MULTIPLY, "*", A, B, NULL);
  305
+mult_expr(N) ::= unary_expr(A). {
  306
+	N = A;
236 307
 }
237 308
 
238  
-node(N) ::= node(A) TOK_DIVIDE node(B). {
239  
-	N = node(TOK_DIVIDE, "/", A, B, NULL);
  309
+mult_expr(N) ::= mult_expr(A) TOK_MULTIPLY unary_expr(B). {
  310
+	FOLD_BINARY(N, op_multiply, "*", A, B, a * b);
240 311
 }
241 312
 
242  
-node(N) ::= node(A) TOK_PERCENT node(B). {
243  
-	N = node(TOK_PERCENT, "%", A, B, NULL);
  313
+mult_expr(N) ::= mult_expr(A) TOK_DIVIDE unary_expr(B). {
  314
+	FOLD_BINARY(N, op_divide, "/", A, B, a / b);
244 315
 }
245 316
 
246  
-node(N) ::= TOK_MINUS node(A). [TOK_NOT] {
247  
-	N = node(TOK_NOT, "!", A, NULL, NULL);
  317
+mult_expr(N) ::= mult_expr(A) TOK_PERCENT unary_expr(B). {
  318
+	FOLD_BINARY(N, op_percent, "%", A, B, a-b*(int) (a/b));
248 319
 }
249 320
 
250  
-node(N) ::= unary(I) TOK_LPAREN node(A) TOK_RPAREN. {
  321
+unary_expr(N) ::= primary_expr(A). {
  322
+	N = A;
  323
+}
  324
+
  325
+unary_expr(N) ::= TOK_MINUS unary_expr(A). {
  326
+	FOLD_UNARY(N, op_not, "!", A, -a);
  327
+}
  328
+
  329
+primary_expr(N) ::= unary_misc(I) TOK_LPAREN expr(A) TOK_RPAREN. {
251 330
 	N = node(I->token, I->label, A, NULL, NULL);
252 331
 	free(I);
253 332
 }
254 333
 
255  
-node(N) ::= binary(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_RPAREN. {
256  
-	N = node(I->token, I->label, A, B, NULL);
  334
+primary_expr(N) ::= TOK_SQR(I) TOK_LPAREN expr(A) TOK_RPAREN. {
  335
+	FOLD_UNARY(N, op_sqr, "sqr", A, a*a);
257 336
 	free(I);
258 337
 }
259 338
 
260  
-node(N) ::= ternary(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_COMMA node(C)
  339
+primary_expr(N) ::= binary_misc(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
261 340
     TOK_RPAREN. {
262  
-	N = node(I->token, I->label, A, B, C);
  341
+	N = node(I->token, I->label, A, B, NULL);
  342
+	free(I);
  343
+}
  344
+
  345
+primary_expr(N) ::= TOK_ABOVE(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
  346
+     TOK_RPAREN. {
  347
+	FOLD_BINARY(N, op_above, "above", A, B, a > b);
  348
+	free(I);
  349
+}
  350
+
  351
+primary_expr(N) ::= TOK_BELOW(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
  352
+     TOK_RPAREN. {
  353
+	FOLD_BINARY(N, op_below, "below", A, B, a < b);
  354
+	free(I);
  355
+}
  356
+
  357
+primary_expr(N) ::= TOK_EQUAL(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
  358
+     TOK_RPAREN. {
  359
+	FOLD_BINARY(N, op_equal, "equal", A, B, a == b);
263 360
 	free(I);
264 361
 }
265 362
 
266  
-node(N) ::= TOK_LPAREN node(A) TOK_RPAREN. {
  363
+primary_expr(N) ::= TOK_MAX(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
  364
+     TOK_RPAREN. {
  365
+	FOLD_BINARY(N, op_max, "max", A, B, a > b ? a : b);
  366
+	free(I);
  367
+}
  368
+
  369
+primary_expr(N) ::= TOK_MIN(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
  370
+     TOK_RPAREN. {
  371
+	FOLD_BINARY(N, op_min, "min", A, B, a < b ? a : b);
  372
+	free(I);
  373
+}
  374
+
  375
+primary_expr(N) ::= TOK_IF(I) TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_COMMA
  376
+    expr(C) TOK_RPAREN. {
  377
+	N = conditional(A, B, C);
  378
+	free(I);
  379
+}
  380
+
  381
+primary_expr(N) ::= TOK_LPAREN expr(A) TOK_RPAREN. {
267 382
 	N = A;
268 383
 }
269 384
 
  385
+primary_expr(N) ::= TOK_CONSTANT(C). {
  386
+	N = constant(C->constant);
  387
+	free(C);
  388
+}
  389
+
  390
+primary_expr(N) ::= ident(I). {
  391
+	N = node(I->token, I->label, NULL, NULL, NULL);
  392
+	free(I);
  393
+}
  394
+
270 395
 ident(O) ::= TOK_IDENT(I).	{ O = I; }
271 396
 ident(O) ::= unary(I).		{ O = I; }
  397
+ident(O) ::= unary_misc(I).	{ O = I; }
272 398
 ident(O) ::= binary(I).		{ O = I; }
  399
+ident(O) ::= binary_misc(I).	{ O = I; }
273 400
 ident(O) ::= ternary(I).	{ O = I; }
274 401
 
275  
-unary(O) ::= TOK_ABS(I).	{ O = I; }
276  
-unary(O) ::= TOK_COS(I).	{ O = I; }
277  
-unary(O) ::= TOK_F2I(I).	{ O = I; }
278  
-unary(O) ::= TOK_ICOS(I).	{ O = I; }
279  
-unary(O) ::= TOK_I2F(I).	{ O = I; }
280  
-unary(O) ::= TOK_INT(I).	{ O = I; }
281  
-unary(O) ::= TOK_INVSQRT(I).	{ O = I; }
282  
-unary(O) ::= TOK_ISIN(I).	{ O = I; }
283  
-unary(O) ::= TOK_QUAKE(I).	{ O = I; }
284  
-unary(O) ::= TOK_SIN(I).	{ O = I; }
  402
+unary_misc(O) ::= TOK_ABS(I).	{ O = I; }
  403
+unary_misc(O) ::= TOK_COS(I).	{ O = I; }
  404
+unary_misc(O) ::= TOK_F2I(I).	{ O = I; }
  405
+unary_misc(O) ::= TOK_ICOS(I).	{ O = I; }
  406
+unary_misc(O) ::= TOK_I2F(I).	{ O = I; }
  407
+unary_misc(O) ::= TOK_INT(I).	{ O = I; }
  408
+unary_misc(O) ::= TOK_INVSQRT(I).	{ O = I; }
  409
+unary_misc(O) ::= TOK_ISIN(I).	{ O = I; }
  410
+unary_misc(O) ::= TOK_QUAKE(I).	{ O = I; }
  411
+unary_misc(O) ::= TOK_SIN(I).	{ O = I; }
285 412
 unary(O) ::= TOK_SQR(I).	{ O = I; }
286  
-unary(O) ::= TOK_SQRT(I).	{ O = I; }
  413
+unary_misc(O) ::= TOK_SQRT(I).	{ O = I; }
287 414
 
288 415
 binary(O) ::= TOK_ABOVE(I).	{ O = I; }
289 416
 binary(O) ::= TOK_BELOW(I).	{ O = I; }
290 417
 binary(O) ::= TOK_EQUAL(I).	{ O = I; }
291 418
 binary(O) ::= TOK_MAX(I).	{ O = I; }
292 419
 binary(O) ::= TOK_MIN(I).	{ O = I; }
293  
-binary(O) ::= TOK_TSIGN(I).	{ O = I; }
  420
+binary_misc(O) ::= TOK_TSIGN(I).	{ O = I; }
294 421
 
295 422
 ternary(O) ::= TOK_IF(I).	{ O = I; }
2  src/compiler/scanner.re
@@ -136,7 +136,9 @@ int scan(struct scanner *s)
136 136
 		<N>"("			{ return TOK_LPAREN; }
137 137
 		<N>")"			{ return TOK_RPAREN; }
138 138
 		<N>","			{ return TOK_COMMA; }
  139
+		<N>"?"			{ return TOK_QUESTION; }
139 140
 		<N>":"			{ return TOK_COLON; }
  141
+
140 142
 		<N,FNAME1>"="		{ if (YYGETCONDITION() == yycFNAME1)
141 143
 						YYSETCONDITION(yycFNAME2);
142 144
 					  return TOK_ASSIGN; }
40  src/compiler/test/cond
... ...
@@ -0,0 +1,40 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "conditional: x = a ? b : c" <<EOF
  7
+x = a ? b : c
  8
+EOF
  9
+expect <<EOF
  10
+x = (if a b c)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "conditional: x = a+b ? c+d : e+f" <<EOF
  16
+x = a+b ? c+d : e+f
  17
+EOF
  18
+expect <<EOF
  19
+x = (if (+ a b) (+ c d) (+ e f))
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "conditional: x = a ? b ? c : d : e" <<EOF
  25
+x = a ? b ? c : d : e
  26
+EOF
  27
+expect <<EOF
  28
+x = (if a (if b c d) e)
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "conditional: x = a ? b : c ? d : e" <<EOF
  34
+x = a ? b : c ? d : e
  35
+EOF
  36
+expect <<EOF
  37
+x = (if a b (if c d e))
  38
+EOF
  39
+
  40
+###############################################################################
58  src/compiler/test/fcond
... ...
@@ -0,0 +1,58 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "fold conditional: x = a ? b : c (nothing to fold)" << EOF
  7
+x = a ? b : c
  8
+EOF
  9
+expect <<EOF
  10
+x = (if a b c)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "fold conditional: x = 1 ? b : c" << EOF
  16
+x = 1 ? b : c
  17
+EOF
  18
+expect <<EOF
  19
+x = b
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "fold conditional: x = 0 ? b : c" << EOF
  25
+x = 0 ? b : c
  26
+EOF
  27
+expect <<EOF
  28
+x = c
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "fold conditional: x = if(a, b, c) (nothing to fold)" << EOF
  34
+x = if(a, b, c)
  35
+EOF
  36
+expect <<EOF
  37
+x = (if a b c)
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "fold conditional: x = if(1, b, c)" << EOF
  43
+x = if(1, b, c)
  44
+EOF
  45
+expect <<EOF
  46
+x = b
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "fold conditional: x = if(0, b,c)" << EOF
  52
+x = if(0, b, c)
  53
+EOF
  54
+expect <<EOF
  55
+x = c
  56
+EOF
  57
+
  58
+###############################################################################
146  src/compiler/test/fold
... ...
@@ -0,0 +1,146 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "constant folding: x = 1+2" << EOF
  7
+x = 1+2
  8
+EOF
  9
+expect <<EOF
  10
+x = 3
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "constant folding: x = 1-2" << EOF
  16
+x = 1-2
  17
+EOF
  18
+expect <<EOF
  19
+x = -1
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "constant folding: x = 2*3" << EOF
  25
+x = 2*3
  26
+EOF
  27
+expect <<EOF
  28
+x = 6
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "constant folding: x = 4/5" << EOF
  34
+x = 4/5
  35
+EOF
  36
+expect <<EOF
  37
+x = 0.8
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "constant folding: x = 2.8 % 0.5" << EOF
  43
+x = 2.8 % 0.5
  44
+EOF
  45
+expect <<EOF
  46
+x = 0.3
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "constant folding: x = a+1 (nothign to fold)" << EOF
  52
+x = a+1
  53
+EOF
  54
+expect <<EOF
  55
+x = (+ a 1)
  56
+EOF
  57
+
  58
+#------------------------------------------------------------------------------
  59
+
  60
+ptest "constant folding: x = 1+b (nothign to fold)" << EOF
  61
+x = 1+b
  62
+EOF
  63
+expect <<EOF
  64
+x = (+ 1 b)
  65
+EOF
  66
+
  67
+#------------------------------------------------------------------------------
  68
+
  69
+ptest "constant folding: above" << EOF
  70
+x = above(1, 2)
  71
+y = above(2, 1)
  72
+z = above(1, 1)
  73
+EOF
  74
+expect <<EOF
  75
+x = 0
  76
+y = 1
  77
+z = 0
  78
+EOF
  79
+
  80
+#------------------------------------------------------------------------------
  81
+
  82
+ptest "constant folding: below" << EOF
  83
+x = below(1, 2)
  84
+y = below(2, 1)
  85
+z = below(1, 1)
  86
+EOF
  87
+expect <<EOF
  88
+x = 1
  89
+y = 0
  90
+z = 0
  91
+EOF
  92
+
  93
+#------------------------------------------------------------------------------
  94
+
  95
+ptest "constant folding: equal" << EOF
  96
+x = equal(1, 2)
  97
+y = equal(2, 1)
  98
+z = equal(1, 1)
  99
+EOF
  100
+expect <<EOF
  101
+x = 0
  102
+y = 0
  103
+z = 1
  104
+EOF
  105
+
  106
+#------------------------------------------------------------------------------
  107
+
  108
+ptest "constant folding: max" << EOF
  109
+x = max(2, 3)
  110
+y = max(3, 2)
  111
+EOF
  112
+expect <<EOF
  113
+x = 3
  114
+y = 3
  115
+EOF
  116
+
  117
+#------------------------------------------------------------------------------
  118
+
  119
+ptest "constant folding: min" << EOF
  120
+x = min(2, 3)
  121
+y = min(3, 2)
  122
+EOF
  123
+expect <<EOF
  124
+x = 2
  125
+y = 2
  126
+EOF
  127
+
  128
+#------------------------------------------------------------------------------
  129
+
  130
+ptest "constant folding: unary minus" << EOF
  131
+x = -2
  132
+EOF
  133
+expect <<EOF
  134
+x = -2
  135
+EOF
  136
+
  137
+#------------------------------------------------------------------------------
  138
+
  139
+ptest "constant folding: sqr" << EOF
  140
+x = sqr(3)
  141
+EOF
  142
+expect <<EOF
  143
+x = 9
  144
+EOF
  145
+
  146
+###############################################################################
130  src/compiler/test/prec
... ...
@@ -0,0 +1,130 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "precedence: x = a+b*c+d" <<EOF
  7
+x = a+b*c+d
  8
+EOF
  9
+expect <<EOF
  10
+x = (+ (+ a (* b c)) d)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "precedence: x = a+b/c+d" <<EOF
  16
+x = a+b/c+d
  17
+EOF
  18
+expect <<EOF
  19
+x = (+ (+ a (/ b c)) d)
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "precedence: x = a+b%c+d" <<EOF
  25
+x = a+b%c+d
  26
+EOF
  27
+expect <<EOF
  28
+x = (+ (+ a (% b c)) d)
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "precedence: x = a-b*c-d" <<EOF
  34
+x = a-b*c-d
  35
+EOF
  36
+expect <<EOF
  37
+x = (- (- a (* b c)) d)
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "precedence: x = a-b/c-d" <<EOF
  43
+x = a-b/c-d
  44
+EOF
  45
+expect <<EOF
  46
+x = (- (- a (/ b c)) d)
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "precedence: x = a-b%c-d" <<EOF
  52
+x = a-b%c-d
  53
+EOF
  54
+expect <<EOF
  55
+x = (- (- a (% b c)) d)
  56
+EOF
  57
+
  58
+#------------------------------------------------------------------------------
  59
+
  60
+ptest "precedence: x = -a*b" <<EOF
  61
+x = -a*b
  62
+EOF
  63
+expect <<EOF
  64
+x = (* (! a) b)
  65
+EOF
  66
+
  67
+#------------------------------------------------------------------------------
  68
+
  69
+ptest "precedence: x = a/b" <<EOF
  70
+x = -a/b
  71
+EOF
  72
+expect <<EOF
  73
+x = (/ (! a) b)
  74
+EOF
  75
+
  76
+#------------------------------------------------------------------------------
  77
+
  78
+ptest "precedence: x = a%b" <<EOF
  79
+x = -a%b
  80
+EOF
  81
+expect <<EOF
  82
+x = (% (! a) b)
  83
+EOF
  84
+
  85
+#------------------------------------------------------------------------------
  86
+
  87
+ptest "precedence: x = -sin(a)" <<EOF
  88
+x = -sin(a)
  89
+EOF
  90
+expect <<EOF
  91
+x = (! (sin a))
  92
+EOF
  93
+
  94
+#------------------------------------------------------------------------------
  95
+
  96
+ptest "precedence: x = -max(a, b)" <<EOF
  97
+x = -max(a, b)
  98
+EOF
  99
+expect <<EOF
  100
+x = (! (max a b))
  101
+EOF
  102
+
  103
+#------------------------------------------------------------------------------
  104
+
  105
+ptest "precedence: x = -if(a, b, c)" <<EOF
  106
+x = -if(a, b, c)
  107
+EOF
  108
+expect <<EOF
  109
+x = (! (if a b c))
  110
+EOF
  111
+
  112
+#------------------------------------------------------------------------------
  113
+
  114
+ptest "precedence: x = -(a+b)" <<EOF
  115
+x = -(a+b)
  116
+EOF
  117
+expect <<EOF
  118
+x = (! (+ a b))
  119
+EOF
  120
+
  121
+#------------------------------------------------------------------------------
  122
+
  123
+ptest "precedence: x = a--b" <<EOF
  124
+x = a--b
  125
+EOF
  126
+expect <<EOF
  127
+x = (- a (! b))
  128
+EOF
  129
+
  130
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.