Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/flickernoise
base: d1bdf36
...
head fork: m-labs/flickernoise
compare: 2aa0d1f
  • 8 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
Commits on Dec 12, 2011
Werner Almesberger wpwrak compiler/ptest/: FNP parser tester
ptest/ allows the FNP parser to run on the host, thus enabling easy
regression testing.
f02bee2
Werner Almesberger wpwrak compiler/test/: regression test framework and a few test cases 11e24d0
Werner Almesberger wpwrak patches/: fix various typos (PLEASE REVIEW !)
The strict syntax checking introduced with the following commit will
reject some patches. This is an attempt to correct the syntax errors
in what is hopefully a sensible way.
d897d81
Werner Almesberger wpwrak parser.y: make syntax errors fatal
While the lemon documentation [1] claims that, in the absence of
explicit error handling, all errors are fatal, this isn't true.
Instead, if the parser could enter a valid state by just ignoring
tokens, it would do so. This made things like  a = b + + c
"valid" expressions.

[1] At the end of http://www.hwaci.com/sw/lemon/lemon.html
e59ff46
Werner Almesberger wpwrak compiler: allow semicolons at the end of assignments
Semicolons are optional, but if they are used, they must appear at
the end of an assignment. (We may generalize this in the future.)
2d669f9
Werner Almesberger wpwrak compiler: added //-type comments 2c3f8c4
Werner Almesberger wpwrak compiler: added /*...*/-type comments 83d3ad0
Werner Almesberger wpwrak compiler: a bare "." is not a number
Before this patch, we accepted . as a synonym for zero. This is
probably not a good idea, and we may have better uses for it later.
2aa0d1f
2  patches/Idiot & Rovastar - Altars Of Madness 2 (X42 Mix).fnp
View
@@ -63,5 +63,5 @@ per_frame=fVideoEchoZoom=fVideoEchoZoom-.3*sin(time*(q5*0.01));
per_vertex=box=abs(x*2-0.4*sin(q3)) + abs(y*2+0.4*sin(q5));
per_vertex=q1 = 4.05+(sin(x+0.237*time)-cos(y+0.513*time));
per_vertex=zoom = if(above(box,1),q1*.1,zoom);
-per_vertex=rot = if(above(box,1),sin(0.885*time),0)*(x+y)-rad)*sin(q5)*0.5
+per_vertex=rot = if(above(box,1),sin(0.885*time),0)*(x+y)-rad*sin(q5)*0.5
2  patches/Lekernel & Rozzor & Aderassi - Video Cannon.fnp
View
@@ -52,7 +52,7 @@ per_frame=dx_r = equal(kick,2)*0.018*sin(6*time) + (1-equal(kick,2))*dx_r;
per_frame=dy_r = equal(kick,2)*0.015*sin(7*time) + (1-equal(kick,2))*dy_r;
per_frame=dy = dy + 2*dy_r * 0.5*sin(0.8*time);
per_frame=dx = dx + 2*dx_r * 0.5*sin(time);
-per_frame=warp = warp + if (below(kick,0), + 0.5*treb, 0);
+per_frame=warp = warp + if (below(kick,0), 0.5*treb, 0);
per_frame=q2 = kick;
per_frame=decay=below(sin(1.5*time),0.95)*0.15+0.85
per_vertex=rot = rot + 0.3*(0.2*sin(1-rad)*5 - 0.2*sin(0.05*rad)*5) * q2;
2  patches/Rovastar & Idiot24-7 - Balk Acid.fnp
View
@@ -50,7 +50,7 @@ per_frame=rot=rot+0.10*sin(time);
per_frame=mv_r=0.5 +0.5*sin(time*1.23);
per_frame=mv_b=0.5 + 0.5*sin(time*1.26);
per_frame=mv_g=0.5+ 0.5*sin(time*1.19);
-per_frame=wave_g=wave_g*+.20*sin(time*.13);
+per_frame=wave_g=wave_g+.20*sin(time*.13);
per_frame=wave_r=wave_r+.13*sin(time);
per_frame=wave_b=wave_b*sin(time);
per_frame=wave_x=wave_x-.5*sin(time*.13);
2  patches/Rozzor & Aderrasi - Canon (DMX out).fnp
View
@@ -62,7 +62,7 @@ per_frame=dx_r = equal(kick,2)*0.018*sin(6*time) + (1-equal(kick,2))*dx_r;
per_frame=dy_r = equal(kick,2)*0.015*sin(7*time) + (1-equal(kick,2))*dy_r;
per_frame=dy = dy + 2*dy_r * 0.5*sin(0.8*time);
per_frame=dx = dx + 2*dx_r * 0.5*sin(time);
-per_frame=warp = warp + if (below(kick,0), + 0.5*treb, 0);
+per_frame=warp = warp + if (below(kick,0), 0.5*treb, 0);
per_frame=q2 = kick;
per_vertex=rot = rot + 0.3*(0.2*sin(1-rad)*5 - 0.2*sin(0.05*rad)*5) * q2;
per_vertex=cx = if(above(dy,-.5),1-rot * 2,rot*q2);
23 src/compiler/Makefile
View
@@ -0,0 +1,23 @@
+.PHONY: all clean
+.PHONY: test tests valgrind
+
+all:
+ $(MAKE) -C ptest
+
+# ----- Tests -----------------------------------------------------------------
+
+test tests: all
+ LANG= sh -c \
+ 'passed=0 && cd test && \
+ for n in [a-z]*; do \
+ [ $$n != core ] && SCRIPT=$$n . ./$$n; done; \
+ echo "Passed all $$passed tests"'
+
+valgrind:
+ VALGRIND="valgrind -q" $(MAKE) tests
+
+# ----- Cleanup ---------------------------------------------------------------
+
+clean:
+ $(MAKE) -C ptest clean
+ rm -f test/core
7 src/compiler/parser.y
View
@@ -85,6 +85,7 @@
%type node {struct ast_node *}
%destructor node { free($$); }
+%syntax_error { yy_parse_failed(yypParser); }
start ::= TOK_START_EXPR node(N). {
state->comm->parseout = N;
@@ -99,11 +100,15 @@ assignments ::= assignments assignment.
assignments ::= .
-assignment ::= ident(I) TOK_ASSIGN node(N). {
+assignment ::= ident(I) TOK_ASSIGN node(N) opt_semi. {
fpvm_do_assign(state->comm->fragment, I->label, N);
fpvm_parse_free(N);
}
+opt_semi ::= opt_semi TOK_SEMI.
+
+opt_semi ::= .
+
node(N) ::= TOK_CONSTANT(C). {
N = node(TOK_CONSTANT, "", NULL, NULL, NULL);
N->contents.constant = C->constant;
63 src/compiler/ptest/Makefile
View
@@ -0,0 +1,63 @@
+RTEMS_VERSION ?= 4.11
+RTEMS_MAKEFILE_PATH ?= \
+ /opt/rtems-$(RTEMS_VERSION)/lm32-rtems$(RTEMS_VERSION)/milkymist/
+RTEMS_FPVM_H = $(RTEMS_MAKEFILE_PATH)/lib/include/fpvm
+
+CFLAGS = -Wall -g -I.. -I.
+OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o
+
+# ----- Verbosity control -----------------------------------------------------
+
+CC_normal := $(CC)
+
+CC_quiet = @echo " CC " $@ && $(CC_normal)
+GEN_quiet = @echo " GENERATE " $@ &&
+
+ifeq ($(V),1)
+ CC = $(CC_normal)
+ GEN =
+else
+ CC = $(CC_quiet)
+ GEN = $(GEN_quiet)
+endif
+
+# ----- Rules -----------------------------------------------------------------
+
+.PHONY: all clean
+
+all: fpvm ptest
+
+fpvm:
+ $(GEN) ln -s $(RTEMS_FPVM_H) fpvm
+
+ptest: $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $^
+
+%.o: ../%.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+%.c: %.re
+ $(GEN) re2c -o $@ $<
+
+%.c: %.y
+ $(GEN) lemon $<
+
+%.h %.inc: %.ids
+ $(GEN) cd .. && ./idgen `basename $<`
+
+# ----- Dependencies ----------------------------------------------------------
+
+../parser.h: ../parser.c
+scanner.o: ../parser.h
+parser_helper.o: ../parser.h
+ptest.o: ../parser.h
+unique.o: ../fnp.inc
+
+# ----- Cleanup ---------------------------------------------------------------
+
+clean:
+ rm -f $(OBJS)
+ rm -f ../scanner.c
+ rm -f ../parser.c ../parser.h ../parser.out
+ rm -f ../fnp.h ../fnp.inc
+ rm -f fpvm
211 src/compiler/ptest/ptest.c
View
@@ -0,0 +1,211 @@
+/*
+ * ptest.c - FNP parser tester
+ *
+ * Copyright 2011 by Werner Almesberger
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "../fpvm.h"
+#include "../parser_helper.h"
+#include "../parser.h"
+
+
+static int quiet = 0;
+
+
+static void dump_ast(const struct ast_node *ast);
+
+
+static void branch(const struct ast_node *ast)
+{
+ if (ast) {
+ putchar(' ');
+ dump_ast(ast);
+ }
+}
+
+
+static void op(const char *s, const struct ast_node *ast)
+{
+ printf("(%s", s);
+ branch(ast->contents.branches.a);
+ branch(ast->contents.branches.b);
+ branch(ast->contents.branches.c);
+ putchar(')');
+}
+
+
+static void dump_ast(const struct ast_node *ast)
+{
+ switch (ast->op) {
+ case op_ident:
+ printf("%s", ast->label);
+ break;
+ case op_constant:
+ printf("%g", ast->contents.constant);
+ break;
+ case op_plus:
+ op("+", ast);
+ break;
+ case op_minus:
+ op("-", ast);
+ break;
+ case op_multiply:
+ op("*", ast);
+ break;
+ case op_divide:
+ op("/", ast);
+ break;
+ case op_percent:
+ op("%", ast);
+ break;
+ case op_abs:
+ op("abs", ast);
+ break;
+ case op_isin:
+ op("isin", ast);
+ break;
+ case op_icos:
+ op("icos", ast);
+ break;
+ case op_sin:
+ op("sin", ast);
+ break;
+ case op_cos:
+ op("cos", ast);
+ break;
+ case op_above:
+ op("above", ast);
+ break;
+ case op_below:
+ op("below", ast);
+ break;
+ case op_equal:
+ op("equal", ast);
+ break;
+ case op_i2f:
+ op("i2f", ast);
+ break;
+ case op_f2i:
+ op("f2i", ast);
+ break;
+ case op_if:
+ op("if", ast);
+ break;
+ case op_tsign:
+ op("tsign", ast);
+ break;
+ case op_quake:
+ op("quake", ast);
+ break;
+ case op_not:
+ op("!", ast);
+ break;
+ case op_sqr:
+ op("sqr", ast);
+ break;
+ case op_sqrt:
+ op("sqrt", ast);
+ break;
+ case op_invsqrt:
+ op("invsqrt", ast);
+ break;
+ case op_min:
+ op("min", ast);
+ break;
+ case op_max:
+ op("max", ast);
+ break;
+ case op_int:
+ op("int", ast);
+ break;
+ default:
+ abort();
+ }
+}
+
+
+int fpvm_do_assign(struct fpvm_fragment *fragment, const char *dest,
+ struct ast_node *ast)
+{
+ if (!quiet) {
+ printf("%s = ", dest);
+ dump_ast(ast);
+ putchar('\n');
+ }
+ return 1;
+}
+
+
+static const char *read_stdin(void)
+{
+ char *buf = NULL;
+ int len = 0, size = 0;
+ ssize_t got;
+
+ do {
+ if (len == size) {
+ size += size ? size : 1024;
+ buf = realloc(buf, size+1);
+ if (!buf) {
+ perror("realloc");
+ exit(1);
+ }
+ }
+ got = read(0, buf+len, size-len);
+ if (got < 0) {
+ perror("read");
+ exit(1);
+ }
+ len += got;
+ }
+ while (got);
+
+ buf[len] = 0;
+
+ return buf;
+}
+
+
+static void usage(const char *name)
+{
+ fprintf(stderr, "usage: %s [-q] [expr]\n", name);
+ exit(1);
+}
+
+
+int main(int argc, char **argv)
+{
+ int c;
+ const char *buf;
+ union parser_comm comm;
+
+ while ((c = getopt(argc, argv, "q")) != EOF)
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ default:
+ usage(*argv);
+ }
+ switch (argc-optind) {
+ case 0:
+ buf = read_stdin();
+ break;
+ case 1:
+ buf = argv[optind];
+ break;
+ default:
+ usage(*argv);
+ }
+
+ return !fpvm_parse(buf, TOK_START_ASSIGN, &comm);
+}
9 src/compiler/scanner.re
View
@@ -58,8 +58,14 @@ int scan(struct scanner *s)
/*!re2c
[\x20\n\r\t] { goto std; }
+
+ "//"[^\n\x00]* { goto std; }
+ "/*"("*"*[^/\x00]|[^*\x00])*"*"+"/"
+ { goto std; }
+
[0-9]+ { return TOK_CONSTANT; }
- [0-9]* "." [0-9]* { return TOK_CONSTANT; }
+ [0-9]+ "." [0-9]* { return TOK_CONSTANT; }
+ [0-9]* "." [0-9]+ { return TOK_CONSTANT; }
"above" { return TOK_ABOVE; }
"abs" { return TOK_ABS; }
@@ -91,6 +97,7 @@ int scan(struct scanner *s)
")" { return TOK_RPAREN; }
"," { return TOK_COMMA; }
"=" { return TOK_ASSIGN; }
+ ";" { return TOK_SEMI; }
[\x00-\xff] { return TOK_ERROR; }
*/
}
52 src/compiler/test/Common
View
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Common - Elements shared by all regression tests for the FNP parser
+#
+# Written 2010, 2011 by Werner Almesberger
+# Copyright 2010, 2011 Werner Almesberger
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+
+
+ptest()
+{
+ echo -n "$1: " 1>&2
+ shift
+ $VALGRIND ${PTST:-../ptest/ptest} "$@" >_out 2>&1 || {
+ echo FAILED "($SCRIPT)" 1>&2
+ cat _out
+ rm -f _out
+ exit 1
+ }
+}
+
+
+ptest_fail()
+{
+ echo -n "$1: " 1>&2
+ shift
+ $VALGRIND ${PTST:-../ptest/ptest} "$@" >_out 2>&1 && {
+ echo FAILED "($SCRIPT)" 1>&2
+ cat _out
+ rm -f _out
+ exit 1
+ }
+}
+
+
+expect()
+{
+ diff -u - "$@" _out >_diff || {
+ echo FAILED "($SCRIPT)" 1>&2
+ cat _diff 1>&2
+ rm -f _out _diff
+ exit 1
+ }
+ echo PASSED 1>&2
+ rm -f _out _diff
+ passed=`expr ${passed:-0} + 1`
+}
49 src/compiler/test/arith
View
@@ -0,0 +1,49 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "arithmetic: x = a+b" <<EOF
+x = a+b
+EOF
+expect <<EOF
+x = (+ a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "arithmetic: x = a-b" <<EOF
+x = a-b
+EOF
+expect <<EOF
+x = (- a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "arithmetic: x = a*b" <<EOF
+x = a*b
+EOF
+expect <<EOF
+x = (* a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "arithmetic: x = a/b" <<EOF
+x = a/b
+EOF
+expect <<EOF
+x = (/ a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "arithmetic: x = a%b" <<EOF
+x = a/b
+EOF
+expect <<EOF
+x = (/ a b)
+EOF
+
+###############################################################################
136 src/compiler/test/comment
View
@@ -0,0 +1,136 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "comment: line with just // " <<EOF
+// this is a comment
+a = b + c
+EOF
+expect <<EOF
+a = (+ b c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: line ending with // comment" <<EOF
+a = b + c // comment
+d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: // after //" <<EOF
+a = b + c // comment // more
+d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: // ending with EOF" "a = b// end"
+expect <<EOF
+a = b
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /* ... */" <<EOF
+a = b + c /* comment */
+d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /* ... newline ... */" <<EOF
+a = b + c /* comment
+more */ d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /* ... * ... */" <<EOF
+a = 1 /* comment * more */
+b = 2
+EOF
+expect <<EOF
+a = 1
+b = 2
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /* ... ** ... */" <<EOF
+a = 3 /* comment ** more */
+b = 4
+EOF
+expect <<EOF
+a = 3
+b = 4
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /* ... **/" <<EOF
+a = 5 /* comment **/
+b = 6
+EOF
+expect <<EOF
+a = 5
+b = 6
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "comment: /**/" <<EOF
+a = 7 /**/
+b = 8
+EOF
+expect <<EOF
+a = 7
+b = 8
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "comment: /*/ (error)" <<EOF
+a = 9 /*/
+b = a
+EOF
+expect <<EOF
+FPVM: parse error
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "comment: unterminated /* ... with newline" <<EOF
+a = b + c /* comment
+d = e + f
+EOF
+expect <<EOF
+FPVM: parse error
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "comment: unterminated /* ... without newline" "a = b+c /* comment"
+expect <<EOF
+FPVM: parse error
+EOF
+
+###############################################################################
32 src/compiler/test/error
View
@@ -0,0 +1,32 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest_fail "syntax error: x = backtick" <<EOF
+x = \`
+EOF
+expect <<EOF
+FPVM: scan error
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "syntax error: x = a b" <<EOF
+x = a b
+EOF
+expect <<EOF
+x = a
+FPVM: parse error
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "syntax error: x = a + + b" <<EOF
+x = a + + b
+EOF
+expect <<EOF
+FPVM: parse error
+EOF
+
+###############################################################################
59 src/compiler/test/number
View
@@ -0,0 +1,59 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "number: a = 1" <<EOF
+a = 1
+EOF
+expect <<EOF
+a = 1
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "number: b = 1.2" <<EOF
+b = 1.2
+EOF
+expect <<EOF
+b = 1.2
+EOF
+
+#------------------------------------------------------------------------------
+#------------------------------------------------------------------------------
+
+ptest "number: c = .3" <<EOF
+c = .3
+EOF
+expect <<EOF
+c = 0.3
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "number: d = 4." <<EOF
+d = 4.
+EOF
+expect <<EOF
+d = 4
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "number: e = 51.23" <<EOF
+e = 51.23
+EOF
+expect <<EOF
+e = 51.23
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "number: f = ." <<EOF
+f = .
+EOF
+expect <<EOF
+FPVM: scan error
+EOF
+
+###############################################################################
91 src/compiler/test/wrap
View
@@ -0,0 +1,91 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "wrap: baseline" <<EOF
+a = b + c
+EOF
+expect <<EOF
+a = (+ b c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: with newline" <<EOF
+a = b +
+c
+EOF
+expect <<EOF
+a = (+ b c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: two assignments on two lines" <<EOF
+a = b + c
+d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: two assignments on one line" <<EOF
+a = b + c d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: one assignment ending with semicolon" <<EOF
+a = b + c;
+EOF
+expect <<EOF
+a = (+ b c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: one assignment ending with multiple semicolons" <<EOF
+a = b + c;;;;;;;;;;;
+EOF
+expect <<EOF
+a = (+ b c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "wrap: two assignments separated by semicolon" <<EOF
+a = b + c; d = e + f
+EOF
+expect <<EOF
+a = (+ b c)
+d = (+ e f)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "wrap: one assignment containing semicolon (1)" <<EOF
+a = b +; c
+EOF
+expect <<EOF
+FPVM: parse error
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "wrap: one assignment containing semicolon (2)" <<EOF
+a = b; + c
+EOF
+expect <<EOF
+a = b
+FPVM: parse error
+EOF
+
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.