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: cc9e057^
...
head fork: m-labs/flickernoise
compare: d755a0b
  • 13 commits
  • 24 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jan 05, 2012
Werner Almesberger wpwrak compiler: define op_not such that we don't trigger a warning
lm32-rtems4.11-gcc doesn't like to compare enums "inherited" from other
enums. We just "manually" code the offset instead.
cc9e057
Commits on Jan 07, 2012
Werner Almesberger wpwrak compiler: track reduction of "label" use in libfpvm
First, we use the new node_is_op in parse_free. Second, we no longer
have a good error message if op_not "leaks" in test/not.
36ef9cd
Commits on Jan 10, 2012
Werner Almesberger wpwrak compiler: don't predefine identifiers for function names
Since function names are normally not used for variables, we keep them
separate and only allocate an identifier when needed. This will help
with a future migration towards a proper symbol table.

This also reduces the size of the table of predefined identifiers,
slightly accelerating the compiler.
eaf4b67
Werner Almesberger wpwrak test: allow leak tests to fail and count the failed tests
This adds instrumentation to expect() to make test failure non-fatal if
FAIL_ON_ERROR is set to "false", then uses it in the "leak" target.
55805a1
Werner Almesberger wpwrak ptest: new option -s to dump all variables/symbols
Also added the corresponding infrastructure to unique.c/unique.h
484399e
Werner Almesberger wpwrak tests: move list of patches from test/patches to shareable test/Patches 8e581f9
Werner Almesberger wpwrak test/nsyms: count the number of user-defined variables/symbols in pat…
…ch pool

This is less a regression test bit more an indicator for how adaquate
the structure of the symbol table is.
38815b5
Werner Almesberger wpwrak compiler: nMotionVectorsX was missing in fnp.ids 565d57d
Werner Almesberger wpwrak compiler: rename unique.[ch] to symtab.[ch] c0f929b
Werner Almesberger wpwrak compiler: "struct sym" megapatch
This changes the compiler to use "struct sym" instead of "const char *"
to refer to variables when communicating with libfpvm. This also
implies that the symbol table moves to "struct sym" and that things
that are not a variable have no identifier associated with them.
9783fb2
Werner Almesberger wpwrak compiler: separate file names more clearly from symbols
The goal is to get rid of "label", which now only serves as a pointer
into the source (or a copy thereof), for diagnostics.
bda6e87
Commits on Jan 11, 2012
Werner Almesberger wpwrak compiler: adapt to libfpvm use of "struct fpvm_sym" and introduce "st…
…ruct sym"

We now have a Flickernoise-local "struct sym" that contains the libfpvm
symbol.
35ec434
Werner Almesberger wpwrak compiler: record index of system variables in symbol table
This removes the list of variable names from compiler.c and lets
fnp.ids provide the mapping from name to index.
d755a0b
4 src/Makefile
View
@@ -63,7 +63,7 @@ OBJS += $(addprefix renderer/,framedescriptor.o analyzer.o sampler.o \
eval.o line.o wave.o font.o osd.o raster.o renderer.o \
videoinreconf.o)
OBJS += $(addprefix compiler/,compiler.o parser_helper.o scanner.o \
- parser.o unique.o)
+ parser.o symtab.o)
POBJS=$(addprefix $(OBJDIR)/,$(OBJS))
@@ -99,7 +99,7 @@ compiler/infra-fnp.h: \
compiler/parser.h: compiler/parser.c
obj/compiler/scanner.o: compiler/parser.h
obj/compiler/parser_helper.o: compiler/parser.h
-obj/compiler/unique.o: compiler/fnp.inc
+obj/compiler/symtab.o: compiler/fnp.inc
obj/compiler/compiler.o: compiler/infra-fnp.h compiler/parser.h
# boot images for Milkymist One
18 src/compiler/Makefile
View
@@ -7,18 +7,24 @@ all:
# ----- 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"'
+ LANG= sh -c \
+ 'passed=0 && failed=0 && cd test && \
+ for n in [a-z]*; do \
+ [ $$n != core ] && SCRIPT=$$n . ./$$n; done; \
+ if [ $$failed = 0 ]; then \
+ echo "Passed all $$passed tests"; \
+ else \
+ total=`expr $$passed + $$failed`; \
+ echo "Failed $$failed/$$total tests"; \
+ exit 1; \
+ fi'
valgrind:
VALGRIND="valgrind -q" $(MAKE) tests
leak leaks:
VALGRIND="valgrind -q --leak-check=full --show-reachable=yes" \
- $(MAKE) tests
+ FAIL_ON_ERROR=false $(MAKE) tests
# ----- Cleanup ---------------------------------------------------------------
244 src/compiler/compiler.c
View
@@ -23,12 +23,13 @@
#include <string.h>
#include <fpvm/fpvm.h>
+#include <fpvm/symbol.h>
#include <fpvm/ast.h>
#include <fpvm/schedulers.h>
#include <fpvm/pfpu.h>
#include "../pixbuf/pixbuf.h"
-#include "unique.h"
+#include "symtab.h"
#include "parser_helper.h"
#include "parser.h"
#include "compiler.h"
@@ -65,10 +66,10 @@ static void init_fpvm(struct fpvm_fragment *fragment, int vector_mode)
* the same. We can get rid of these calls to unique() later.
*/
- _Xi = unique("_Xi");
- _Xo = unique("_Xo");
- _Yi = unique("_Yi");
- _Yo = unique("_Yo");
+ _Xi = &unique("_Xi")->fpvm_sym;
+ _Xo = &unique("_Xo")->fpvm_sym;
+ _Yi = &unique("_Yi")->fpvm_sym;
+ _Yo = &unique("_Yo")->fpvm_sym;
fpvm_do_init(fragment, vector_mode);
}
@@ -76,9 +77,9 @@ static void init_fpvm(struct fpvm_fragment *fragment, int vector_mode)
static const char *assign_chunk(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
- if(fpvm_do_assign(comm->u.fragment, label, node))
+ if(fpvm_do_assign(comm->u.fragment, &sym->fpvm_sym, node))
return NULL;
else
return strdup(fpvm_get_last_error(comm->u.fragment));
@@ -107,139 +108,9 @@ static int compile_chunk(struct fpvm_fragment *fragment, const char *chunk)
/* PER-FRAME VARIABLES */
/****************************************************************/
-const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
- "sx",
- "sy",
- "cx",
- "cy",
- "rot",
- "dx",
- "dy",
- "zoom",
- "decay",
- "wave_mode",
- "wave_scale",
- "wave_additive",
- "wave_usedots",
- "wave_brighten",
- "wave_thick",
- "wave_x",
- "wave_y",
- "wave_r",
- "wave_g",
- "wave_b",
- "wave_a",
-
- "ob_size",
- "ob_r",
- "ob_g",
- "ob_b",
- "ob_a",
- "ib_size",
- "ib_r",
- "ib_g",
- "ib_b",
- "ib_a",
-
- "nMotionVectorsX",
- "nMotionVectorsY",
- "mv_dx",
- "mv_dy",
- "mv_l",
- "mv_r",
- "mv_g",
- "mv_b",
- "mv_a",
-
- "bTexWrap",
-
- "time",
- "bass",
- "mid",
- "treb",
- "bass_att",
- "mid_att",
- "treb_att",
-
- "warp",
- "fWarpAnimSpeed",
- "fWarpScale",
-
- "q1",
- "q2",
- "q3",
- "q4",
- "q5",
- "q6",
- "q7",
- "q8",
-
- "fVideoEchoAlpha",
- "fVideoEchoZoom",
- "nVideoEchoOrientation",
-
- "dmx1",
- "dmx2",
- "dmx3",
- "dmx4",
- "dmx5",
- "dmx6",
- "dmx7",
- "dmx8",
-
- "idmx1",
- "idmx2",
- "idmx3",
- "idmx4",
- "idmx5",
- "idmx6",
- "idmx7",
- "idmx8",
-
- "osc1",
- "osc2",
- "osc3",
- "osc4",
-
- "midi1",
- "midi2",
- "midi3",
- "midi4",
- "midi5",
- "midi6",
- "midi7",
- "midi8",
-
- "video_a",
-
- "image1_a",
- "image1_x",
- "image1_y",
- "image1_zoom",
- "image2_a",
- "image2_x",
- "image2_y",
- "image2_zoom"
-};
-
-static int pfv_from_name(const char *name)
+static int pfv_from_sym(const struct sym *sym)
{
- int i;
-
- for(i=0;i<COMP_PFV_COUNT;i++) {
- if(strcmp(pfv_names[i], name) == 0)
- return i;
- }
-
- if(strcmp(name, "fDecay") == 0) return pfv_decay;
- if(strcmp(name, "nWaveMode") == 0) return pfv_wave_mode;
- if(strcmp(name, "fWaveScale") == 0) return pfv_wave_scale;
- if(strcmp(name, "bAdditiveWaves") == 0) return pfv_wave_additive;
- if(strcmp(name, "bWaveDots") == 0) return pfv_wave_usedots;
- if(strcmp(name, "bMaximizeWaveColor") == 0) return pfv_wave_brighten;
- if(strcmp(name, "bWaveThick") == 0) return pfv_wave_thick;
- if(strcmp(name, "fWaveAlpha") == 0) return pfv_wave_a;
- return -1;
+ return sym->pfv_idx;
}
static void pfv_update_patch_requires(struct compiler_sc *sc, int pfv)
@@ -314,12 +185,12 @@ static void all_initials_to_pfv(struct compiler_sc *sc)
initial_to_pfv(sc, i);
}
-static void pfv_bind_callback(void *_sc, const char *sym, int reg)
+static void pfv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
{
struct compiler_sc *sc = _sc;
int pfv;
- pfv = pfv_from_name(sym);
+ pfv = pfv_from_sym(FPVM2SYM(sym));
if(pfv >= 0) {
pfv_update_patch_requires(sc, pfv);
sc->p->pfv_allocation[pfv] = reg;
@@ -377,76 +248,9 @@ static bool schedule_pfv(struct compiler_sc *sc)
/* PER-VERTEX VARIABLES */
/****************************************************************/
-const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
- /* System */
- "_texsize",
- "_hmeshsize",
- "_vmeshsize",
-
- /* MilkDrop */
- "sx",
- "sy",
- "cx",
- "cy",
- "rot",
- "dx",
- "dy",
- "zoom",
-
- "time",
- "bass",
- "mid",
- "treb",
- "bass_att",
- "mid_att",
- "treb_att",
-
- "warp",
- "fWarpAnimSpeed",
- "fWarpScale",
-
- "q1",
- "q2",
- "q3",
- "q4",
- "q5",
- "q6",
- "q7",
- "q8",
-
- "idmx1",
- "idmx2",
- "idmx3",
- "idmx4",
- "idmx5",
- "idmx6",
- "idmx7",
- "idmx8",
-
- "osc1",
- "osc2",
- "osc3",
- "osc4",
-
- "midi1",
- "midi2",
- "midi3",
- "midi4",
- "midi5",
- "midi6",
- "midi7",
- "midi8",
-};
-
-static int pvv_from_name(const char *name)
+static int pvv_from_sym(const struct sym *sym)
{
- int i;
-
- for(i=0;i<COMP_PVV_COUNT;i++) {
- if(strcmp(pvv_names[i], name) == 0)
- return i;
- }
- return -1;
+ return sym->pvv_idx;
}
static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
@@ -459,12 +263,12 @@ static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
sc->p->require |= REQUIRE_MIDI;
}
-static void pvv_bind_callback(void *_sc, const char *sym, int reg)
+static void pvv_bind_callback(void *_sc, struct fpvm_sym *sym, int reg)
{
struct compiler_sc *sc = _sc;
int pvv;
- pvv = pvv_from_name(sym);
+ pvv = pvv_from_sym(FPVM2SYM(sym));
if(pvv >= 0) {
pvv_update_patch_requires(sc, pvv);
sc->p->pvv_allocation[pvv] = reg;
@@ -540,13 +344,13 @@ static bool schedule_pvv(struct compiler_sc *sc)
/****************************************************************/
static const char *assign_default(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
struct compiler_sc *sc = comm->u.sc;
int pfv;
float v;
- pfv = pfv_from_name(label);
+ pfv = pfv_from_sym(sym);
if(pfv < 0)
return strdup("unknown parameter");
@@ -571,24 +375,24 @@ static const char *assign_default(struct parser_comm *comm,
}
static const char *assign_fragment(struct fpvm_fragment *frag,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
- if(fpvm_do_assign(frag, label, node))
+ if(fpvm_do_assign(frag, &sym->fpvm_sym, node))
return NULL;
else
return strdup(fpvm_get_last_error(frag));
}
static const char *assign_per_frame(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
- return assign_fragment(&comm->u.sc->pfv_fragment, label, node);
+ return assign_fragment(&comm->u.sc->pfv_fragment, sym, node);
}
static const char *assign_per_vertex(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
- return assign_fragment(&comm->u.sc->pvv_fragment, label, node);
+ return assign_fragment(&comm->u.sc->pvv_fragment, sym, node);
}
static const char *assign_image_name(struct parser_comm *comm,
3  src/compiler/compiler.h
View
@@ -236,9 +236,6 @@ struct patch {
typedef void (*report_message)(const char *);
-extern const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN];
-extern const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN];
-
struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
struct patch *patch_copy(struct patch *p);
395 src/compiler/fnp.ids
View
@@ -11,232 +11,151 @@
#
#
-# Built-in functions
-#
-
-above
-abs
-below
-cos
-equal
-f2i
-icos
-i2f
-if
-int
-invsqrt
-isin
-max
-min
-quake
-sin
-sqr
-sqrt
-tsign
-
-#
-#
-# Per-Frame Variables
-#
-
-sx
-sy
-cx
-cy
-rot
-dx
-dy
-zoom
-decay
-wave_mode
-wave_scale
-wave_additive
-wave_usedots
-wave_brighten
-wave_thick
-wave_x
-wave_y
-wave_r
-wave_g
-wave_b
-wave_a
-
-ob_size
-ob_r
-ob_g
-ob_b
-ob_a
-ib_size
-ib_r
-ib_g
-ib_b
-ib_a
-
-nMotionVectorsY
-mv_dx
-mv_dy
-mv_l
-mv_r
-mv_g
-mv_b
-mv_a
-
-bTexWrap
-
-time
-bass
-mid
-treb
-bass_att
-mid_att
-treb_att
-
-warp
-fWarpAnimSpeed
-fWarpScale
-
-q1
-q2
-q3
-q4
-q5
-q6
-q7
-q8
-
-fVideoEchoAlpha
-fVideoEchoZoom
-nVideoEchoOrientation
-
-dmx1
-dmx2
-dmx3
-dmx4
-dmx5
-dmx6
-dmx7
-dmx8
-
-idmx1
-idmx2
-idmx3
-idmx4
-idmx5
-idmx6
-idmx7
-idmx8
-
-osc1
-osc2
-osc3
-osc4
-
-midi1
-midi2
-midi3
-midi4
-midi5
-midi6
-midi7
-midi8
-
-video_a
-
-image1_a
-image1_x
-image1_y
-image1_zoom
-image2_a
-image2_x
-image2_y
-image2_zoom
+# Per-Frame and Per-Vertex Variables
+#
+
+sx pfv_sx pvv_sx
+sy pfv_sy pvv_sy
+cx pfv_cx pvv_cx
+cy pfv_cy pvv_cy
+rot pfv_rot pvv_rot
+dx pfv_dx pvv_dx
+dy pfv_dy pvv_dy
+zoom pfv_zoom pvv_zoom
+decay pfv_decay -1
+wave_mode pfv_wave_mode -1
+wave_scale pfv_wave_scale -1
+wave_additive pfv_wave_additive -1
+wave_usedots pfv_wave_usedots -1
+wave_brighten pfv_wave_brighten -1
+wave_thick pfv_wave_thick -1
+wave_x pfv_wave_x -1
+wave_y pfv_wave_y -1
+wave_r pfv_wave_r -1
+wave_g pfv_wave_g -1
+wave_b pfv_wave_b -1
+wave_a pfv_wave_a -1
+
+ob_size pfv_ob_size -1
+ob_r pfv_ob_r -1
+ob_g pfv_ob_g -1
+ob_b pfv_ob_b -1
+ob_a pfv_ob_a -1
+ib_size pfv_ib_size -1
+ib_r pfv_ib_r -1
+ib_g pfv_ib_g -1
+ib_b pfv_ib_b -1
+ib_a pfv_ib_a -1
+
+nMotionVectorsX pfv_mv_x -1
+nMotionVectorsY pfv_mv_y -1
+mv_dx pfv_mv_dx -1
+mv_dy pfv_mv_dy -1
+mv_l pfv_mv_l -1
+mv_r pfv_mv_r -1
+mv_g pfv_mv_g -1
+mv_b pfv_mv_b -1
+mv_a pfv_mv_a -1
+
+bTexWrap pfv_tex_wrap -1
+
+time pfv_time pvv_time
+bass pfv_bass pvv_bass
+mid pfv_mid pvv_mid
+treb pfv_treb pvv_treb
+bass_att pfv_bass_att pvv_bass_att
+mid_att pfv_mid_att pvv_mid_att
+treb_att pfv_treb_att pvv_treb_att
+
+warp pfv_warp pvv_warp
+fWarpAnimSpeed pfv_warp_anim_speed pvv_warp_anim_speed
+fWarpScale pfv_warp_scale pvv_warp_scale
+
+q1 pfv_q1 pvv_q1
+q2 pfv_q2 pvv_q2
+q3 pfv_q3 pvv_q3
+q4 pfv_q4 pvv_q4
+q5 pfv_q5 pvv_q5
+q6 pfv_q6 pvv_q6
+q7 pfv_q7 pvv_q7
+q8 pfv_q8 pvv_q8
+
+fVideoEchoAlpha pfv_video_echo_alpha -1
+fVideoEchoZoom pfv_video_echo_zoom -1
+nVideoEchoOrientation pfv_video_echo_orientation -1
+
+dmx1 pfv_dmx1 -1
+dmx2 pfv_dmx2 -1
+dmx3 pfv_dmx3 -1
+dmx4 pfv_dmx4 -1
+dmx5 pfv_dmx5 -1
+dmx6 pfv_dmx6 -1
+dmx7 pfv_dmx7 -1
+dmx8 pfv_dmx8 -1
+
+idmx1 pfv_idmx1 pvv_idmx1
+idmx2 pfv_idmx2 pvv_idmx2
+idmx3 pfv_idmx3 pvv_idmx3
+idmx4 pfv_idmx4 pvv_idmx4
+idmx5 pfv_idmx5 pvv_idmx5
+idmx6 pfv_idmx6 pvv_idmx6
+idmx7 pfv_idmx7 pvv_idmx7
+idmx8 pfv_idmx8 pvv_idmx8
+
+osc1 pfv_osc1 pvv_osc1
+osc2 pfv_osc2 pvv_osc2
+osc3 pfv_osc3 pvv_osc3
+osc4 pfv_osc4 pvv_osc4
+
+midi1 pfv_midi1 pvv_midi1
+midi2 pfv_midi2 pvv_midi2
+midi3 pfv_midi3 pvv_midi3
+midi4 pfv_midi4 pvv_midi4
+midi5 pfv_midi5 pvv_midi5
+midi6 pfv_midi6 pvv_midi6
+midi7 pfv_midi7 pvv_midi7
+midi8 pfv_midi8 pvv_midi8
+
+video_a pfv_video_a -1
+
+image1_a pfv_image1_a -1
+image1_x pfv_image1_x -1
+image1_y pfv_image1_y -1
+image1_zoom pfv_image1_zoom -1
+image2_a pfv_image2_a -1
+image2_x pfv_image2_x -1
+image2_y pfv_image2_y -1
+image2_zoom pfv_image2_zoom -1
#
# Aliases
#
-fDecay
-nWaveMode
-fWaveScale
-bAdditiveWaves
-bWaveDots
-bMaximizeWaveColor
-bWaveThick
-fWaveAlpha
+fDecay pfv_decay -1
+nWaveMode pfv_wave_mode -1
+fWaveScale pfv_wave_scale -1
+bAdditiveWaves pfv_wave_additive -1
+bWaveDots pfv_wave_usedots -1
+bMaximizeWaveColor pfv_wave_brighten -1
+bWaveThick pfv_wave_thick -1
+fWaveAlpha pfv_wave_a -1
#
-# Per-Vertex Variables
+# Per-Vertex Variables (system)
#
-# System
-
-_texsize
-_hmeshsize
-_vmeshsize
-
-# MilkDrop
-
-sx
-sy
-cx
-cy
-rot
-dx
-dy
-zoom
-
-time
-bass
-mid
-treb
-bass_att
-mid_att
-treb_att
-
-warp
-fWarpAnimSpeed
-fWarpScale
-
-q1
-q2
-q3
-q4
-q5
-q6
-q7
-q8
-
-idmx1
-idmx2
-idmx3
-idmx4
-idmx5
-idmx6
-idmx7
-idmx8
-
-osc1
-osc2
-osc3
-osc4
-
-midi1
-midi2
-midi3
-midi4
-midi5
-midi6
-midi7
-midi8
+_texsize -1 pvv_texsize
+_hmeshsize -1 pvv_hmeshsize
+_vmeshsize -1 pvv_vmeshsize
#
# FPVM internal variables
#
-_Xo
-_Yo
-_Xi
-_Yi
+_Xo -1 -1
+_Yo -1 -1
+_Xi -1 -1
+_Yi -1 -1
#
# PVV internal variables
@@ -244,41 +163,41 @@ _Yi
# Initialization
-x
-y
-rad
+x -1 -1
+y -1 -1
+rad -1 -1
# Zoom
-_invzoom
-_xy
-_yz
+_invzoom -1 -1
+_xy -1 -1
+_yz -1 -1
# Scale
-_xs
-_ys
+_xs -1 -1
+_ys -1 -1
# Warp
-_warptime
-_invwarpscale
-_f0
-_f1
-_f2
-_f3
-_ox2
-_oy2
-_xw
-_yw
+_warptime -1 -1
+_invwarpscale -1 -1
+_f0 -1 -1
+_f1 -1 -1
+_f2 -1 -1
+_f3 -1 -1
+_ox2 -1 -1
+_oy2 -1 -1
+_xw -1 -1
+_yw -1 -1
# Rotate
-_cosr
-_sinr
-_u
-_v
-_xr
-_yr
-_xd
-_yd
+_cosr -1 -1
+_sinr -1 -1
+_u -1 -1
+_v -1 -1
+_xr -1 -1
+_yr -1 -1
+_xd -1 -1
+_yd -1 -1
21 src/compiler/idgen
View
@@ -2,7 +2,7 @@
#
# idgen - Identifier table generator
#
-# Copyright 2011 by Werner Almesberger
+# Copyright 2011-2012 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
@@ -21,17 +21,17 @@ usage()
[ "$2" ] && usage
[ -r "$1" ] || { echo "$1: not found" 1&2; exit 1; }
-trap "echo $1.h $1.inc" 0
-
f=`basename "$1" .ids`
+trap "rm $f.h $f.inc" 0
+
cat <<EOF >$f.h
/* MACHINE-GENERATED. DO NOT EDIT ! */
#ifndef IDS_H
#define IDS_H
-extern const char *well_known[];
+extern struct sym *well_known[];
EOF
@@ -40,11 +40,18 @@ cat <<EOF >$f.inc
EOF
-sed 's/#.*//;s/ //g;/^$/d' $1 | sort | uniq | {
+sed 's/#.*//;/^ *$/d' $1 | sort | {
i=0
while read n; do
- echo "#define ID_$n (well_known[$i])" >>$f.h
- echo "\"$n\"," >>$f.inc
+ set - $n
+ echo "#define ID_$1 (well_known[$i])" >>$f.h
+ cat <<EOF >>$f.inc
+{
+ .fpvm_sym = { .name = "$1" },
+ .pfv_idx = $2,
+ .pvv_idx = $3,
+},
+EOF
i=`expr $i + 1`
done
}
115 src/compiler/parser.y
View
@@ -18,11 +18,15 @@
%include {
#include <assert.h>
#include <string.h>
+ #include <ctype.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
+
#include <fpvm/ast.h>
#include <fpvm/fpvm.h>
+
+ #include "symtab.h"
#include "parser_itf.h"
#include "parser_helper.h"
#include "parser.h"
@@ -32,7 +36,7 @@
static void yy_parse_failed(struct yyParser *yypParser);
typedef const char *(*assign_callback)(struct parser_comm *comm,
- const char *label, struct ast_node *node);
+ struct sym *sym, struct ast_node *node);
#define FAIL \
do { \
@@ -81,36 +85,40 @@
[TOK_INT] = op_int,
};
- static struct ast_node *node_op(enum ast_op op, const char *id,
+ static struct ast_node *node_op(enum ast_op op,
struct ast_node *a, struct ast_node *b, struct ast_node *c)
{
struct ast_node *n;
n = malloc(sizeof(struct ast_node));
n->op = op;
- n->label = id;
+ n->sym = NULL;
n->contents.branches.a = a;
n->contents.branches.b = b;
n->contents.branches.c = c;
return n;
}
- static struct ast_node *node(int token, const char *id,
+ static struct ast_node *node(int token, struct sym *sym,
struct ast_node *a, struct ast_node *b, struct ast_node *c)
{
- return node_op(tok2op[token], id, a, b, c);
+ struct ast_node *n;
+
+ n = node_op(tok2op[token], a, b, c);
+ n->sym = &sym->fpvm_sym;
+ return n;
}
static struct ast_node *constant(float n)
{
struct ast_node *node;
- node = node_op(op_constant, "", NULL, NULL, NULL);
+ node = node_op(op_constant, NULL, NULL, NULL);
node->contents.constant = n;
return node;
}
- #define FOLD_UNARY(res, ast_op, name, arg, expr) \
+ #define FOLD_UNARY(res, ast_op, arg, expr) \
do { \
if((arg)->op == op_constant) { \
float a = (arg)->contents.constant; \
@@ -118,12 +126,11 @@
res = constant(expr); \
parse_free(arg); \
} else { \
- res = node_op(ast_op, name, \
- arg, NULL, NULL); \
+ res = node_op(ast_op, arg, NULL, NULL); \
} \
} while (0)
- #define FOLD_BINARY(res, ast_op, name, arg_a, arg_b, expr) \
+ #define FOLD_BINARY(res, ast_op, arg_a, arg_b, expr) \
do { \
if((arg_a)->op == op_constant && \
(arg_b)->op == op_constant) { \
@@ -134,7 +141,7 @@
parse_free(arg_a); \
parse_free(arg_b); \
} else { \
- res = node_op(ast_op, name, \
+ res = node_op(ast_op, \
arg_a, arg_b, NULL); \
} \
} while (0)
@@ -146,10 +153,10 @@
struct ast_node *next = a->contents.branches.a;
parse_free_one(a);
- return node_op(op_if, "if", next, c, b);
+ return node_op(op_if, next, c, b);
}
if(a->op != op_constant)
- return node_op(op_if, "if", a, b, c);
+ return node_op(op_if, a, b, c);
if(a->contents.constant) {
parse_free(a);
parse_free(c);
@@ -168,6 +175,15 @@
state->error_lineno = state->id->lineno;
}
}
+
+ static struct id *symbolify(struct id *id)
+ {
+ const char *p;
+
+ for(p = id->label; isalnum(*p); p++);
+ id->sym = unique_n(id->label, p-id->label);
+ return id;
+ }
}
%start_symbol start
@@ -237,7 +253,7 @@ assignments ::= assignments assignment.
assignments ::= .
assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
- state->error = state->comm->assign_default(state->comm, I->label, N);
+ state->error = state->comm->assign_default(state->comm, I->sym, N);
free(I);
if(state->error) {
FAIL;
@@ -248,15 +264,15 @@ assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. {
assignment ::= TOK_IMAGEFILE(I) TOK_ASSIGN TOK_FNAME(N). {
state->error = state->comm->assign_image_name(state->comm,
- atoi(I->label+9), N->label);
+ atoi(I->label+9), N->fname);
free(I);
if(state->error) {
FAIL;
- free((void *) N->label);
+ free((void *) N->fname);
free(N);
return;
}
- free((void *) N->label);
+ free((void *) N->fname);
free(N);
}
@@ -313,14 +329,14 @@ equal_expr(N) ::= rel_expr(A). {
}
equal_expr(N) ::= equal_expr(A) TOK_EQ rel_expr(B). {
- FOLD_BINARY(N, op_equal, "equal", A, B, a == b);
+ FOLD_BINARY(N, op_equal, A, B, a == b);
}
equal_expr(N) ::= equal_expr(A) TOK_NE rel_expr(B). {
struct ast_node *tmp;
- FOLD_BINARY(tmp, op_equal, "equal", A, B, a == b);
- FOLD_UNARY(N, op_not, "!", tmp, !a);
+ FOLD_BINARY(tmp, op_equal, A, B, a == b);
+ FOLD_UNARY(N, op_not, tmp, !a);
}
rel_expr(N) ::= add_expr(A). {
@@ -328,25 +344,25 @@ rel_expr(N) ::= add_expr(A). {
}
rel_expr(N) ::= rel_expr(A) TOK_LT add_expr(B). {
- FOLD_BINARY(N, op_below, "below", A, B, a < b);
+ FOLD_BINARY(N, op_below, A, B, a < b);
}
rel_expr(N) ::= rel_expr(A) TOK_GT add_expr(B). {
- FOLD_BINARY(N, op_above, "above", A, B, a > b);
+ FOLD_BINARY(N, op_above, A, B, a > b);
}
rel_expr(N) ::= rel_expr(A) TOK_LE add_expr(B). {
struct ast_node *tmp;
- FOLD_BINARY(tmp, op_above, "above", A, B, a > b);
- FOLD_UNARY(N, op_not, "!", tmp, !a);
+ FOLD_BINARY(tmp, op_above, A, B, a > b);
+ FOLD_UNARY(N, op_not, tmp, !a);
}
rel_expr(N) ::= rel_expr(A) TOK_GE add_expr(B). {
struct ast_node *tmp;
- FOLD_BINARY(tmp, op_below, "below", A, B, a < b);
- FOLD_UNARY(N, op_not, "!", tmp, !a);
+ FOLD_BINARY(tmp, op_below, A, B, a < b);
+ FOLD_UNARY(N, op_not, tmp, !a);
}
add_expr(N) ::= mult_expr(A). {
@@ -354,11 +370,11 @@ add_expr(N) ::= mult_expr(A). {
}
add_expr(N) ::= add_expr(A) TOK_PLUS mult_expr(B). {
- FOLD_BINARY(N, op_plus, "+", A, B, a + b);
+ FOLD_BINARY(N, op_plus, A, B, a + b);
}
add_expr(N) ::= add_expr(A) TOK_MINUS mult_expr(B). {
- FOLD_BINARY(N, op_minus, "-", A, B, a - b);
+ FOLD_BINARY(N, op_minus, A, B, a - b);
}
mult_expr(N) ::= unary_expr(A). {
@@ -366,15 +382,15 @@ mult_expr(N) ::= unary_expr(A). {
}
mult_expr(N) ::= mult_expr(A) TOK_MULTIPLY unary_expr(B). {
- FOLD_BINARY(N, op_multiply, "*", A, B, a * b);
+ FOLD_BINARY(N, op_multiply, A, B, a * b);
}
mult_expr(N) ::= mult_expr(A) TOK_DIVIDE unary_expr(B). {
- FOLD_BINARY(N, op_divide, "/", A, B, a / b);
+ FOLD_BINARY(N, op_divide, A, B, a / b);
}
mult_expr(N) ::= mult_expr(A) TOK_PERCENT unary_expr(B). {
- FOLD_BINARY(N, op_percent, "%", A, B, a-b*(int) (a/b));
+ FOLD_BINARY(N, op_percent, A, B, a-b*(int) (a/b));
}
unary_expr(N) ::= primary_expr(A). {
@@ -382,11 +398,11 @@ unary_expr(N) ::= primary_expr(A). {
}
unary_expr(N) ::= TOK_MINUS unary_expr(A). {
- FOLD_UNARY(N, op_negate, "-", A, -a);
+ FOLD_UNARY(N, op_negate, A, -a);
}
unary_expr(N) ::= TOK_NOT unary_expr(A). {
- FOLD_UNARY(N, op_not, "!", A, !a);
+ FOLD_UNARY(N, op_not, A, !a);
}
@@ -394,16 +410,16 @@ unary_expr(N) ::= TOK_NOT unary_expr(A). {
primary_expr(N) ::= unary_misc(I) TOK_LPAREN expr(A) TOK_RPAREN. {
- N = node(I->token, I->label, A, NULL, NULL);
+ N = node(I->token, NULL, A, NULL, NULL);
free(I);
}
primary_expr(N) ::= TOK_SQR TOK_LPAREN expr(A) TOK_RPAREN. {
- FOLD_UNARY(N, op_sqr, "sqr", A, a*a);
+ FOLD_UNARY(N, op_sqr, A, a*a);
}
primary_expr(N) ::= TOK_SQRT TOK_LPAREN expr(A) TOK_RPAREN. {
- FOLD_UNARY(N, op_sqrt, "sqrt", A, sqrtf(a));
+ FOLD_UNARY(N, op_sqrt, A, sqrtf(a));
}
@@ -412,28 +428,28 @@ primary_expr(N) ::= TOK_SQRT TOK_LPAREN expr(A) TOK_RPAREN. {
primary_expr(N) ::= binary_misc(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
TOK_RPAREN. {
- N = node(I->token, I->label, A, B, NULL);
+ N = node(I->token, NULL, A, B, NULL);
free(I);
}
primary_expr(N) ::= TOK_ABOVE TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_RPAREN. {
- FOLD_BINARY(N, op_above, "above", A, B, a > b);
+ FOLD_BINARY(N, op_above, A, B, a > b);
}
primary_expr(N) ::= TOK_BELOW TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_RPAREN. {
- FOLD_BINARY(N, op_below, "below", A, B, a < b);
+ FOLD_BINARY(N, op_below, A, B, a < b);
}
primary_expr(N) ::= TOK_EQUAL TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_RPAREN. {
- FOLD_BINARY(N, op_equal, "equal", A, B, a == b);
+ FOLD_BINARY(N, op_equal, A, B, a == b);
}
primary_expr(N) ::= TOK_MAX TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_RPAREN. {
- FOLD_BINARY(N, op_max, "max", A, B, a > b ? a : b);
+ FOLD_BINARY(N, op_max, A, B, a > b ? a : b);
}
primary_expr(N) ::= TOK_MIN TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_RPAREN. {
- FOLD_BINARY(N, op_min, "min", A, B, a < b ? a : b);
+ FOLD_BINARY(N, op_min, A, B, a < b ? a : b);
}
@@ -459,7 +475,7 @@ primary_expr(N) ::= TOK_CONSTANT(C). {
}
primary_expr(N) ::= ident(I). {
- N = node(I->token, I->label, NULL, NULL, NULL);
+ N = node(I->token, I->sym, NULL, NULL, NULL);
free(I);
}
@@ -474,14 +490,17 @@ primary_expr(N) ::= ident(I). {
* they have function-specific code for constant folding. {u,bi,ter}nary_misc
* are identifiers the parser treats as generic functions, without knowing
* anything about their semantics.
+ *
+ * The use of symbolify() is somewhat inefficient, but use of function names
+ * for variables should be a rare condition anyway.
*/
ident(O) ::= TOK_IDENT(I). { O = I; }
-ident(O) ::= unary(I). { O = I; }
-ident(O) ::= unary_misc(I). { O = I; }
-ident(O) ::= binary(I). { O = I; }
-ident(O) ::= binary_misc(I). { O = I; }
-ident(O) ::= ternary(I). { O = I; }
+ident(O) ::= unary(I). { O = symbolify(I); }
+ident(O) ::= unary_misc(I). { O = symbolify(I); }
+ident(O) ::= binary(I). { O = symbolify(I); }
+ident(O) ::= binary_misc(I). { O = symbolify(I); }
+ident(O) ::= ternary(I). { O = symbolify(I); }
unary_misc(O) ::= TOK_ABS(I). { O = I; }
unary_misc(O) ::= TOK_COS(I). { O = I; }
35 src/compiler/parser_helper.c
View
@@ -19,9 +19,11 @@
#define _GNU_SOURCE /* for asprintf */
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <malloc.h>
#include <fpvm/ast.h>
+#include "symtab.h"
#include "scanner.h"
#include "parser.h"
#include "parser_itf.h"
@@ -41,7 +43,11 @@ static int printable_label(const char *s)
{
const char *p;
- for(p = s; *p > ' '; p++);
+ if(isalnum(*s)) {
+ for(p = s; isalnum(*p); p++);
+ } else {
+ for(p = s; *p > ' '; p++);
+ }
return p-s;
}
@@ -85,29 +91,12 @@ const char *parse(const char *expr, int start_token, struct parser_comm *comm)
identifier->label = "";
break;
case TOK_FNAME:
- identifier->label = get_token(s);
+ identifier->fname = get_name(s);
+ identifier->label = identifier->fname;
break;
case TOK_IDENT:
- case TOK_ABOVE:
- case TOK_ABS:
- case TOK_BELOW:
- case TOK_COS:
- case TOK_EQUAL:
- case TOK_F2I:
- case TOK_ICOS:
- case TOK_I2F:
- case TOK_IF:
- case TOK_INT:
- case TOK_INVSQRT:
- case TOK_ISIN:
- case TOK_MAX:
- case TOK_MIN:
- case TOK_QUAKE:
- case TOK_SIN:
- case TOK_SQR:
- case TOK_SQRT:
- case TOK_TSIGN:
- identifier->label = get_unique_token(s);
+ identifier->sym = get_symbol(s);
+ identifier->label = identifier->sym->fpvm_sym.name;
break;
default:
identifier->label = (const char *) s->old_cursor;
@@ -151,7 +140,7 @@ void parse_free_one(struct ast_node *node)
void parse_free(struct ast_node *node)
{
if(node == NULL) return;
- if(node->label[0] != 0) {
+ if(node_is_op(node)) {
parse_free(node->contents.branches.a);
parse_free(node->contents.branches.b);
parse_free(node->contents.branches.c);
12 src/compiler/parser_helper.h
View
@@ -21,11 +21,11 @@
#include <fpvm/ast.h>
#include <fpvm/fpvm.h>
+#include "symtab.h"
+
/* virtual operation - for use inside the parser only */
-enum {
- op_not = op_vops+1,
-};
+#define op_not (op_vops+1)
struct compiler_sc;
@@ -36,11 +36,11 @@ struct parser_comm {
struct compiler_sc *sc;
} u;
const char *(*assign_default)(struct parser_comm *comm,
- const char *label, struct ast_node *node);
+ struct sym *sym, struct ast_node *node);
const char *(*assign_per_frame)(struct parser_comm *comm,
- const char *label, struct ast_node *node);
+ struct sym *sym, struct ast_node *node);
const char *(*assign_per_vertex)(struct parser_comm *comm,
- const char *label, struct ast_node *node);
+ struct sym *sym, struct ast_node *node);
const char *(*assign_image_name)(struct parser_comm *comm,
int number, const char *name);
};
2  src/compiler/parser_itf.h
View
@@ -28,6 +28,8 @@
struct id {
int token;
const char *label;
+ struct sym *sym;
+ const char *fname;
float constant;
int lineno;
};
4 src/compiler/ptest/Makefile
View
@@ -4,7 +4,7 @@ LIBFPVM_X86 = $(MMDIR)/software/libfpvm/x86-linux
CFLAGS_STANDALONE = -DSTANDALONE=\"standalone.h\"
CFLAGS = -Wall -g -I.. -I. $(CFLAGS_STANDALONE)
-OBJS = ptest.o scanner.o parser.o parser_helper.o unique.o compiler.o \
+OBJS = ptest.o scanner.o parser.o parser_helper.o symtab.o compiler.o \
libfpvm.a
LDLIBS = -lm
@@ -60,7 +60,7 @@ libfpvm.a:
scanner.o: ../parser.h
parser_helper.o: ../parser.h
ptest.o: ../parser.h
-unique.o: ../fnp.inc
+symtab.o: ../fnp.inc
compiler.o: ../infra-fnp.h
# ----- Cleanup ---------------------------------------------------------------
37 src/compiler/ptest/ptest.c
View
@@ -1,7 +1,7 @@
/*
* ptest.c - FNP parser tester
*
- * Copyright 2011 by Werner Almesberger
+ * Copyright 2011-2012 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
@@ -19,10 +19,11 @@
#include "../parser_helper.h"
#include "../parser.h"
#include "../compiler.h"
-#include "../unique.h"
+#include "../symtab.h"
static int quiet = 0;
+static int symbols = 0;
static const char *fail = NULL;
static const char *buffer;
@@ -53,7 +54,7 @@ static void dump_ast(const struct ast_node *ast)
{
switch (ast->op) {
case op_ident:
- printf("%s", ast->label);
+ printf("%s", ast->sym->name);
break;
case op_constant:
printf("%g", ast->contents.constant);
@@ -143,12 +144,12 @@ static void dump_ast(const struct ast_node *ast)
static const char *assign_default(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
if (fail)
return strdup(fail);
if (!quiet) {
- printf("%s = ", label);
+ printf("%s = ", sym->fpvm_sym.name);
dump_ast(node);
putchar('\n');
}
@@ -157,10 +158,10 @@ static const char *assign_default(struct parser_comm *comm,
static const char *assign_per_frame(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
if (!quiet) {
- printf("per_frame = %s = ", label);
+ printf("per_frame = %s = ", sym->fpvm_sym.name);
dump_ast(node);
putchar('\n');
}
@@ -169,10 +170,10 @@ static const char *assign_per_frame(struct parser_comm *comm,
static const char *assign_per_vertex(struct parser_comm *comm,
- const char *label, struct ast_node *node)
+ struct sym *sym, struct ast_node *node)
{
if (!quiet) {
- printf("per_vertex = %s = ", label);
+ printf("per_vertex = %s = ", sym->fpvm_sym.name);
dump_ast(node);
putchar('\n');
}
@@ -238,6 +239,8 @@ static void parse_only(const char *pgm)
const char *error;
error = parse(pgm, TOK_START_ASSIGN, &comm);
+ if (symbols)
+ unique_dump();
unique_free();
if (!error)
return;
@@ -272,6 +275,11 @@ static void dump_regs(const int *alloc, const char (*names)[FPVM_MAXSYMLEN],
static void show_patch(const struct patch *patch)
{
+/*
+ * @@@ Disable for now since we have no good way to get the names and the
+ * mapping archtecture is still in flux.
+ */
+#if 0
int i;
printf("global:\n");
@@ -287,6 +295,7 @@ static void show_patch(const struct patch *patch)
dump_regs(patch->pvv_allocation, pvv_names, patch->pervertex_regs,
COMP_PVV_COUNT);
pfpu_dump(patch->pervertex_prog, patch->pervertex_prog_length);
+#endif
}
@@ -317,11 +326,12 @@ static void free_buffer(void)
static void usage(const char *name)
{
fprintf(stderr,
-"usage: %s [-c|-f error] [-n runs] [-q] [expr]\n\n"
+"usage: %s [-c|-f error] [-n runs] [-q] [-s] [expr]\n\n"
" -c generate code and dump generated code (unless -q is set)\n"
" -f error fail any assignment with specified error message\n"
" -n runs run compilation repeatedly (default: run only once)\n"
" -q quiet operation\n"
+" -s dump symbol table after parsing (only if -c is not set)\n"
, name);
exit(1);
}
@@ -334,7 +344,7 @@ int main(int argc, char **argv)
unsigned long repeat = 1;
char *end;
- while ((c = getopt(argc, argv, "cf:n:q")) != EOF)
+ while ((c = getopt(argc, argv, "cf:n:qs")) != EOF)
switch (c) {
case 'c':
codegen = 1;
@@ -350,11 +360,14 @@ int main(int argc, char **argv)
case 'q':
quiet = 1;
break;
+ case 's':
+ symbols = 1;
+ break;
default:
usage(*argv);
}
- if (codegen && fail)
+ if (codegen && (fail || symbols))
usage(*argv);
switch (argc-optind) {
8 src/compiler/scanner.h
View
@@ -44,12 +44,12 @@ void delete_scanner(struct scanner *s);
/* get to the next token and return its type */
int scan(struct scanner *s);
-/* get the unique string comprising the current token
+/* get the symbol for the unique string comprising the current token
*/
-const char *get_unique_token(struct scanner *s);
+struct sym *get_symbol(struct scanner *s);
-/* like get_unique_token, but malloc'ed non-unique string */
-const char *get_token(struct scanner *s);
+/* malloc'ed non-unique string */
+const char *get_name(struct scanner *s);
float get_constant(struct scanner *s);
6 src/compiler/scanner.re
View
@@ -20,7 +20,7 @@
#include <string.h>
#include <malloc.h>
-#include "unique.h"
+#include "symtab.h"
#include "scanner.h"
#define YYCTYPE unsigned char
@@ -158,13 +158,13 @@ int scan(struct scanner *s)
*/
}
-const char *get_unique_token(struct scanner *s)
+struct sym *get_symbol(struct scanner *s)
{
return unique_n((const char *) s->old_cursor,
s->cursor - s->old_cursor);
}
-const char *get_token(struct scanner *s)
+const char *get_name(struct scanner *s)
{
char *buf;
int n;
160 src/compiler/symtab.c
View
@@ -0,0 +1,160 @@
+/*
+ * symtab.c - Symbol table
+ *
+ * Copyright 2011-2012 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 <string.h>
+#include <assert.h>
+
+#include "compiler.h"
+#include "symtab.h"
+
+
+#define INITIAL_ALLOC 64
+
+
+struct key_n {
+ const char *s;
+ int n;
+};
+
+struct sym well_known[] = {
+#include "fnp.inc"
+};
+
+static struct sym *syms = NULL;
+static int num_syms = 0, allocated = 0;
+
+
+/*
+ * "a" is not NUL-terminated and its length "a" is determined by "n".
+ * "b" is NUL-terminated.
+ */
+
+static int strcmp_n(const char *a, const char *b, int n)
+{
+ int diff;
+
+ diff = strncmp(a, b, n);
+ if (diff)
+ return diff;
+ /* handle implicit NUL in string "a" */
+ return -b[n];
+}
+
+
+static char *strdup_n(const char *s, int n)
+{
+ char *new;
+
+ new = malloc(n+1);
+ memcpy(new, s, n);
+ new[n] = 0;
+ return new;
+}
+
+
+static void grow_table(void)
+{
+ if(num_syms != allocated)
+ return;
+
+ allocated = allocated ? allocated*2 : INITIAL_ALLOC;
+ syms = realloc(syms, allocated*sizeof(*syms));
+}
+
+
+static int cmp(const void *a, const void *b)
+{
+ const struct sym *sym = b;
+
+ return strcmp(a, sym->fpvm_sym.name);
+}
+
+
+static int cmp_n(const void *a, const void *b)
+{
+ const struct key_n *key = a;
+ const struct sym *sym = b;
+
+ return strcmp_n(key->s, sym->fpvm_sym.name, key->n);
+}
+
+
+struct sym *unique(const char *s)
+{
+ struct sym *res;
+ struct sym *walk;
+
+ res = bsearch(s, well_known, sizeof(well_known)/sizeof(*well_known),
+ sizeof(*well_known), cmp);
+ if(res)
+ return res;
+ for(walk = syms; walk != syms+num_syms; walk++)
+ if(!strcmp(walk->fpvm_sym.name, s))
+ return walk;
+ grow_table();
+ syms[num_syms].fpvm_sym.name = strdup(s);
+ syms[num_syms].pfv_idx = syms[num_syms].pvv_idx = -1;
+ return syms+num_syms++;
+}
+
+
+struct sym *unique_n(const char *s, int n)
+{
+ struct key_n key = {
+ .s = s,
+ .n = n,
+ };
+ struct sym *res;
+ struct sym *walk;
+
+ assert(n);
+ res = bsearch(&key, well_known, sizeof(well_known)/sizeof(*well_known),
+ sizeof(*well_known), cmp_n);
+ if(res)
+ return res;
+ for(walk = syms; walk != syms+num_syms; walk++)
+ if(!strcmp_n(s, walk->fpvm_sym.name, n))
+ return walk;
+ grow_table();
+ syms[num_syms].fpvm_sym.name = strdup_n(s, n);
+ syms[num_syms].pfv_idx = syms[num_syms].pvv_idx = -1;
+ return syms+num_syms++;
+}
+
+
+void unique_free(void)
+{
+ int i;
+
+ for(i = 0; i != num_syms; i++)
+ free((void *) syms[i].fpvm_sym.name);
+ free(syms);
+ syms = NULL;
+ num_syms = allocated = 0;
+}
+
+
+#ifdef STANDALONE
+
+void unique_dump(void)
+{
+ int i;
+
+ for(i = 0; i != sizeof(well_known)/sizeof(*well_known); i++)
+ printf("%s\n", well_known[i].fpvm_sym.name);
+ printf("\n");
+ for(i = 0; i != num_syms; i++)
+ printf("%s\n", syms[i].fpvm_sym.name);
+}
+
+#endif /* STANDALONE */
30 src/compiler/symtab.h
View
@@ -0,0 +1,30 @@
+/*
+ * symtab.h - Symbol table
+ *
+ * Copyright 2011-2012 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.
+ */
+
+#ifndef SYMTAB_H
+#define SYMTAB_H
+
+#include <fpvm/symbol.h>
+
+
+struct sym {
+ struct fpvm_sym fpvm_sym;
+ int pfv_idx, pvv_idx; /* index; -1 if not a variable known to FN */
+};
+
+
+#define FPVM2SYM(fpvm_sym) ((struct sym *) (fpvm_sym))
+
+struct sym *unique(const char *s);
+struct sym *unique_n(const char *s, int n);
+void unique_free(void);
+void unique_dump(void);
+
+#endif /* !SYMTAB_H */
7 src/compiler/test/Common
View
@@ -44,7 +44,12 @@ expect()
echo FAILED "($SCRIPT)" 1>&2
cat _diff 1>&2
rm -f _out _diff
- exit 1
+ if ${FAIL_ON_ERROR:-true}; then
+ exit 1
+ else
+ failed=`expr ${failed:-0} + 1`
+ return 1
+ fi
}
echo PASSED 1>&2
rm -f _out _diff
73 src/compiler/test/Patches
View
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+#
+# We explicitly list all the known patches here so that any local additions
+# won't interfere.
+#
+
+forall_patches()
+{
+for n in \
+ "Aderassi - Making time.fnp" \
+ "Aderrasi - Airs.fnp" \
+ "Aderrasi - Antidote (Aqualung Mix).fnp" \
+ "Aderrasi - Bow to gravity.fnp" \
+ "Aderrasi - Variants Of Eternity (Shaking mix).fnp" \
+ "Bmelgren & Krash - Rainbow Orb Peacock (Lonely Signal Gone Mad Mix).fnp" \
+ "EvilJim - Ice Drops.fnp" \
+ "Fvese - The Tunnel (Final Stage Mix).fnp" \
+ "Geiss & Werner - Tornado (Rain Dance MIDI RMX).fnp" \
+ "Geiss - Approach.fnp" \
+ "Geiss - Cruzin'.fnp" \
+ "Geiss - Eggs.fnp" \
+ "Geiss - Shift.fnp" \
+ "Geiss - The Fatty Lumpkin Sunkle Tweaker.fnp" \
+ "Geiss - Tornado.fnp" \
+ "Idiot & Rovastar - Altars Of Madness 2 (X42 Mix).fnp" \
+ "Illusion & Che - The Piper.fnp" \
+ "Illusion & Rovastar - Clouded Bottle.fnp" \
+ "Illusion & Unchained - Frozen Eye 1.fnp" \
+ "Jeremie - conduirebourre.com.fnp" \
+ "Krash - Digital Flame (Video remix).fnp" \
+ "Krash - Digital Flame.fnp" \
+ "Krash - Interwoven (Nightmare Weft Mix).fnp" \
+ "Lekernel & Geiss - Shaking.fnp" \
+ "Lekernel & Krash - Boil off (DMX).fnp" \
+ "Lekernel & Krash - Personal Shroomery.fnp" \
+ "Lekernel & Rovastar & Fvese - Subconscious Objects.fnp" \
+ "Lekernel & Rozzor & Aderassi - Video Cannon.fnp" \
+ "Lekernel & fiShbRaiN - crazy face.fnp" \
+ "Lekernel - Disc Explosion.fnp" \
+ "Lekernel - Drawing Board (DMX).fnp" \
+ "Lekernel - Eerie Beri.fnp" \
+ "Lekernel - Falling (DMX).fnp" \
+ "Lekernel - FullScreen Video-in Preview.fnp" \
+ "Lekernel - Musique de telephone.fnp" \
+ "Lekernel - Pulsating photography.fnp" \
+ "Lekernel - Sailing.fnp" \
+ "Lekernel - Spiralling.fnp" \
+ "Lekernel - Star Ballet (Bass Travel Mix).fnp" \
+ "Lekernel - Star Ballet (Fountain Mix).fnp" \
+ "Lekernel - Star Ballet.fnp" \
+ "Lekernel - Starpainter.fnp" \
+ "Lekernel - The psychedelic drunken boat.fnp" \
+ "Lekernel - Vibrant Plasma Streams.fnp" \
+ "Philpraxis - Eight bit starfield.fnp" \
+ "Rovastar & Fvese - Dark Subconscious.fnp" \
+ "Rovastar & Idiot24-7 - Balk Acid (DMX madness).fnp" \
+ "Rovastar & Idiot24-7 - Balk Acid.fnp" \
+ "Rovastar - A Million Miles from Earth.fnp" \
+ "Rovastar - Cosmic Echoes 2.fnp" \
+ "Rovastar - Explosive Minds.fnp" \
+ "Rovastar - Forgotten Moon.fnp" \
+ "Rovastar - Hallucinogenic Pyramids.fnp" \
+ "Rovastar - Torrid Tales.fnp" \
+ "Rozzor & Aderrasi - Canon (DMX out).fnp" \
+ "Telek - Slow Shift Matrix (bb4.5).fnp" \
+ "Unchained - A Matter Of Taste (Remix).fnp" \
+ "Zylot - The Inner Workings of my New Computer.fnp" \
+ "bmelgren - Godhead (Video mix).fnp" \
+ "nil - Cid and Lucy.fnp"; do
+ eval "$@"
+done
+}
31 src/compiler/test/dualuse
View
@@ -0,0 +1,31 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "dual use: min = sin+cos" <<EOF
+min = sin+cos
+EOF
+expect <<EOF
+min = (+ (sin) (cos))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "dual use: sin = sqr-if" <<EOF
+sin = sqr-if
+EOF
+expect <<EOF
+sin = (- (sqr) (if))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "dual use: if = max*int" <<EOF
+if = max*int
+EOF
+expect <<EOF
+if = (* (max) (int))
+EOF
+
+###############################################################################
2  src/compiler/test/not
View
@@ -16,7 +16,7 @@ ptest_fail "not: !a (try to generate code)" -c << EOF
per_frame: wave_a = !a
EOF
expect <<EOF
-FPVM, line 2: Operation not supported: ! near 'EOF'
+FPVM, line 2: Operation not supported: 29 near 'EOF'
EOF
#------------------------------------------------------------------------------
32 src/compiler/test/nsyms
View
@@ -0,0 +1,32 @@
+#!/bin/sh
+. ./Common
+. ./Patches
+
+###############################################################################
+
+PATCHDIR=../../../patches
+
+count_syms()
+{
+
+ s=`${PTST:-../ptest/ptest} -q -s <"$PATCHDIR/$n" | \
+ sed '1,/^$/d' | wc -l`
+ ns=`expr $ns + $s`
+ np=`expr $np + 1`
+ [ $s -gt $max ] && max=$s
+}
+
+
+echo -n "nsyms: count number of symbols: " 1>&2
+
+max=0
+ns=0
+np=0
+forall_patches count_syms
+echo $max,$ns/$np >_out
+
+expect <<EOF
+12,112/60
+EOF
+
+###############################################################################
73 src/compiler/test/patches
View
@@ -1,5 +1,6 @@
#!/bin/sh
. ./Common
+. ./Patches
###############################################################################
@@ -13,77 +14,15 @@ if [ "$VALGRIND" ]; then
VALGRIND="$VALGRIND --leak-check=full --show-reachable=yes"
fi
-#
-# We explicitly list all the known patches here so that any local additions
-# won't interfere.
-#
-
PATCHDIR=../../../patches
-for n in \
- "Aderassi - Making time.fnp" \
- "Aderrasi - Airs.fnp" \
- "Aderrasi - Antidote (Aqualung Mix).fnp" \
- "Aderrasi - Bow to gravity.fnp" \
- "Aderrasi - Variants Of Eternity (Shaking mix).fnp" \
- "Bmelgren & Krash - Rainbow Orb Peacock (Lonely Signal Gone Mad Mix).fnp" \
- "EvilJim - Ice Drops.fnp" \
- "Fvese - The Tunnel (Final Stage Mix).fnp" \
- "Geiss & Werner - Tornado (Rain Dance MIDI RMX).fnp" \
- "Geiss - Approach.fnp" \
- "Geiss - Cruzin'.fnp" \
- "Geiss - Eggs.fnp" \
- "Geiss - Shift.fnp" \
- "Geiss - The Fatty Lumpkin Sunkle Tweaker.fnp" \
- "Geiss - Tornado.fnp" \
- "Idiot & Rovastar - Altars Of Madness 2 (X42 Mix).fnp" \
- "Illusion & Che - The Piper.fnp" \
- "Illusion & Rovastar - Clouded Bottle.fnp" \
- "Illusion & Unchained - Frozen Eye 1.fnp" \
- "Jeremie - conduirebourre.com.fnp" \
- "Krash - Digital Flame (Video remix).fnp" \
- "Krash - Digital Flame.fnp" \
- "Krash - Interwoven (Nightmare Weft Mix).fnp" \
- "Lekernel & Geiss - Shaking.fnp" \
- "Lekernel & Krash - Boil off (DMX).fnp" \
- "Lekernel & Krash - Personal Shroomery.fnp" \
- "Lekernel & Rovastar & Fvese - Subconscious Objects.fnp" \
- "Lekernel & Rozzor & Aderassi - Video Cannon.fnp" \
- "Lekernel & fiShbRaiN - crazy face.fnp" \
- "Lekernel - Disc Explosion.fnp" \
- "Lekernel - Drawing Board (DMX).fnp" \
- "Lekernel - Eerie Beri.fnp" \
- "Lekernel - Falling (DMX).fnp" \
- "Lekernel - FullScreen Video-in Preview.fnp" \
- "Lekernel - Musique de telephone.fnp" \
- "Lekernel - Pulsating photography.fnp" \
- "Lekernel - Sailing.fnp" \
- "Lekernel - Spiralling.fnp" \
- "Lekernel - Star Ballet (Bass Travel Mix).fnp" \
- "Lekernel - Star Ballet (Fountain Mix).fnp" \
- "Lekernel - Star Ballet.fnp" \
- "Lekernel - Starpainter.fnp" \
- "Lekernel - The psychedelic drunken boat.fnp" \
- "Lekernel - Vibrant Plasma Streams.fnp" \
- "Philpraxis - Eight bit starfield.fnp" \
- "Rovastar & Fvese - Dark Subconscious.fnp" \
- "Rovastar & Idiot24-7 - Balk Acid (DMX madness).fnp" \
- "Rovastar & Idiot24-7 - Balk Acid.fnp" \
- "Rovastar - A Million Miles from Earth.fnp" \
- "Rovastar - Cosmic Echoes 2.fnp" \
- "Rovastar - Explosive Minds.fnp" \
- "Rovastar - Forgotten Moon.fnp" \
- "Rovastar - Hallucinogenic Pyramids.fnp" \
- "Rovastar - Torrid Tales.fnp" \
- "Rozzor & Aderrasi - Canon (DMX out).fnp" \
- "Telek - Slow Shift Matrix (bb4.5).fnp" \
- "Unchained - A Matter Of Taste (Remix).fnp" \
- "Zylot - The Inner Workings of my New Computer.fnp" \
- "bmelgren - Godhead (Video mix).fnp" \
- "nil - Cid and Lucy.fnp"; do
+do_test()
+{
ptest "patch: $n" -c -q <"$PATCHDIR/$n"
expect </dev/null
-done
+}
+
+forall_patches do_test
VALGRIND=$valgrind_orig
135 src/compiler/unique.c
View
@@ -1,135 +0,0 @@
-/*
- * unique.c - Unique string store
- *
- * 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 <string.h>
-#include <assert.h>
-
-#include "unique.h"
-
-
-#define INITIAL_ALLOC 64
-
-
-struct key_n {
- const char *s;
- int n;
-};
-
-const char *well_known[] = {
-#include "fnp.inc"
-};
-
-static const char **vars = NULL;
-static int num_vars = 0, allocated = 0;
-
-
-/*
- * "a" is not NUL-terminated and its length "a" is determined by "n".
- * "b" is NUL-terminated.
- */
-
-static int strcmp_n(const char *a, const char *b, int n)
-{
- int diff;
-
- diff = strncmp(a, b, n);
- if (diff)
- return diff;
- /* handle implicit NUL in string "a" */
- return -b[n];
-}
-
-
-static char *strdup_n(const char *s, int n)
-{
- char *new;
-
- new = malloc(n+1);
- memcpy(new, s, n);
- new[n] = 0;
- return new;
-}
-
-
-static void grow_table(void)
-{
- if(num_vars != allocated)
- return;
-
- allocated = allocated ? allocated*2 : INITIAL_ALLOC;
- vars = realloc(vars, allocated*sizeof(*vars));
-}
-
-
-static int cmp(const void *a, const void *b)
-{
- return strcmp(a, *(const char **) b);
-}
-
-
-static int cmp_n(const void *a, const void *b)
-{
- const struct key_n *key = a;
-
- return strcmp_n(key->s, *(const char **) b, key->n);
-}
-
-
-const char *unique(const char *s)
-{
- const char **res;
- const char **walk;
-
- res = bsearch(s, well_known, sizeof(well_known)/sizeof(*well_known),
- sizeof(s), cmp);
- if(res)
- return *res;
- for(walk = vars; walk != vars+num_vars; walk++)
- if(!strcmp(*walk, s))
- return *walk;
- grow_table();
- return vars[num_vars++] = strdup(s);
-}
-
-
-const char *unique_n(const char *s, int n)
-{
- struct key_n key = {
- .s = s,
- .n = n,
- };
- const char **res;
- const char **walk;
-
- assert(n);
- res = bsearch(&key, well_known, sizeof(well_known)/sizeof(*well_known),
- sizeof(s), cmp_n);
- if(res)
- return *res;
- for(walk = vars; walk != vars+num_vars; walk++)
- if(!strcmp_n(s, *walk, n))
- return *walk;
- grow_table();
- return vars[num_vars++] = strdup_n(s, n);
-}
-
-
-void unique_free(void)
-{
- int i;
-
- for(i = 0; i != num_vars; i++)
- free((void *) vars[i]);
- free(vars);
- vars = NULL;
- num_vars = allocated = 0;
-}
18 src/compiler/unique.h
View
@@ -1,18 +0,0 @@
-/*
- * unique.h - Unique string store
- *
- * 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.
- */
-
-#ifndef UNIQUE_H
-#define UNIQUE_H
-
-const char *unique(const char *s);
-const char *unique_n(const char *s, int n);
-void unique_free(void);
-
-#endif /* !UNIQUE_H */

No commit comments for this range

Something went wrong with that request. Please try again.