Skip to content

Commit

Permalink
GH-18 Resolve the CATCH THROW issues, in part by refactoring the
Browse files Browse the repository at this point in the history
parsing loop into a more Forth like word structure GH-20.  Added
more tests.  Start re-working the DO..LEAVE..+LOOP family of words
GH-23, which is incomplete at for the moment.  This breaks some of
the examples such as `life1d.p4` and `life.p4` GH-23.
  • Loading branch information
SirWumpus committed Aug 25, 2024
1 parent 8997f60 commit 5f50ac5
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 209 deletions.
10 changes: 8 additions & 2 deletions src/.gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end
define showrs
p ctx->rs.top + 1 - ctx->rs.base
p ctx->rs
x/16gx ctx->rs.base-2
x/24gx ctx->rs.base-2
end

define showword
Expand All @@ -45,7 +45,13 @@ commands
finish
end

b p4Repl:_repl
b p4Repl:_interpret
disable 2
b p4Repl:_inter_loop
disable 3
b p4Repl:_halt
disable 4
b p4Repl:_evaluate
disable 5

show user
5 changes: 5 additions & 0 deletions src/makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,8 @@ post4.i : config.h post4.h post4.c

test : post4$E
cd ../test && ${MAKE} $@

valgrind: post4$E
echo BYE | valgrind --leak-check=full ./post4$E
valgrind --leak-check=full ./post4$E ../test/units.p4
valgrind --leak-check=full ./post4$E ../examples/life1d.p4
109 changes: 69 additions & 40 deletions src/post4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1302,11 +1302,24 @@ p4Repl(P4_Ctx *ctx, int rc)
P4_Cell w, x, *ip;

static P4_Word words[] = {
P4_WORD("_repl", &&_repl, P4_BIT_HIDDEN, 0x00),
P4_WORD("LIT", &&_lit, 0, 0x01), // historic
#define w_lit words[0]
P4_WORD(";", &&_exit, P4_BIT_HIDDEN, 0x10), // _seext
#define w_semi words[1]
P4_WORD("_abort", &&_abort, 0, 0x00),
#define w_abort words[2]
P4_WORD("_quit", &&_quit, 0, 0x00),
#define w_quit words[3]
P4_WORD("_interpret", &&_interpret, 0, 0x00),
#define w_interpret words[4]
P4_WORD("REFILL", &&_refill, 0, 0x01),
#define w_refill words[5]
P4_WORD("_branchnz", &&_branchnz, 0, 0x10),
#define w_branchnz words[6]
#ifdef HAVE_HOOKS
P4_WORD("_hook_add", &&_hook_add, 0, 0x10), // p4
P4_WORD("_hook_call", &&_hook_call, 0, 0x00), // p4
#endif
#ifdef HAVE_MATH_H
// P4_WORD("min-float", &&_min_float, 0, 0x01), // p4
P4_WORD("max-float", &&_max_float, 0, 0x01), // p4
Expand Down Expand Up @@ -1382,10 +1395,6 @@ p4Repl(P4_Ctx *ctx, int rc)
P4_WORD("_ds", &&_ds, 0, 0x03), // p4
P4_WORD("_dsp@", &&_dsp_get, 0, 0x01), // p4
P4_WORD("_dsp!", &&_dsp_put, 0, 0x10), // p4
#ifdef HAVE_HOOKS
P4_WORD("_hook_add", &&_hook_add, 0, 0x10), // p4
P4_WORD("_hook_call", &&_hook_call, 0, 0x00), // p4
#endif
P4_WORD("_input_push", &&_input_push, 0, 0x0600), // p4
P4_WORD("_input_pop", &&_input_pop, 0, 0x6000), // p4
P4_WORD("_longjmp", &&_longjmp, 0, 0x10), // p4
Expand Down Expand Up @@ -1495,7 +1504,6 @@ p4Repl(P4_Ctx *ctx, int rc)
P4_WORD("MS", &&_ms, 0, 0x10),
P4_WORD("_parse", &&_parse, 0, 0x22), // p4
P4_WORD("PARSE-NAME", &&_parse_name, 0, 0x02),
P4_WORD("REFILL", &&_refill, 0, 0x01),
P4_WORD("SAVE-BUFFERS", &&_save_buffers, 0, 0x00),
P4_WORD("SOURCE", &&_source, 0, 0x02),
P4_WORD("SOURCE-ID", &&_source_id, 0, 0x01),
Expand All @@ -1505,17 +1513,6 @@ p4Repl(P4_Ctx *ctx, int rc)
P4_WORD(NULL, NULL, 0, 0),
};

#define w_repl words[0] // See exec[].
#define w_lit words[1]
#define w_semi words[2] // See _seext.

/* When the REPL executes a word, it puts the XT of the word here
* and starts the machine with the IP pointed to exec[]. When the
* word completes the next XT (w_repl) transitions from threaded
* code back into the C driven REPL.
*/
static P4_Cell exec[] = { { 0 }, { .w = &w_repl } };

if (p4_builtin_words == NULL) {
/* Link up the base dictionary. */
for (word = words; word->code != NULL; word++) {
Expand All @@ -1528,9 +1525,24 @@ p4Repl(P4_Ctx *ctx, int rc)
#define NEXT goto _next
#define THROW(x) { rc = (x); goto _thrown; }

static P4_Word w_inter_loop = P4_WORD("_inter_loop", &&_inter_loop, P4_BIT_HIDDEN, 0x00);
static P4_Word w_halt = P4_WORD("_halt", &&_halt, P4_BIT_HIDDEN, 0x00);
static P4_Word w_ok = P4_WORD("_ok", &&_ok, P4_BIT_HIDDEN, 0x00);
static P4_Cell repl[] = {
{.w = &w_interpret}, {.w = &w_ok}, {.w = &w_refill},
{.w = &w_branchnz}, {.n = -4 * sizeof (P4_Cell)},
{.w = &w_halt}
};
/* When the REPL executes a word, it puts the XT of the word here
* and executes the word with the IP pointed to exec[]. When the
* word completes the next XT transitions from threaded code back
* into the C driven REPL.
*/
static P4_Cell exec[] = { { 0 }, {.w = &w_inter_loop} };

_thrown:
switch (rc) {
case P4_THROW_TERMINATE:
case P4_THROW_SIGTERM:
/* Return shell equivalent exit status. */
(void) printf(crlf);
return 128+SIGTERM;
Expand Down Expand Up @@ -1596,12 +1608,15 @@ _quit: P4_RESET(ctx->rs);
case P4_THROW_OK:
;
}
_repl: p4StackGuards(ctx);
/* The input buffer might have been primed (EVALUATE, LOAD),
* so try to parse it first before reading more input.
*/
do {
while (ctx->input.offset < ctx->input.length) {
ip = repl+1;

// do {
/* The input buffer might have been primed (EVALUATE, LOAD),
* so try to parse it first before reading more input.
*/
_interpret: p4StackGuards(ctx);
P4_PUSH(ctx->rs, ip);
_inter_loop: while (ctx->input.offset < ctx->input.length) {
str = p4ParseName(&ctx->input);
if (str.length == 0) {
break;
Expand Down Expand Up @@ -1629,18 +1644,23 @@ _repl: p4StackGuards(ctx);
} else if (ctx->state == P4_STATE_COMPILE && !P4_WORD_IS_IMM(word)) {
p4WordAppend(ctx, (P4_Cell) word);
} else {
// Setup XT of word found to execute.
exec[0].w = word;
ip = exec;
NEXT;
}
}
if (P4_INTERACTIVE(ctx)) {
ip = P4_POP(ctx->rs).p;
NEXT;

_ok: if (P4_INTERACTIVE(ctx)) {
(void) printf("ok ");
(void) fflush(stdout);
}
} while (p4Refill(ctx, &ctx->input));
if (P4_INTERACTIVE(ctx)) {
NEXT;

// } while (p4Refill(ctx, &ctx->input));

_halt: if (P4_INTERACTIVE(ctx)) {
(void) printf(crlf);
}
return rc;
Expand Down Expand Up @@ -1701,6 +1721,14 @@ _branchz: w = *ip;
ip = (P4_Cell *)((P4_Char *) ip + (x.u == 0 ? w.n : P4_CELL));
NEXT;

// ( flag -- )
_branchnz: w = *ip;
x = P4_POP(ctx->ds);
p4TraceLit(ctx, x);
p4TraceLit(ctx, w);
ip = (P4_Cell *)((P4_Char *) ip + (x.u != 0 ? w.n : P4_CELL));
NEXT;

#ifdef HAVE_HOOKS
// ( func `<spaces>name` -- )
_hook_add: str = p4ParseName(&ctx->input);
Expand Down Expand Up @@ -1848,22 +1876,23 @@ _rm_marker: x.w = w.xt;

_input_push: p4StackGuards(ctx);
w.p = ctx->rs.top+1;
P4_DROP(ctx->rs, -sizeof (P4_Input) / sizeof (P4_Cell));
P4_DROP(ctx->rs, -sizeof (ctx->input) / sizeof (P4_Cell));
(void) memcpy(w.v, &ctx->input, sizeof (ctx->input));
NEXT;

_input_pop: P4_DROP(ctx->rs, sizeof (P4_Input) / sizeof (P4_Cell));
_input_pop: P4_DROP(ctx->rs, sizeof (ctx->input) / sizeof (P4_Cell));
w.p = ctx->rs.top+1;
(void) memcpy(&ctx->input, w.v, sizeof (ctx->input));
p4StackGuards(ctx);
NEXT;

// ( i*x caddr u -- j*x )
_evaluate: w = P4_POP(ctx->ds);
x = P4_POP(ctx->ds);
rc = p4EvalString(ctx, x.s, w.u);
NEXT;

_evaluate: ctx->input.length = P4_POP(ctx->ds).z;
ctx->input.buffer = P4_POP(ctx->ds).s;
ctx->input.fp = (FILE *) -1;
ctx->input.offset = 0;
ctx->input.blk = 0;
goto _interpret;

/* CREATE DOES> is bit of a mind fuck. Their purpose is to define
* words that in turn define new words. Best to look at a simple
Expand Down Expand Up @@ -2103,15 +2132,14 @@ _dup: w = P4_TOP(ctx->ds);
NEXT;

// ( xu ... x1 x0 u -- xu ... x1 x0 xu )
// Could be implemented in Post4 minus the stack depth check.
// : PICK >R _ds DROP 1 - CELLS + R> CELLS - @ ;
// : PICK >R _DS DROP 1 - R> - CELLS + @ ;
// 0 PICK == DUP, 1 PICK == OVER
_pick: w = P4_POP(ctx->ds);
x = P4_PICK(ctx->ds, w.u);
P4_PUSH(ctx->ds, x);
NEXT;

// ( x y -- y x )
// ( x y -- y x ): pp _ds drop 2 - rot - cells + @ ;
// 1 ROLL == SWAP
_swap: w = P4_POP(ctx->ds);
x = P4_TOP(ctx->ds);
Expand Down Expand Up @@ -2636,7 +2664,8 @@ _seext: word = P4_POP(ctx->ds).xt;
w.u += P4_CELL + P4_CELL_ALIGN(w.p[1].u + 1);
} else {
(void) printf("%.*s ", (int) x.w->name.length, x.w->name.string);
if ((x.w->code == &&_branch || x.w->code == &&_branchz || x.w->code == &&_call)) {
if (x.w->code == &&_branch || x.w->code == &&_branchz
|| x.w->code == &&_branchnz || x.w->code == &&_call) {
/* If a branch/call is postponed then it is a control
* structure definition so what follows is an xt, not
* a relative distance.
Expand Down Expand Up @@ -3028,7 +3057,7 @@ static int signalmap[][2] = {
{ SIGFPE, P4_THROW_SIGFPE },
{ SIGQUIT, P4_THROW_QUIT },
{ SIGSEGV, P4_THROW_SIGSEGV },
{ SIGTERM, P4_THROW_TERMINATE },
{ SIGTERM, P4_THROW_SIGTERM },
{ 0, 0 }
};

Expand Down
28 changes: 16 additions & 12 deletions src/post4.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,20 +328,24 @@ struct p4_word {
#define P4_BIT_HIDDEN 0x0004
#define P4_BIT_COMPILE 0x0008

#define P4_WORD_IS_IMM(w) (((w)->bits & P4_BIT_IMM) == P4_BIT_IMM)
#define P4_WORD_SET_IMM(w) ((w)->bits |= P4_BIT_IMM)
#define P4_WORD_CLEAR_IMM(w) ((w)->bits &= ~P4_BIT_IMM)
#define P4_WORD_IS(w, bit) (((w)->bits & (bit)) == (bit))
#define P4_WORD_SET(w, bit) ((w)->bits |= (bit))
#define P4_WORD_CLEAR(w, bit) ((w)->bits &= ~(bit))

#define P4_WORD_WAS_CREATED(w) (((w)->bits & P4_BIT_CREATED) == P4_BIT_CREATED)
#define P4_WORD_SET_CREATED(w) ((w)->bits |= P4_BIT_CREATED)
#define P4_WORD_IS_IMM(w) P4_WORD_IS(w, P4_BIT_IMM)
#define P4_WORD_SET_IMM(w) P4_WORD_SET(w, P4_BIT_IMM)
#define P4_WORD_CLEAR_IMM(w) P4_WORD_CLEAR(w, P4_BIT_IMM)

#define P4_WORD_IS_HIDDEN(w) (((w)->bits & P4_BIT_HIDDEN) == P4_BIT_HIDDEN)
#define P4_WORD_SET_HIDDEN(w) ((w)->bits |= P4_BIT_HIDDEN)
#define P4_WORD_CLEAR_HIDDEN(w) ((w)->bits &= ~P4_BIT_HIDDEN)
#define P4_WORD_WAS_CREATED(w) P4_WORD_IS(w, P4_BIT_CREATED)
#define P4_WORD_SET_CREATED(w) P4_WORD_SET(w, P4_BIT_CREATED)

#define P4_WORD_IS_COMPILE(w) (((w)->bits & P4_BIT_COMPILE) == P4_BIT_COMPILE)
#define P4_WORD_SET_COMPILE(w) ((w)->bits |= P4_BIT_COMPILE)
#define P4_WORD_CLEAR_COMPILE(w) ((w)->bits &= ~P4_BIT_COMPILE)
#define P4_WORD_IS_HIDDEN(w) P4_WORD_IS(w, P4_BIT_HIDDEN)
#define P4_WORD_SET_HIDDEN(w) P4_WORD_SET(w, P4_BIT_HIDDEN)
#define P4_WORD_CLEAR_HIDDEN(w) P4_WORD_CLEAR(w,P4_BIT_HIDDEN)

#define P4_WORD_IS_COMPILE(w) P4_WORD_IS(w, P4_BIT_COMPILE)
#define P4_WORD_SET_COMPILE(w) P4_WORD_SET(w, P4_BIT_COMPILE)
#define P4_WORD_CLEAR_COMPILE(w) P4_WORD_CLEAR(w, P4_BIT_COMPILE)

#ifdef USE_STACK_CHECKS
P4_Uint poppush;
Expand Down Expand Up @@ -514,7 +518,7 @@ typedef struct {

/* -4095..-256 reserved for the system (that's us). */

#define P4_THROW_TERMINATE (-256)
#define P4_THROW_SIGTERM (-256)
#define P4_THROW_GENERIC (-4095)

/***********************************************************************
Expand Down
Loading

0 comments on commit 5f50ac5

Please sign in to comment.