+0 UN                                   ! No. of decimal places to print !
+0 UW                                   ! Maximum width per line !

0,128ET                                 ! Abort on error !

EO - 200 "L
    @^A/Macro requires TECO version 200+/ 13^T 10^T ^C
'

!!  pi.tec - TECO-64 macro to print pi
!!
!!  The following was based on "A Spigot Algorithm for the Digits of Pi", by
!!  Stanley Rabinowitz and Stan Wagon, published in The American Mathematical
!!  Monthly, 102(1995)195-203, and is a revised and improved version of an
!!  earlier TECO macro whose output was only valid to about 360 digits. This
!!  version more closely follows the algorithm, as well as the sample Pascal
!!  code included in the cited article, but no attempt is made herein to
!!  explain it in detail, other than to comment that it treats lines in the
!!  edit buffer as elements of an array that is used to calculate the digits,
!!  with the convention that the array is inverted, such that the first
!!  element is the last line of the buffer.
!!

QN "E
    10 UN                               !! If no value, use 10 digits
|
    QN-1 "L
        :@^A/Number of decimal places must be greater than 0/
        ^C
    '
'

:%N                                     !! Add 1 for leading 0 we won't print

@^UD/^^. ^T/                            !! Print decimal point
@^UP/QP :MN :MD Q9 < 9 :MN >/           !! Print predigit and any nines

@^UN/ := :%D /                          !! Output digit and count it

QW "G                                   !! If width specified,
    :@^UN{ (QD // QW) "E -1^T ' }       !!  then start new line if needed
'

HK                                      !! Clear the edit buffer
0 UP                                    !! "predigit" variable
0 U9                                    !! "nines" variable

(QN * 10 / 3) U0                        !! No. of edit buffer lines
0 UD                                    !! Count of printed digits

Q0 UI                                   !! Array index

QI < 2 \ 10I >                          !! Start with 2 on each line

QN
<
    0 J
    0 UQ                                !! "q" variable
    Q0 UI                               !! Array index

    QI
    <
        \ * 10 + (QQ * QI) UA           !! Get next element
        (QI * 2 - 1) UJ
        (QA / QJ) UQ
        0L K (QA // QJ) \ 10I           !! Replace current element
        -1 :%I
    >

    ZJ -L \ UA                          !! Read first element
    0L K (QQ // 10) \ 10I               !!  and replace it
    (QQ / 10) UQ

    !! Done calculating next digit. Now see if we should print it.

    (QQ - 9) "E                         !! Is it a 9?
        :%9                             !! Yes, just count digit
    |
        (QQ - 10) "E                    !! No. Is it a 10?
            (QP + 1) :MN                !! Yes, print predigit + 1
            Q9 < 0 :MN >                !! Translate 9s to 0s
            0 UP
        |
            QD "N
                :MP                     !! Print pre-digit and any nines
                0,0XD                   !! Print only one decimal point
            |
                :%D                     !! Count initial 0 but don't print it
            '
            QQ UP
        '
        0 U9                            !! Reset counter for 9s
    '
>

:MP                                     !! Print final digit
-1^T                                    !! Output newline
HK                                      !! Clear the edit buffer
^[^[
