>
> Thanks for that. I look forward to the day that I can
> understand it :)
Well, it took some time to write it ;-) It is a very powerful
demonstration of REBOLs ability to do most things you want if *you* are
up to it.
What does this script do? It creates a "hidden" context using the 'use
construct. The value returned from the code block of 'use is a function
that has access to all these words/values.
So... the use context can act as an extra stack frame. This is exactly
what it does: it sets a flag for a function (metafunc) to inidicate
recursive calling. Innerfunc is inside metafunc and is your actual code.
Metafunc simply counts and implements a goto with throwing away the
"current stack frame" (local words).
All the p1 and p2 stuff is to pass/count refinements.
Enjoy your headache ;-)
--Maarten
> > No, but I wrote a function that does this. Only for
> > tail recursive
> > functions though. And gives you good insight in
> > cracking some REBOL nuts
> > ;-)
> >
> > See below....
> > ----------------------------------------
> >
> > REBOL []
> >
> >
> > tail-func: func
> > [
> > {Returns a function that handles tail-recursion
> > transparently.}
> > args [block!] body [block!]
> > /local _*meta-func _*meta-spec _*meta-body
> > _*statement _*comm _*p1
> > _*p2 _*r _*w
> > ]
> > [
> > _*meta-spec: append/only copy [] args
> > _*meta-body: append/only copy [] body
> >
> > ;matches refinements and copies refinements to our
> > command
> > _*p1: [ set _*r refinement!
> > (either get bind to-word _*r '_*comm [append
> > _*comm mold _*r
> > _*ref-mode: on][ _*ref-mode: off ])]
> > ;matches words and copies their values to the
> > statement if ref-mode =
> > on
> > _*p2: [ set _*w word! (if _*ref-mode [ append/only
> > _*statement get
> > bind to-word _*w '_*comm])]
> >
> >
> > _*meta-func: copy
> > [
> > ;The use context is accessible from the wrapper
> > function that
> > ;eliminates tail recursion. It plays the role of a
> > stack frame
> > ;it implements a goto like behaviour in case of
> > tail recursion
> > use [ _*loop-detected _*myself _*innerfunc _*loops
> > _*myspec _*myspec2
> > _*mycall]
> > [
> > ;some static initialization of the use context
> > varaiables
> > _*loops: 0
> > _*loop-detected: false
> > _*mycall: copy []
> > _*innerfunc: func (_*meta-spec) (_*meta-body)
> > _*myspec: copy first :_*innerfunc
> > _*myspec2: either found? find _*myspec /local
> > [append copy _*myspec [_*ref-mode _*p1 _*p2 _*r
> > _*w _*comm
> > _*statement _*ret]]
> > [append copy _*myspec [/local _*ref-mode _*p1
> > _*p2 _*r _*w _*comm
> > _*statement _*ret]]
> > insert/only _*myspec2 [catch]
> >
> > ;The function that is returned from the use
> > context
> > _*myself: func _*myspec2
> > [
> > ;How deep in a loop am I?
> > _*loops: _*loops + 1
> >
> > ;These parse rules extract how I am called
> > ;(which refinements and so)
> > _*p1: [(_*p1)]
> > _*p2: [(_*p2)]
> > _*ref-mode: on
> >
> > ;Our initial call
> > _*comm: copy {_*innerfunc}
> > ;Our initial statement
> > _*statement: copy []
> >
> > ;Generate our statement and call
> > parse _*myspec [ any [ _*p1 | _*p2 ]]
> > insert _*statement to-path _*comm
> >
> > ;Copy it in the use context so it survives
> > ;a loop (_*mycall is the 'goto args)
> > _*mycall: copy _*statement
> >
> > if _*loops = 2
> > [
> > _*loops: 1
> > _*loop-detected: true
> > return
> > ]
> >
> > ;Until we are no longer in loop-detection mode
> > until
> > [
> > _*loop-detected: false
> > set/any '_*ret do bind _*mycall '_*loops
> > not _*loop-detected
> > ]
> >
> > ;Use context cleanup
> > _*loops: 0
> > _*loop-detected: false
> > _*mycall: copy []
> >
> >
> > ;return our value
> > return get/any '_*ret
> > ];_*myself: func ...
> >
> > ];use context
> >
> > ];meta-func
> >
> > ;return our function....
> > do compose/deep _*meta-func
> > ]
> >
> > ;example usage
> > f: tail-func [x][x: x + 1 print x f x]
> >
> > --
> > To unsubscribe from this list, just send an email to
> > [EMAIL PROTECTED] with unsubscribe as the
> > subject.
> >
>
>
________________________________________________________________________
> Want to chat instantly with your online friends? Get the FREE Yahoo!
> Messenger http://mail.messenger.yahoo.co.uk
> --
> To unsubscribe from this list, just send an email to
> [EMAIL PROTECTED] with unsubscribe as the subject.
--
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.