Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 9 files changed
  • 0 comments
  • 1 contributor
Jan 27, 2012
Werner Almesberger ptest: -c -c compiles into FPVM code and dumps the result
Also changed compiler.c to export init_fpvm, for sharing with ptest.
ed83089
Werner Almesberger tests: new command "pvm" to generate and pretty-print FPVM code
The prettification is done by ptest/prvm.pl
1a05965
Werner Almesberger compiler: completed boolean "and" and "or"
This commit:

- fixes a bug in the parser that made it not recognize && and ||
  (it did accept band and bor),
- adds op_band and op_bor to ptest.c, and
- adds test cases "and" and "or"
6e741aa
Werner Almesberger test/Common: don't require argument of equiv1 and equiv2 to be a file…
… name

This changes the use from  equiv1 FILE  to  equiv1 <FILE
With the change, we can also pass simpler expressions directly
on the command line, with  equiv1 "EXPRESSION"

Also updated test/rewrite
933ac8f
Werner Almesberger test/rewrite: added two examples from Unchained - A Matter Of Taste (…
…Remix)
a5468c2
2  src/compiler/compiler.c
@@ -60,7 +60,7 @@ static void comp_report(struct compiler_sc *sc, const char *format, ...)
60 60
 	sc->rmc(outbuf);
61 61
 }
62 62
 
63  
-static void init_fpvm(struct fpvm_fragment *fragment, int vector_mode)
  63
+void init_fpvm(struct fpvm_fragment *fragment, int vector_mode)
64 64
 {
65 65
 	/*
66 66
 	 * We need to pass these through unique() because the parser does
1  src/compiler/compiler.h
@@ -247,6 +247,7 @@ struct patch {
247 247
 
248 248
 typedef void (*report_message)(const char *);
249 249
 
  250
+void init_fpvm(struct fpvm_fragment *fragment, int vector_mode);
250 251
 struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
251 252
 struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
252 253
 struct patch *patch_copy(struct patch *p);
2  src/compiler/parser.y
@@ -351,7 +351,7 @@ expr(N) ::= cond_expr(A). {
351 351
 	N = A;
352 352
 }
353 353
 
354  
-cond_expr(N) ::= equal_expr(A). {
  354
+cond_expr(N) ::= bool_or_expr(A). {
355 355
 	N = A;
356 356
 }
357 357
 
29  src/compiler/ptest/prvm.pl
... ...
@@ -0,0 +1,29 @@
  1
+#!/usr/bin/perl
  2
+#
  3
+# prvm.pl - FPVM code dump prettifier
  4
+#
  5
+# Copyright 2012 by Werner Almesberger
  6
+#
  7
+# This program is free software: you can redistribute it and/or modify
  8
+# it under the terms of the GNU General Public License as published by
  9
+# the Free Software Foundation, version 3 of the License.
  10
+#
  11
+
  12
+$r{"R0002"} = "R2";
  13
+while (<>) {
  14
+	next if /^==/;
  15
+	if (/^(R\S+)\s(.*)/) {
  16
+		$r = $1;
  17
+		$v = $2;
  18
+		$v = sprintf("%g", $v) if $v =~ /^[-0-9]/;
  19
+		$r{$r} = $v if $r ne "R0002";
  20
+		next;
  21
+	}
  22
+	for $r (keys %r) {
  23
+		s/\b$r\b/$r{$r}/g;
  24
+	}
  25
+	s/<R2>//;
  26
+	s/ +/ /g;
  27
+	s/^\d{4}: //;
  28
+	print;
  29
+}
100  src/compiler/ptest/ptest.c
@@ -138,6 +138,12 @@ static void dump_ast(const struct ast_node *ast)
138 138
 	case op_bnot:
139 139
 		op("!", ast);
140 140
 		break;
  141
+	case op_band:
  142
+		op("&&", ast);
  143
+		break;
  144
+	case op_bor:
  145
+		op("||", ast);
  146
+		break;
141 147
 	default:
142 148
 		abort();
143 149
 	}
@@ -344,33 +350,62 @@ static void compile(const char *pgm)
344 350
 }
345 351
 
346 352
 
347  
-#if 0
348  
-static void compile_raw(const char *pgm)
  353
+static const char *assign_raw(struct parser_comm *comm,
  354
+    struct sym *sym, struct ast_node *node)
349 355
 {
350  
-	struct patch patch;
351  
-	struct compiler_sc sc = {
352  
-		.p = &patch
353  
-	};
354  
-	struct patch *p;
  356
+	struct fpvm_fragment *frag = comm->u.fragment;
355 357
 
356  
-	memset(&patch, 0, sizeof(patch));
357  
-	patch.rmc = report;
  358
+	if(fpvm_do_assign(frag, &sym->fpvm_sym, node))
  359
+		return NULL;
  360
+	else
  361
+		return strdup(fpvm_get_last_error(frag));
  362
+}
  363
+
  364
+
  365
+static const char *assign_raw_fail(struct parser_comm *comm,
  366
+    struct sym *sym, struct ast_node *node)
  367
+{
  368
+	return strdup("unsupported assignment mode");
  369
+}
358 370
 
359  
-	if (!parse_patch(&sc, pgm)) {
360  
-		symtab_free();
361  
-		exit(1);
362  
-	}
363  
-	patch.perframe_prog_length = fpvm_default_schedule(&sc.pfv_fragment,
364  
-	    (unsigned *) patch.perframe_prog,
365  
-	    (unsigned *) patch.perframe_regs);
366  
-	patch.pervertex_prog_length = fpvm_default_schedule(&sc.pvv_fragment,
367  
-	    (unsigned *) patch.pervertex_prog,
368  
-	    (unsigned *) patch.pervertex_regs);
369 371
 
  372
+static const char *assign_image_fail(struct parser_comm *comm,
  373
+    int number, const char *name)
  374
+{
370 375
 	if (!quiet)
371  
-		show_patch(p);
  376
+		printf("image %d = \"%s\"\n", number, name);
  377
+	return NULL;
  378
+}
  379
+
  380
+
  381
+static void compile_vm(const char *pgm)
  382
+{
  383
+	struct fpvm_fragment fragment;
  384
+	struct parser_comm comm = {
  385
+		.u.fragment = &fragment,
  386
+		.assign_default = assign_raw,
  387
+		.assign_per_frame = assign_raw,
  388
+		.assign_per_vertex = assign_raw_fail,
  389
+		.assign_image_name = assign_image_fail,
  390
+	};
  391
+	int ok;
  392
+
  393
+	init_fpvm(&fragment, 0);
  394
+	fpvm_set_bind_mode(&fragment, FPVM_BIND_ALL);
  395
+	symtab_init();
  396
+	ok = parse(pgm, TOK_START_ASSIGN, &comm);
  397
+
  398
+	if (ok)
  399
+		fpvm_dump(&fragment);
  400
+	symtab_free();
  401
+	if (ok)
  402
+		return;
  403
+
  404
+	fflush(stdout);
  405
+	fprintf(stderr, "%s\n", comm.msg);
  406
+	free((void *) comm.msg);
  407
+	exit(1);
372 408
 }
373  
-#endif
374 409
 
375 410
 
376 411
 static void free_buffer(void)
@@ -382,8 +417,9 @@ static void free_buffer(void)
382 417
 static void usage(const char *name)
383 418
 {
384 419
 	fprintf(stderr,
385  
-"usage: %s [-c|-f error] [-n runs] [-q] [-s] [-Wwarning...] [expr]\n\n"
  420
+"usage: %s [-c [-c]|-f error] [-n runs] [-q] [-s] [-Wwarning...] [expr]\n\n"
386 421
 "  -c        generate code and dump generated code (unless -q is set)\n"
  422
+"  -c -c     generate and dump VM code\n"
387 423
 "  -f error  fail any assignment with specified error message\n"
388 424
 "  -n runs   run compilation repeatedly (default: run only once)\n"
389 425
 "  -q        quiet operation\n"
@@ -407,7 +443,7 @@ int main(int argc, char **argv)
407 443
 	while ((c = getopt(argc, argv, "cf:n:qsW:")) != EOF)
408 444
 		switch (c) {
409 445
 		case 'c':
410  
-			codegen = 1;
  446
+			codegen++;
411 447
 			break;
412 448
 		case 'f':
413 449
 			fail = optarg;
@@ -450,12 +486,20 @@ int main(int argc, char **argv)
450 486
 		usage(*argv);
451 487
 	}
452 488
 
453  
-	while (repeat--) {
454  
-		if (codegen)
455  
-			compile(buffer);
456  
-		else
  489
+	while (repeat--)
  490
+		switch (codegen) {
  491
+		case 0:
457 492
 			parse_only(buffer);
458  
-	}
  493
+			break;
  494
+		case 1:
  495
+			compile(buffer);
  496
+			break;
  497
+		case 2:
  498
+			compile_vm(buffer);
  499
+			break;
  500
+		default:
  501
+			usage(*argv);
  502
+		}
459 503
 
460 504
 	return 0;
461 505
 }
19  src/compiler/test/Common
@@ -67,9 +67,8 @@ sedit()
67 67
 equiv1()
68 68
 {
69 69
 	echo -n "$1: " 1>&2
70  
-	one=$2
71  
-	shift 2
72  
-	$VALGRIND ${PTST:-../ptest/ptest} "$@" <"$one" >_out 2>&1 || {
  70
+	shift
  71
+	$VALGRIND ${PTST:-../ptest/ptest} "$@" >_out 2>&1 || {
73 72
 		echo FAILED "($SCRIPT)" 1>&2
74 73
 		cat _out
75 74
 		rm -f _out
@@ -80,9 +79,7 @@ equiv1()
80 79
 
81 80
 equiv2()
82 81
 {
83  
-	two=$1
84  
-	shift
85  
-	$VALGRIND ${PTST:-../ptest/ptest} "$@" <"$two" >_two 2>&1 || {
  82
+	$VALGRIND ${PTST:-../ptest/ptest} "$@" >_two 2>&1 || {
86 83
 		echo FAILED "($SCRIPT)" 1>&2
87 84
 		cat _two
88 85
 		rm -f _out _two
@@ -98,3 +95,13 @@ equiv2()
98 95
 	rm -f _out _two _diff
99 96
 	passed=`expr ${passed:-0} + 1`
100 97
 }
  98
+
  99
+
  100
+fpvm()
  101
+{
  102
+	one=$1
  103
+	shift
  104
+	ptest "$one" -c -c "$@"
  105
+	${PRVM:-../ptest/prvm.pl} _out >_tmp || exit 1
  106
+	mv _tmp _out
  107
+}
79  src/compiler/test/and
... ...
@@ -0,0 +1,79 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "and: band(a, b)" << EOF
  7
+sx = band(a, b)
  8
+EOF
  9
+expect <<EOF
  10
+sx = (&& a b)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "and: a && b" << EOF
  16
+sx = a && b
  17
+EOF
  18
+expect <<EOF
  19
+sx = (&& a b)
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "and: 0 && 0" << EOF
  25
+sx = 0 && 0
  26
+EOF
  27
+expect <<EOF
  28
+sx = 0
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "and: 1 && 0" << EOF
  34
+sx = 1 && 0
  35
+EOF
  36
+expect <<EOF
  37
+sx = 0
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "and: 0 && 1" << EOF
  43
+sx = 0 && 1
  44
+EOF
  45
+expect <<EOF
  46
+sx = 0
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "and: 1 && 1" << EOF
  52
+sx = 1 && 1
  53
+EOF
  54
+expect <<EOF
  55
+sx = 1
  56
+EOF
  57
+
  58
+#------------------------------------------------------------------------------
  59
+
  60
+ptest "and: a && b == c" << EOF
  61
+sx = a && b == c
  62
+EOF
  63
+expect <<EOF
  64
+sx = (&& a (equal b c))
  65
+EOF
  66
+
  67
+#------------------------------------------------------------------------------
  68
+
  69
+fpvm "and: a && b (generate code)" <<EOF
  70
+sx = a && b
  71
+EOF
  72
+expect <<EOF
  73
+COPY a -> R2
  74
+IF 1,0 -> R-003
  75
+COPY b -> R2
  76
+IF R-003,0 -> sx
  77
+EOF
  78
+
  79
+###############################################################################
79  src/compiler/test/or
... ...
@@ -0,0 +1,79 @@
  1
+#!/bin/sh
  2
+. ./Common
  3
+
  4
+###############################################################################
  5
+
  6
+ptest "or: bor(a, b)" << EOF
  7
+sx = bor(a, b)
  8
+EOF
  9
+expect <<EOF
  10
+sx = (|| a b)
  11
+EOF
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+ptest "or: a || b" << EOF
  16
+sx = a || b
  17
+EOF
  18
+expect <<EOF
  19
+sx = (|| a b)
  20
+EOF
  21
+
  22
+#------------------------------------------------------------------------------
  23
+
  24
+ptest "or: 0 || 0" << EOF
  25
+sx = 0 || 0
  26
+EOF
  27
+expect <<EOF
  28
+sx = 0
  29
+EOF
  30
+
  31
+#------------------------------------------------------------------------------
  32
+
  33
+ptest "or: 1 || 0" << EOF
  34
+sx = 1 || 0
  35
+EOF
  36
+expect <<EOF
  37
+sx = 1
  38
+EOF
  39
+
  40
+#------------------------------------------------------------------------------
  41
+
  42
+ptest "or: 0 || 1" << EOF
  43
+sx = 0 || 1
  44
+EOF
  45
+expect <<EOF
  46
+sx = 1
  47
+EOF
  48
+
  49
+#------------------------------------------------------------------------------
  50
+
  51
+ptest "or: 1 || 1" << EOF
  52
+sx = 1 || 1
  53
+EOF
  54
+expect <<EOF
  55
+sx = 1
  56
+EOF
  57
+
  58
+#------------------------------------------------------------------------------
  59
+
  60
+ptest "or: a || b && c" << EOF
  61
+sx = a || b && c
  62
+EOF
  63
+expect <<EOF
  64
+sx = (|| a (&& b c))
  65
+EOF
  66
+
  67
+#------------------------------------------------------------------------------
  68
+
  69
+fpvm "or: a || b (generate code)" <<EOF
  70
+sx = a || b
  71
+EOF
  72
+expect <<EOF
  73
+COPY a -> R2
  74
+IF 1,0 -> R-003
  75
+COPY b -> R2
  76
+IF 1,R-003 -> sx
  77
+EOF
  78
+
  79
+###############################################################################
45  src/compiler/test/rewrite
@@ -6,8 +6,49 @@
6 6
 PATCHDIR=../../../patches
7 7
 
8 8
 equiv1 "rewrite: prettier Krash - Digital Flame" \
9  
-    "$PATCHDIR/Krash - Digital Flame.fnp"
  9
+    <"$PATCHDIR/Krash - Digital Flame.fnp"
10 10
 sedit s/swapcolour/swap/g
11  
-equiv2 Data/flame.fnp
  11
+equiv2 <Data/flame.fnp
  12
+
  13
+#------------------------------------------------------------------------------
  14
+
  15
+#
  16
+# The original used rand(3) instead of sin(3), but we don't have that (yet ?)
  17
+#
  18
+
  19
+equiv1 "rewrite: per_frame_2 from Unchained - A Matter Of Taste (Remix)" <<EOF
  20
+per_frame_2=entropy=if(bnot(entropy),2,if(equal(pulse,-9.42),1+sin(3),entropy));
  21
+EOF
  22
+equiv2 <<EOF
  23
+per_frame:
  24
+	entropy = !entropy ? 2 :
  25
+	    pulse == -9.42 ? 1+sin(3) : entropy;
  26
+EOF
  27
+
  28
+#------------------------------------------------------------------------------
  29
+
  30
+equiv1 "rewrite: per_frame_12 from Unchained - A Matter Of Taste (Remix)" <<EOF
  31
+per_frame_12=pulse=if(above(abs(pulse),9.42),-9.42,pulse+.1*bor(bor(bass_changed*bnot(treb_changed),treb_changed*bnot(bass_changed))*bnot(mid_changed),mid_changed)+(mid+bass+treb)*entropy*.01);
  32
+EOF
  33
+equiv2 <<EOF
  34
+per_frame:
  35
+	pulse = abs(pulse) > 9.42 ? -9.42 :
  36
+	    pulse+
  37
+	    0.1*(
  38
+	        (bass_changed*!treb_changed || treb_changed*!bass_changed)*
  39
+		  !mid_changed ||
  40
+		mid_changed)+
  41
+	    (mid+bass+treb)*entropy*0.01;
  42
+EOF
  43
+
  44
+#
  45
+# This could be written even more cleanly as
  46
+#
  47
+#	pulse = abs(pulse) > 9.42 ? -9.42 :
  48
+#	    pulse+
  49
+#	    0.1*(mid_changed ? 1 :
  50
+#	        bass_changed*!treb_changed || treb_changed*!bass_changed)+
  51
+#	    0.01*(mid+bass+treb)*entropy;
  52
+#
12 53
 
13 54
 ###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.