[net.lang.c] goto/forth

cottrell@nbs-vms.ARPA (02/20/85)

/*
> I came up with the following piece of C code the other night.  A friend and
> I were talking about ways of writing a generic Forth interpretor in C.
> We realized that the register save/restore at procedure call cost a lot
> when you have lots of small routines (as in a forth interpretor).  Also,
> a large switch statement has expenses of its own.  Then we thought about 
> indirect goto's.  et voila:
> 
> 	main()
> 	{
> 		int *a;
> 
> 	b:
> 		a = b;
> 		printf("a = 0x%x\n", a);
> 	}
> 
> (NOTE: This was compiled under 4.2BSD on a -750)
> 
> This compiles and runs perfectly.  However, when adding an obvious statement
> (namely, "goto *a") it won't let us compile it.  It seems like the compiler
> will *almost* let us do this.
> 
> What I want to know is, "can this be easily added to the language?",
> "Is it a reasonable thing to add?".  Comments anyone?
> 
> -- 
> -:--:-
> David Herron;

Technically it is illegal to assign `a=b', altho some compilers allow 
it. I read the release notes of a C compiler (pwb?) by dmr wondering
why a label could be passed to as an argument. It seemed to be 
interpreted as a funxion ptr. Try using setjmp/longjmp to do this.

	jim
*/

tmb@talcott.UUCP (Thomas M. Breuel) (02/22/85)

> Technically it is illegal to assign `a=b', altho some compilers allow 
> it. I read the release notes of a C compiler (pwb?) by dmr wondering
> why a label could be passed to as an argument. It seemed to be 
> interpreted as a funxion ptr. Try using setjmp/longjmp to do this.

setjmp/longjmp are slow, and they have the (in this case undesirable)
side effect of re-storing automatic variables. When I was faced with
the problem in a LISP interpreter, I came up with:

#define transfer(f)	return(fun)f

fun next();

fun start()
{
	transfer(next);
}

eval()
{
	register fun kont=start;

	while(kont) kont=(fun)(*kont)();
}

This is actually relatively fast and efficient (at least on a 68000).
The price that you pay is that certain things (in particular in a
LISP interpreter) become difficult because you can't really call eval
recursively. In my case that does not matter, since the LISP evaluation
stack is handled separately anyhow, and since I am using a non-recursive
garbage collector, a pushdown automaton for the reader, ... .

						Thomas.

cottrell@nbs-vms.ARPA (03/01/85)

/*
I tried to send this to the author directly, but couldn't, so...

> Now.  Why didn't you think about your response before posting?

Probably because you didn't make yourself quite clear. I was also
responding to another point, namely the assignment of a label name
to a variable. I didn't realize you had more than one label to
goto. However, you could do multiple setjmp's with DIFFERENT
jmp_buf's, possibly an array of them, and longjmp(jmp_buf[x],val).
This is clearly absurd, but interesting for at least two seconds.
BTW, which NPR do you listen to & where? I love WAMU in DC, lotsa
bluegrass & jazz. WETA also carries the Grateful Dead concerts
New Years Eve. Send me your FORTH interpreter when you're done,
I'd like to play with it.

	jim
*/

eliovson@aecom.UUCP (Moshe Eliovson) (03/06/85)

> > Technically it is illegal to assign `a=b', altho some compilers allow 
> > it. I read the release notes of a C compiler (pwb?) by dmr wondering
> > why a label could be passed to as an argument. It seemed to be 
> > interpreted as a funxion ptr. Try using setjmp/longjmp to do this.
> 
> setjmp/longjmp are slow, and they have the (in this case undesirable)
> side effect of re-storing automatic variables. When I was faced with
> the problem in a LISP interpreter, I came up with:
> 
> #define transfer(f)	return(fun)f
> 
> fun next();
> 
> fun start()
> {
> 	transfer(next);
> }
> 
> eval()
> {
> 	register fun kont=start;
> 
> 	while(kont) kont=(fun)(*kont)();
> }
> 
> 						Thomas.

	How does this simulate 'a=b'?  Could you please explain
	what this code is meant to do and how it achieves it?

	Moshe Eliovson
	philabs!aecom!eliovson