# Failure (was: Joy inbuilt editor)

## John Cowan — 2001-05-16 13:20:46

    Manfred von Thun wrote:

     > You know a lot more about setjmp than I do. I have only used

    > it for "escape from error, back to main", the sort of thing

    > which in Pascal tends to be a simple "GOTO 1", where the label 1

    > is in the main program.

     Setjmp and longjmp are rather like labels and gotos, except

    that the jmp_buf is a fully reified continuation.  Thus

    one can have code something like this:

    static jmp_buf fail_buf;

    ...

    exeterm() {

         jmp_buf local_fail_buf;

         /* local_fail_buf = fail_buf does not work */

         memcpy(local_fail_buf, fail_buf, sizeof(fail_buf));

         if (setjmp(fail_buf)) {

             /* fail invoked */ }

         else {

             /* normal execution */ }

         /* fail_buf = local_fail_buf does not work */

         memcpy(fail_buf, local_fail_buf, sizeof(fail_buf));

    }

    fail() {

         longjmp(fail_buf, 1);

         }

    Invoking "fail" will cause the setjmp at the most recent

    dynamic instance of exeterm to be resumed in the "true"

    path of the "if setjmp" conditional.

    --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## Manfred von Thun — 2001-05-17 01:33:26

    This is my wishlist for additions to John Cowan's Joy 1.0 beta

    I am sending it to the group in case anyone wants to update

    their own version of my prototype Joy 0.0

    The additions concern seven new operators for shuffling

    the top elements of the stack.

    The first new operator is "rotate" for interchanging the

    first and third element of the stack. The other new operators

    are variants of the (now 6) ordinary stack shuffling operators.

    For  X = (pop,dup,swap,rollup,rolldown,rotate), a variant

    is introduced called "Xd", with the "d" for "dipped".

    For example "swapd" would be the same as "[swap] dip".

    See the new online manual entries below for details.

    The first reason for the additions is to make the naming of the

    variants more systematic than what I have in the standard library.

    The other reason is to make these variants more efficient.

    The additions are just inside the main interpreter file interp.c

    (John will know that the four cases of  ->u.num  will have to be

    changed for his Joy 1.0 beta.)

     - Manfred

    --- There are just two consecutive additions to interp.c

    --- The first is for the code, the second for the online manual.

    --- insert this just after "rollup" and "rolldown"

    --- This is a new operator "rotate" and a new macro for defining

    --- "dipped" versions of the principal stack shuffling operators

    PRIVATE void rotate_()

    {

        THREEPARAMS("rotate");

        SAVESTACK;

        TERNARY(SAVED1->op,SAVED1->u.num);

        NULLARY(SAVED2->op,SAVED2->u.num);

        NULLARY(SAVED3->op,SAVED3->u.num);

        POP(dump);

    }

    #define DIPPED(PROCEDURE,NAME,PARAMCOUNT,ARGUMENT)		\

    PRIVATE void PROCEDURE()					\

    {   PARAMCOUNT(NAME);						\

        SAVESTACK;							\

        POP(stk);							\

        ARGUMENT();							\

        NULLARY(SAVED1->op,SAVED1->u.num);				\

        POP(dump);							\

    }

    DIPPED(popd_,"popd",TWOPARAMS,pop_)

    DIPPED(dupd_,"dupd",TWOPARAMS,dup_)

    DIPPED(swapd_,"swapd",THREEPARAMS,swap_)

    DIPPED(rolldownd_,"rolldownd",FOURPARAMS,rolldown_)

    DIPPED(rollupd_,"rollupd",FOURPARAMS,rollup_)

    DIPPED(rotated_,"rotated",FOURPARAMS,rotate_)

    --- END of fist insertion just after "rollup" and "rolldown"

    --- insert the following in the online manual section

    --- just after the entries for "rollup" and "rolldown"

    {"rotate",		rotate_,	"X Y Z  ->  Z Y X",

    "Interchanges X and Z"},

    {"popd",		popd_,		"Y Z  ->  Z",

    "As if defined by:   popd  ==  [pop] dip "},

    {"dupd",		dupd_,		"Y Z  ->  Y Y Z",

    "As if defined by:   dupd  ==  [dup] dip"},

    {"swapd",		swapd_,		"X Y Z  ->  Y X Z",

    "As if defined by:   swapd  ==  [swap] dip"},

    {"rollupd",		rollupd_,	"X Y Z W  ->  Z X Y W",

    "As if defined by:   rollupd  ==  [rollup] dip"},

    {"rolldownd",		rolldownd_,	"X Y Z W  ->  Y Z X W",

    "As if defined by:   rolldownd  ==  [rolldown] dip "},

    {"rotated",		rotated_,	"X Y Z W  ->  Z Y X W",

    "As if defined by:   rotated  ==  [rotate] dip"},

    --- END of second insertion

## Manfred von Thun — 2001-05-17 01:46:15

    On Wed, 16 May 2001, John Cowan wrote:

     > Setjmp and longjmp are rather like labels and gotos, except

    > that the jmp_buf is a fully reified continuation.  Thus

    > one can have code something like this:

    >

    > static jmp_buf fail_buf;

    > ...

    > exeterm() {

    >      jmp_buf local_fail_buf;

    >

    >      /* local_fail_buf = fail_buf does not work */

    >      memcpy(local_fail_buf, fail_buf, sizeof(fail_buf));

    >

    >      if (setjmp(fail_buf)) {

    >          /* fail invoked */ }

    >      else {

    >          /* normal execution */ }

    >

    >      /* fail_buf = local_fail_buf does not work */

    >      memcpy(fail_buf, local_fail_buf, sizeof(fail_buf));

    > }

     Wow ! I haven't used such sophisticated versions of jmpbuf, and

    have not seen any description of such wizardry. One obvious

    concern: if this is inside  exeterm() , will the memcpy have

    to be executed for every instruction (even the simplest operators

    such as dup ?). I take it that this would slow down execution

    for everything, but I do not know by how much. Also, do these

    buffers get allocated on the stack or elsewhere, do they need

    GC? I am completely lost about these matters.

      - Manfred