On Thursday, March 23, 2023 at 11:16:01 PM UTC-5, luser droog wrote:
> On Thursday, March 23, 2023 at 10:54:51 AM UTC-5, luser droog wrote:
> > On Wednesday, March 15, 2023 at 2:46:26 AM UTC-5, David Newall wrote:
> > > On 14/3/23 11:05, luser droog wrote:
> > > > The variable arguments are interpolated in reverse order (ie. the
> > > > normal top-of-stack down-ward way). I'm not sure how useful it
> > > > actually is. Should it take an array for the variable arguments and
> > > > take them left-to-right?
> > > I love this game! :-)
> > >
> > > Here's a slightly different implementation that uses search instead of
> > > testing each character.
> > Very cool. That ought to run faster and use less memory.
> >
> A little further inspiration. I first wanted to bust it up into smaller re-usable
> functions. This has the disadvantage of creating and discarding more
> intermediate arrays, but oh well. Then I re-tooled it to use search instead
> of going char by char, but now it uses more intermediate data.
>
Got rid of the intermediate arrays at the cost of parsing and constructing
a new procedure body in the new, weird looping proc. This code uses /convert
as defined in my previous message. [I'm posting through GG until I fix my gnus
setup for posting, so I can't quote indented code without losing indentation
or doing extra work to add it back.]
/sprintf4 { % data (format%rem) sprintf4 (format<data>*rem)
[ exch
(%) { % data [ (format) (rem) (%) [
pop snag % [ (format) (rem) (%) data
mark exch % [ (format) (rem) (%) [ data
convert % [ (format) (rem) (%) (<data>*)
} on-matches
join-to-mark
} def
/on-matches { % string seek proc
1 dict begin /proc exch def
({
search not { exit } if
3 1 roll mark % pre post match [
//proc exec % pre post match [ proc*
counttomark % pre post match [ proc* n
dup 2 add -1 roll pop % pre post match proc* n
dup 2 add exch % pre post match proc* n+2 n
roll % pre proc* post match
}) cvx exec end loop
} def
/join-to-mark { % [ <obj1> .. <objN>
counttomark dup 1 add copy % [ <obj1> .. <objN> n <obj1> .. <objN> n
0 exch { % ... <obj1> .. <objn> 0
exch length add
} repeat % [ <obj1> .. <objN> n length
counttomark 1 sub index type /stringtype eq
{string}{array} ifelse % [ <obj1> .. <objN> n dest
exch 0 exch { % [ <obj1> .. <objN> dest pos
counttomark -1 roll % [ <obj2> .. <objN> dest pos <obj1>
3 copy putinterval length add % [ <obj2> .. <objN> dest' pos'
} repeat % [ dest length
pop exch pop
} def