Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 10 files changed
  • 0 comments
  • 1 contributor
12  patches/demo/wheel/wheel.fnp
@@ -93,16 +93,16 @@ per_frame:
93 93
 	image2_a = alpha2;
94 94
 
95 95
 	f1 = f1+(speed1-off1)*scale;
96  
-	f1 = f1 < 0 ? f1+24 : f1;
97  
-	f1 = f1 >= 24 ? f1-24 : f1;
  96
+	f1 = f1+24 if f1 < 0;
  97
+	f1 = f1-24 if f1 >= 24;
98 98
 	off1 = reset1 ? speed1 : start1 ? speed1-1/scale : off1;
99  
-	off1 = rev1 ? 2*speed1-off1 : off1;
  99
+	off1 = 2*speed1-off1 if rev1;
100 100
 
101 101
 	f2 = f2+(speed2-off2)*scale;
102  
-	f2 = f2 < 0 ? f2+24 : f2;
103  
-	f2 = f2 >= 24 ? f2-24 : f2;
  102
+	f2 = f2+24 if f2 < 0;
  103
+	f2 = f2-24 if f2 >= 24;
104 104
 	off2 = reset2 ? speed2 : start2 ? speed2-1/scale : off2;
105  
-	off2 = rev2 ? 2*speed2-off2 : off2;
  105
+	off2 = 2*speed2-off2 if rev2;
106 106
 
107 107
 	image1_index = f1;
108 108
 	image2_index = f2;
20  src/compiler/compiler.c
@@ -284,7 +284,7 @@ static void pvv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
284 284
 		r->regs->pvv = sc->p->pervertex_regs+reg;
285 285
 }
286 286
 
287  
-static bool init_pvv(struct compiler_sc *sc)
  287
+static bool init_pvv(struct compiler_sc *sc, int framework)
288 288
 {
289 289
 	int i;
290 290
 
@@ -294,7 +294,7 @@ static bool init_pvv(struct compiler_sc *sc)
294 294
 	fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
295 295
 
296 296
 	fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_SOURCE);
297  
-	if(!compile_chunk(&sc->pvv_fragment, INIT_PVV_FNP))
  297
+	if(framework && !compile_chunk(&sc->pvv_fragment, INIT_PVV_FNP))
298 298
 		goto fail_assign;
299 299
 	fpvm_set_bind_mode(&sc->pvv_fragment, FPVM_BIND_ALL);
300 300
 
@@ -474,8 +474,8 @@ static bool parse_patch(struct compiler_sc *sc, const char *patch_code)
474 474
 	return ok;
475 475
 }
476 476
 
477  
-struct patch *patch_compile(const char *basedir, const char *patch_code,
478  
-    report_message rmc)
  477
+struct patch *patch_do_compile(const char *basedir, const char *patch_code,
  478
+    report_message rmc, int framework)
479 479
 {
480 480
 	struct compiler_sc *sc;
481 481
 	struct patch *p;
@@ -507,14 +507,14 @@ struct patch *patch_compile(const char *basedir, const char *patch_code,
507 507
 
508 508
 	load_defaults(sc);
509 509
 	if(!init_pfv(sc)) goto fail;
510  
-	if(!init_pvv(sc)) goto fail;
  510
+	if(!init_pvv(sc, framework)) goto fail;
511 511
 
512 512
 	if(!parse_patch(sc, patch_code))
513 513
 		goto fail;
514 514
 
515  
-	if(!finalize_pfv(sc)) goto fail;
  515
+	if(framework && !finalize_pfv(sc)) goto fail;
516 516
 	if(!schedule_pfv(sc)) goto fail;
517  
-	if(!finalize_pvv(sc)) goto fail;
  517
+	if(framework && !finalize_pvv(sc)) goto fail;
518 518
 	if(!schedule_pvv(sc)) goto fail;
519 519
 
520 520
 #ifndef STANDALONE
@@ -532,6 +532,12 @@ struct patch *patch_compile(const char *basedir, const char *patch_code,
532 532
 	return NULL;
533 533
 }
534 534
 
  535
+struct patch *patch_compile(const char *basedir, const char *patch_code,
  536
+    report_message rmc)
  537
+{
  538
+	return patch_do_compile(basedir, patch_code, rmc, 1);
  539
+}
  540
+
535 541
 struct patch *patch_compile_filename(const char *filename,
536 542
     const char *patch_code, report_message rmc)
537 543
 {
9  src/compiler/compiler.h
@@ -267,8 +267,17 @@ typedef void (*report_message)(const char *);
267 267
 struct compiler_sc;
268 268
 
269 269
 void init_fpvm(struct fpvm_fragment *fragment, int vector_mode);
  270
+
  271
+/*
  272
+ * Flickernoise only uses patch_compile. patch_do_compile allows disabling
  273
+ * the patch framework, which is useful for code analysis in ptest.
  274
+ */
  275
+
  276
+struct patch *patch_do_compile(const char *basedir, const char *patch_code,
  277
+    report_message rmc, int framework);
270 278
 struct patch *patch_compile(const char *basedir, const char *patch_code,
271 279
     report_message rmc);
  280
+
272 281
 struct patch *patch_compile_filename(const char *filename,
273 282
     const char *patch_code, report_message rmc);
274 283
 struct stimuli *compiler_get_stimulus(struct compiler_sc *sc);
38  src/compiler/parser.y
@@ -35,6 +35,7 @@
35 35
 
36 36
 
37 37
 struct yyParser;
  38
+int syntax_is_new_style = 0;
38 39
 static void yy_parse_failed(struct yyParser *yypParser);
39 40
 
40 41
 typedef const char *(*assign_callback)(struct parser_comm *comm,
@@ -58,6 +59,7 @@ static struct stim_db_midi *midi_dev;
58 59
 			return;					\
59 60
 		}						\
60 61
 		state->style = which;				\
  62
+		syntax_is_new_style = which == new_style;	\
61 63
 	} while (0)
62 64
 
63 65
 static const enum ast_op tok2op[] = {
@@ -79,6 +81,7 @@ static const enum ast_op tok2op[] = {
79 81
 	[TOK_I2F]	= op_i2f,
80 82
 	[TOK_F2I]	= op_f2i,
81 83
 	[TOK_IF]	= op_if,
  84
+	[TOK_IF_NEW]	= op_if,
82 85
 	[TOK_TSIGN]	= op_tsign,
83 86
 	[TOK_QUAKE]	= op_quake,
84 87
 	[TOK_SQR]	= op_sqr,
@@ -155,11 +158,15 @@ static struct ast_node *constant(float n)
155 158
 static struct ast_node *conditional(struct ast_node *a,
156 159
     struct ast_node *b, struct ast_node *c)
157 160
 {
158  
-	if(a->op == op_bnot) {
  161
+	while(a->op == op_bnot) {
159 162
 		struct ast_node *next = a->contents.branches.a;
  163
+		struct ast_node *tmp;
160 164
 
161 165
 		parse_free_one(a);
162  
-		return node_op(op_if, next, c, b);
  166
+		a = next;
  167
+		tmp = b;
  168
+		b = c;
  169
+		c = tmp;
163 170
 	}
164 171
 	if(a->op != op_constant)
165 172
 		return node_op(op_if, a, b, c);
@@ -249,6 +256,7 @@ static void free_file_list(struct file_list *l)
249 256
 %destructor primary_expr { free($$); }
250 257
 
251 258
 %type context {assign_callback}
  259
+%type opt_if {struct ast_node *}
252 260
 %type opt_arg {struct ast_node *}
253 261
 %type midi_dev_type {enum stim_midi_dev_type}
254 262
 %type midi_fn_type {enum stim_midi_fn_type}
@@ -256,6 +264,7 @@ static void free_file_list(struct file_list *l)
256 264
 %type file_list {struct file_list *}
257 265
 %type opt_tag {struct id *}
258 266
 
  267
+%destructor opt_if { free($$); }
259 268
 %destructor opt_arg { parse_free($$); }
260 269
 %destructor file_list { free_file_list($$); }
261 270
 %destructor opt_tag { free($$); }
@@ -310,7 +319,7 @@ assignments ::= .
310 319
 /* ----- Variable assignments ---------------------------------------------- */
311 320
 
312 321
 
313  
-assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
  322
+assignment ::= ident(I) TOK_ASSIGN expr(N) opt_if(IF) opt_semi. {
314 323
 	I->sym->flags |= SF_ASSIGNED;
315 324
 	/*
316 325
 	 * The conditions are as follows:
@@ -332,10 +341,20 @@ assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
332 341
 			    "to zero");
333 342
 			return;
334 343
 		}
  344
+		if(IF) {
  345
+			FAIL("initialization cannot be conditional");
  346
+			return;
  347
+		}
335 348
 		IS_STYLE(new_style);
336 349
 	} else {
337 350
 		const char *msg;
338 351
 
  352
+		if(IF) {
  353
+			struct ast_node *var;
  354
+
  355
+			var = node(I->token, I->sym, NULL, NULL, NULL);
  356
+			N = conditional(IF, N, var);
  357
+		}
339 358
 		msg = state->assign(state->comm, I->sym, N);
340 359
 		free(I);
341 360
 		if(msg) {
@@ -344,9 +363,17 @@ assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
344 363
 			return;
345 364
 		}
346 365
 	}
  366
+	/*
  367
+	 * Q: Why don't we parse_free(IF) ?
  368
+	 * A: If IF is non-NULL, it's now in the AST under N and gets free
  369
+	 * with it.
  370
+	 */
347 371
 	parse_free(N);
348 372
 }
349 373
 
  374
+opt_if(IF) ::= .			{ IF = NULL; }
  375
+opt_if(IF) ::= TOK_IF_NEW expr(E).	{ IF = E; }
  376
+
350 377
 
351 378
 /* ----- MIDI device database ---------------------------------------------- */
352 379
 
@@ -757,6 +784,11 @@ primary_expr(N) ::= TOK_IF TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_COMMA
757 784
 	N = conditional(A, B, C);
758 785
 }
759 786
 
  787
+primary_expr(N) ::= TOK_IF_NEW TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_COMMA
  788
+    expr(C) TOK_RPAREN. {
  789
+	N = conditional(A, B, C);
  790
+}
  791
+
760 792
 
761 793
 /* ----- Primary expressions ----------------------------------------------- */
762 794
 
2  src/compiler/parser_itf.h
@@ -54,6 +54,8 @@ struct parser_state {
54 54
 	} style; 
55 55
 };
56 56
 
  57
+extern int syntax_is_new_style;
  58
+
57 59
 void *ParseAlloc(void *(*mallocProc)(size_t));
58 60
 void ParseFree(void *p, void (*freeProc)(void*));
59 61
 void Parse(void *yyp, int yymajor, struct id *yyminor,
14  src/compiler/ptest/ptest.c
@@ -401,11 +401,11 @@ static void play_midi(struct patch *patch)
401 401
 }
402 402
 
403 403
 
404  
-static void compile(const char *pgm)
  404
+static void compile(const char *pgm, int framework)
405 405
 {
406 406
 	struct patch *patch;
407 407
 
408  
-	patch = patch_compile("/", pgm, report);
  408
+	patch = patch_do_compile("/", pgm, report, framework);
409 409
 	if (!patch) {
410 410
 		symtab_free();
411 411
 		exit(1);
@@ -497,10 +497,11 @@ static void free_buffer(void)
497 497
 static void usage(const char *name)
498 498
 {
499 499
 	fprintf(stderr,
500  
-"usage: %s [-c [-c]|-f error] [-m [chan.]ctrl=value ...] [-n runs]\n"
  500
+"usage: %s [-c [-c [-c]]|-f error] [-m [chan.]ctrl=value ...] [-n runs]\n"
501 501
 "       %*s [-q] [-s] [-v var] [-Wwarning ...] [expr]\n\n"
502  
-"  -c        generate code and dump generated code (unless -q is set)\n"
  502
+"  -c        generate PFPU code and dump generated code (unless -q is set)\n"
503 503
 "  -c -c     generate and dump VM code\n"
  504
+"  -c -c -c  generate and dump PFPU code (without patch framework)\n"
504 505
 "  -f error  fail any assignment with specified error message\n"
505 506
 "  -m [chan.]ctrl=value\n"
506 507
 "            send a MIDI message to the stimuli subsystem\n"
@@ -582,11 +583,14 @@ int main(int argc, char **argv)
582 583
 			parse_only(buffer);
583 584
 			break;
584 585
 		case 1:
585  
-			compile(buffer);
  586
+			compile(buffer, 1);
586 587
 			break;
587 588
 		case 2:
588 589
 			compile_vm(buffer);
589 590
 			break;
  591
+		case 3:
  592
+			compile(buffer, 0);
  593
+			break;
590 594
 		default:
591 595
 			usage(*argv);
592 596
 		}
4  src/compiler/scanner.re
@@ -21,6 +21,7 @@
21 21
 #include <malloc.h>
22 22
 
23 23
 #include "symtab.h"
  24
+#include "parser_itf.h" /* for syntax_is_new_style */
24 25
 #include "scanner.h"
25 26
 
26 27
 #define YYCTYPE     unsigned char
@@ -146,7 +147,8 @@ int scan(struct scanner *s)
146 147
 		<N>"f2i"		{ return TOK_F2I; }
147 148
 		<N>"icos"		{ return TOK_ICOS; }
148 149
 		<N>"i2f"		{ return TOK_I2F; }
149  
-		<N>"if"			{ return TOK_IF; }
  150
+		<N>"if"			{ return syntax_is_new_style ?
  151
+					    TOK_IF_NEW : TOK_IF; }
150 152
 		<N>"int"		{ return TOK_INT; }
151 153
 		<N>"invsqrt"		{ return TOK_INVSQRT; }
152 154
 		<N>"isin"		{ return TOK_ISIN; }
17  src/compiler/test/dualuse
@@ -14,7 +14,7 @@ EOF
14 14
 #------------------------------------------------------------------------------
15 15
 
16 16
 ptest "dual use: sin = sqr-if" <<EOF
17  
-per_frame:
  17
+per_frame=
18 18
 sin = sqr-if
19 19
 EOF
20 20
 expect <<EOF
@@ -23,12 +23,23 @@ EOF
23 23
 
24 24
 #------------------------------------------------------------------------------
25 25
 
26  
-ptest "dual use: if = max*int" <<EOF
27  
-per_frame:
  26
+ptest "dual use: if = max*int (old style)" <<EOF
  27
+per_frame=
28 28
 if = max*int
29 29
 EOF
30 30
 expect <<EOF
31 31
 per_frame = if = (* (max) (int))
32 32
 EOF
33 33
 
  34
+#------------------------------------------------------------------------------
  35
+
  36
+ptest_fail "dual use: if = max*int (new style)" <<EOF
  37
+per_frame:
  38
+dummy = 0	/* scanner switches one token after section */
  39
+if = max*int
  40
+EOF
  41
+expect <<EOF
  42
+line 3: parse error near '='
  43
+EOF
  44
+
34 45
 ###############################################################################
9  src/compiler/test/not
@@ -137,4 +137,13 @@ expect <<EOF
137 137
 sx = (if a c b)
138 138
 EOF
139 139
 
  140
+#------------------------------------------------------------------------------
  141
+
  142
+ptest "not: if(!!a, b, c)" << EOF
  143
+sx = if(!!a, b, c)
  144
+EOF
  145
+expect <<EOF
  146
+sx = (if a b c)
  147
+EOF
  148
+
140 149
 ###############################################################################
34  src/compiler/test/stmtmod
... ...
@@ -0,0 +1,34 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "statement modifier: foo = foo+1 if cond" <<EOF
  7
+per_frame:
  8
+foo = foo+1 if cond
  9
+EOF
  10
+expect <<EOF
  11
+per_frame = foo = (if cond (+ foo 1) foo)
  12
+EOF
  13
+
  14
+#------------------------------------------------------------------------------
  15
+
  16
+ptest "statement modifier: foo = foo+1 if !cond" <<EOF
  17
+per_frame:
  18
+foo = foo+1 if !cond
  19
+EOF
  20
+expect <<EOF
  21
+per_frame = foo = (if cond foo (+ foo 1))
  22
+EOF
  23
+
  24
+#------------------------------------------------------------------------------
  25
+
  26
+ptest_fail "statement modifier: initial = 0 if 1 (error)" <<EOF
  27
+foo = 0
  28
+bar = 0 if 1
  29
+EOF
  30
+expect <<EOF
  31
+line 3: initialization cannot be conditional near 'EOF'
  32
+EOF
  33
+
  34
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.