Thursday, December 8, 2011

Indexed stack shufflers - part 4 (final)

Let's finish this chapter at once.
Here's a less flippant implementation of the stack shufflers we've been discussing.
USING: fry locals.parser locals.types math.parser math.ranges
multiline namespaces sequences ;
IN: shortlocals

: >n-locals ( n -- seq ) [1,b] [ number>string ] map ;

: define-n-locals ( accum n -- accum )
>n-locals '[ _ [ make-local ] map ] H{ } make-assoc ! words hash
(parse-lambda) <lambda> ?rewrite-closures append! ;

SYNTAX: [2> 2 define-n-locals ;
SYNTAX: [3> 3 define-n-locals ;

And here's how it works (notice how it plays nice with other local-introducing parse-words):
IN: scratchpad 2 9 [2> 2 1 / ] call .
4+1/2
IN: scratchpad 2 9 [2> 2 1 / 3 + ] call .
7+1/2
IN: scratchpad 2 9 100 [3> 2 1 / 3 + ] call .
104+1/2
IN: scratchpad 2 9 100 [3> 3 [| a | a 1 / ] call 2 1 3array ] call .
{ 50 9 2 }

define-n-locals is defined exactly as [| is, except we skip the first step inside parse-lambda (i.e. we skip parse-local-defs and instead simply provide the sequence of strings to build locals from.

I also consulted with the Factor Gods and they told me it's impossible to write a version of [2> that simply adds " [| 1 2 | " to the code (which would be sort of the equivalent of C-style "macros", I think).

To which I replied that it's impossible except for one very dirty way of doing it. I'll save that for a future post, when I'm feeling flippant again.

No comments:

Post a Comment