Skip to main content
1 of 7
luser droog
  • 4.9k
  • 2
  • 36
  • 61

Postscript 264

Here's my attempt to do it differently. Rather than the macro-expansion that I usually use, this one checks the size of the execution stack to bound the recursion. If the bound is exceeded, it stops recursively examining the procedure and tries to interpret turtle commands (and discards pop pop otherwise). An advantage of this method is that it does not require enormous amounts of memory. A disadvantage is the recursion control is rather clumsy, as the stack size grows by more than just 1 from one recursion level to the next.

/T[/F{R 0 rlineto}/+{A rotate}/-{A neg rotate}>>def[/a
countexecstack/z{countexecstack a b add lt}/t{T exch 2
copy known{get exec}{pop pop}ifelse}/s{{load}stopped{t}{dup
type/arraytype eq{{z{s}{t}ifelse}forall}{exec}ifelse}ifelse}>>begin
300 400 moveto/I s stroke

It requires the L-system to be pre-defined in a dictionary on the dictstack (prepended to the source), with the initial symbol as I.

Ungolfed and commented with Dragon Curve.

[ %The Dragon Curve
/X{X + Y F}  % productions
/Y{F X - Y}  %
/I{F X}      % initial production
/A 90    % angle
/R 2     % radius
/b 50    % recursion bound
>>begin

/T[ %The Turtle
/F{R 0 rlineto}
/+{A rotate}
/-{A neg rotate}
>>def

[ %The Engine
/a countexecstack  % base execstack size
/z{countexecstack a b add lt }  % execstack size within bounds
/t{T exch 2 copy known{get exec}{pop pop}ifelse}  % try to interpret as turtle command
/s{
    {              % try
        load       % lookup
    } stopped {    % failed to lookup
        t          % try turtle
    }{             % succeeded in lookup
        dup type/arraytype eq{  % if it's an array (ie. a procedure)
            {                   % iterate through it
                z{              % within bounds
                    s           % recursively expand (or descend)
                }{              % exceeded bounds
                    t           % try turtle
                }ifelse
            }forall
        }{                      % not an array
            exec                % simply execute it
        }ifelse
    }ifelse
}
>>begin
300 400 moveto
/I s stroke

dragon curve

luser droog
  • 4.9k
  • 2
  • 36
  • 61