[comp.lang.forth] Data Structures

ForthNet@willett.UUCP (ForthNet articles from GEnie) (02/28/90)

 Date: 02-26-90 (08:06)              Number: 2973 (Echo)
   To: IAN GREEN                     Refer#: NONE
 From: JACK WOEHR                      Read: NO
 Subj: FORTH DATA STRUCTURES         Status: PUBLIC MESSAGE

 >
 >   How about declaring data structures like an array, or a queue. A 
 >stack is automatic but I am unsure how to implement these other 
 >elementary data structures.
 >


        Ian, the CREATE ... DOES> syntax is Forth's way of declaring
 a custom object. Anything created thusly pushes its data address to
 the stack when executed, then performs the associated DOES> code.

        : ARRAY ( #entries ---) \ this "defining" word will create arrays
           CREATE ALLOT \ allot { #entries } bytes
           DOES> ( index --- addr) \ which at runtime self-indexes
           + ;

        20 ARRAY FOO ok
        0 FOO . 1234 ok
        1 FOO . 1235 ok

        ... etc.

        Note there are no limit checks in this construct! However, limit
 checks can be implemented.

        : CHECKARRAY ( #entries ---)
           CREATE DUP , ALLOT
           DOES> ( index --- addr | abort)
           OVER 0< ABORT" Negative array index!"
           2DUP @
           >= ABORT" Index out of range!"
           CELL + + ;

        4 CHECKARRAY FOO ok
        0 FOO . 1234 ok
        1 FOO . 1235 ok
        -1 FOO . Negative array index!
        4 FOO . Index out of range!

        For a more elaborate example, a self-indexing n-dimensional
 array, see DIMARRAY.ARC on most of these fine ForthNet stations.

                =jax=

 NET/Mail : RCFB Golden, CO (303) 278-0364 VESTA & Denver FIG for Forth!
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: 'uunet!willett!dwp' or 'willett!dwp@gateway.sei.cmu.edu'

ForthNet@willett.UUCP (ForthNet articles from GEnie) (03/07/90)

 Date: 03-05-90 (09:14)              Number: 2997 (Echo)
   To: DENNIS RUFFER                 Refer#: 2984
 From: PETE KOZIAR                     Read: NO
 Subj: STACK USAGE                   Status: PUBLIC MESSAGE

 About all I can add to this is that, even though each word needs to put 
 a return address on the return stack, the data manipulation words need 
 to potentially do many accesses on the data stack. 
 ---
  * Via Qwikmail 2.01  The Baltimore Sun 
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: 'uunet!willett!dwp' or 'willett!dwp@gateway.sei.cmu.edu'

ForthNet@willett.UUCP (ForthNet articles from GEnie) (03/18/90)

 Date: 03-13-90 (09:54)              Number: 3035 (Echo)
   To: ALL                           Refer#: NONE
 From: JONAH THOMAS                    Read: (N/A)
 Subj: B-TREES                       Status: PUBLIC MESSAGE

    Some months ago Dave Weinstein put up a message about using TREE
 structures, following a concept by Larry Forsley.  There was a defining
 word, TREE , which recursively made each word it defined to also be a
 defining word which did the same thing TREE did.  Each word got tagged
 with the address of the word which defined it, which created a
 tree-like hierarchy.  Then he defined a set of words which looked at
 the tags to trace out the 'lineage' of any particular word.  It was
 based on an idea by Larry Forsley.  It looked neat, so I saved it.
    When I needed it, I was a bit disappointed.  It's a really nice
 idea, but it doesn't actually do much.  Each word in the tree is a
 defining word.  You use it to define 'branches', the later words in the
 tree.  Each of THEM is ALSO a defining word, which can define new
 defining words.  But none of the words can do anything except define
 new defining words, so you need to fiddle with them to actually use
 them for anything.

    The obvious way to do it is to use a non-recursive defining word,
 which would then be used something like:

 0 subs car
      car subs ford
      car subs chevy
      car subs mercedes
          ford subs escort
          chevy subs nova
                nova subs 1987

    Then CHILD could give its pfa, which contains the pfa of PARENT.
 All nice and neat to use, just an extra word when you define a branch.

 : SUBS CREATE , ;
 : .NAMER BODY> >NAME .NAME ;  ( For Pygmy, 3 - .ID )
 : ANCESTRY BEGIN @ ?DUP WHILE DUP .NAMER REPEAT ;
 ---
  * Via ProDoor 3.1 

 NET/Mail : The MATRIX (5 Nodes/1.2 Gig) Birmingham, AL (205) 323-2016  
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: 'uunet!willett!dwp' or 'willett!dwp@gateway.sei.cmu.edu'

ForthNet@willett.UUCP (ForthNet articles from GEnie) (03/19/90)

 Date: 03-15-90 (04:41)              Number: 3038 (Echo)
   To: ALL                           Refer#: NONE
 From: JONAH THOMAS                    Read: (N/A)
 Subj: B-TREES                       Status: PUBLIC MESSAGE

    This is simpler than the recursive form to put together, but it
 takes more typing to actually make the tree.  What the recursive
 defining words give you is the chance to take all those 'subs' out of
 the tree set-up.  But then you can only use the tree words with
 specialized tree-reading words, in post-fix notation.  I haven't
 actually used it all enough to see whether this is a disadvantage.
    The B-Tree was almost as easy:

 : B-SIDE 2 + ;
 : B-DOWN 4 + ;
 : B-LINK-UP ( here addr | here 0  -- ) 
           DUP IF   B-DOWN DUP @ , !   ELSE  , DROP   THEN ;
 : SUBS ( addr -- ) CREATE HERE SWAP DUP , B-LINK-UP 0 , ;

    Three fields, the 1st looks back, the 2nd looks sideways, and the 3rd
 looks forward.  B-LINK-UP copies the parent's down-address into the
 child's side-address, and the child's address into the parent's
 down-address, so the 1st child defined (the last one in the list) at
 each level has a 0 in its side-address.

 VARIABLE B-LEVEL ( used for indenting while printing )
 : SAME-LEVEL 2 + @ ;
 : DOWN-ONE   4 + @ ;
 : .TREE ( addr -- ) RECURSIVE   CR B-LEVEL @ SPACES DUP .NAMER DUP
     DOWN-ONE ?DUP IF  1 B-LEVEL +!  .TREE   -1 B-LEVEL +!  THEN
     SAME-LEVEL ?DUP   IF .TREE THEN ;

     A non-recursive form of .TREE was more complicated because it had to
 keep track of what it was doing, and know when to quit.  Recursion does
 all that on the return stack automatically.  
     Recursive defining words ought to be really useful, but they don't
 look that useful to me yet.  Maybe with some special state variables, so
 they're part-time recursive defining words.  But it looks really
 complicated.

 ---
  * Via ProDoor 3.1 

 NET/Mail : The MATRIX (5 Nodes/1.2 Gig) Birmingham, AL (205) 323-2016  
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: 'uunet!willett!dwp' or 'willett!dwp@gateway.sei.cmu.edu'

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/01/90)

 Date: 05-29-90 (21:07)              Number: 610 (Echo)
   To: ALL                           Refer#: NONE
 From: MICHAEL HAM                     Read: (N/A)
 Subj: EASTER IDENTIFICATION         Status: PUBLIC MESSAGE

 Does anyone have a nifty algorithm that will give the month and day of
 Easter given the year?  (I can't really believe that such a thing is
 possible given the definition of Easter.)  If not, does anyone have a
 pointer to a table of the Easter dates from, say, 1900 to 2080?  (If and
 when and I get this, I'll upload the table--at 360 bytes at the outside,
 it is probably smaller than the algorithm--and that's allowing a byte
 for month and a byte for day.  And since we know Easter ranges from
 March 22 through April 25, we could do it in one byte:  022 thru 031 for
 the March dates, say, and 101 through 125 for the April dates, with the
 year used as the offset into the table (after subtracting 1900).)

 NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530             
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/01/90)

 Date: 05-29-90 (20:22)              Number: 3289
   To: ALL                           Refer#: NONE
 From: MICHAEL HAM                     Read: HAS REPLIES
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 Easter wanders around the calendar between March 22 and April 25; it is
 (in this part of the work) supposed to be the first Sunday after the
 first full moon after the vernal equinox--or is it the first new moon? 
 At any rate, I have read that the algorithm actually used does not quite
 match the astronomical facts (for the sake of simplicity).  And does
 anyone have the algorithm or know where I can see it?  Alternately (and
 no doubt much simpler) can anyone point me to a table of Easter dates
 for the years 1900 through 2080?
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/01/90)

 Date: 05-30-90 (20:17)              Number: 3291 (Echo)
   To: MICHAEL HAM                   Refer#: 3289
 From: MICHAEL HAM                     Read: NO
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 Well, I have an answer about Easter Sunday:  it falls on the
 first Sunday following the arbitrary Paschal Full Moon, which
 does not necessarily coincide with a real or astronomical full
 moon.  The Paschal Full Moon is calculated by dividing the year
 by 19, and then using the remainder to index into the following
 table:

 0 Apr 14       5 Apr 18       10 Mar 25      15 Mar 30
 1 Apr  3       6 Apr  8       11 Apr 13      16 Apr 17
 2 Apr 23       7 Mar 28       12 Apr  2      17 Apr  7
 3 Apr 11       8 Apr 16       13 Mar 22      18 Mar 27
 4 Mar 31       9 Apr  5       14 Apr 10

 For the year 2000, for example, leaves a remainder of 5 when
 divided by 19.  The table shows that the Paschal Full Moon then
 falls on April 18.  In 2000, April 18 is a Tuesday, so thaM following Sunday (April 23) is Easter Sunday.

 NOTE:  If the Pascal Full Moon falls on a Sunday, Easter is the
 following Sunday.  The earliest Easter can Fall is March 23; the
 latest is April 25.

 Obviously the simplest thing will be to compute the Easter Sunday
 dates and then store them in a table:  if I use a 0 prefix to
 denote March and a 1 prefix to denote April (so that 027 means
 March 27 and 115 means April 15), I can store each date in a
 single byte (with one bit left over for other uses), indexing
 into the table with the year normalized to the beginning of the
 table.

 Ash Wednesday, if you need that, is 40 days before Easter, not
 counting Sundays.  Or 46 days, if you do count Sundays.
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/02/90)

Category 3,  Topic 20
Message 92        Thu May 31, 1990
W.BADEN1 [Wil]               at 21:07 PDT
 
Here is a vanilla algorithm for Easter.

( Easter is the first Sunday strictly after the ) ( Paschal Full Moon.)

: golden# ( year -- n) 19 MOD ( n) 1+ ;

: centuryterm ( year -- n) 
   100 / ( n)  DUP >R    4 /
   R@ 11 + 8 * 25 / +    R> - ;

: paschalfullmoon ( year -- marchDay)
   DUP golden# >R    centuryterm ( n)
   R@ 11 * +   30 MOD    DUP 0= ( n f)
   OVER 1 = ( n f f') R> 11 AND
   OR ( n f) - ( n) 50 - NEGATE ;

: easter ( year -- mo da)
   DUP >R   paschalfullmoon ( n) 3 OVER ( n mar n)
   R> wday - ( n) 7 +   31 /MOD ( d m) 3 + SWAP ;

Given month day year "wday" yields the day of week. (0 is Sunday.) Your system
may already have something for this. The following is for the Gregorian
calendar.

( For convenience the year begins with March 1.)

: yday ( month day anyYear -- dayOfYear year)
   ROT ( day year month) 3 -    DUP 0<
      IF    -1 +under   12 +    THEN
   306 *    5 +    10 /    +under ;

: cday ( month day anyYear -- dayOfCentury century)
   yday ( day year)
   100 /MOD SWAP ( day century year)
   1461 4 */   +under ;

: wday ( month day anyYear -- dayOfWeek)
   cday ( day century) 4 MOD   2*   9 -   - 0 7 UM/MOD DROP ;

Procedamus in Pace.  Wil. (If you don't have it already : +under ROT + SWAP ;)
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/04/90)

 Date: 05-31-90 (21:01)              Number: 3297 (Echo)
   To: MICHAEL HAM                   Refer#: 3291
 From: JERRY SHIFRIN                   Read: 05-31-90 (23:13)
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 MH>Well, I have an answer about Easter Sunday:  it falls on the
 MH>first Sunday following the arbitrary Paschal Full Moon, which

 That must be when the Pascal programmers really go nutzoid!
 Just out of curiousity, why were you interested?  A calendar
 program?
 ---
  ~ EZ 1.29 ~ 
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/04/90)

 Date: 05-31-90 (23:10)              Number: 3298 (Echo)
   To: MICHAEL HAM                   Refer#: 3291
 From: MICHAEL HAM                     Read: 05-31-90 (23:12)
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 In the Paschal Full Moon table above, entry no. 2 is in error:  it
 should be Mar 23 instead of Apr 23.  I am uploading EASTER.ZIP, which
 contains a table of 176 Easter Sunday dates (1901-2076), along with two
 words to extract the date (given the year) and to print the date.  The
 table works fine (used with UR/FORTH), but do NOT use INCLUDE to load
 the file--INCLUDE forces each byte to be at least 32, which zaps all the
 entries for March in ETABLE.  So long as ETABLE is in the main file, it
 should work fine.
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/04/90)

 Date: 05-31-90 (23:13)              Number: 3299 (Echo)
   To: JERRY SHIFRIN                 Refer#: 3297
 From: MICHAEL HAM                     Read: NO
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 I am writing a program to help my wife schedule staff on the ward where
 she works (VA Hospital), and as an aid, I wanted a little pop-up
 calendar.  Showing the Federal holidays was a relative snap, but Easter
 baffled me.  (Easter not observed Federally, but if you're scheduling
 staff it's helpful to know.)
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/04/90)

 Date: 06-01-90 (09:38)              Number: 620 (Echo)
   To: ALL                           Refer#: NONE
 From: MICHAEL HAM                     Read: (N/A)
 Subj: EASTER TABLE                  Status: PUBLIC MESSAGE

 God must give us sleep so that we can see our mistakes while
 unconscious.  I realized after posting EASTER.ZIP that it would be easy
 to make the table INCLUDE-proof by using BL to increment the values for
 March (which might fall under the INCLUDE-imposed minimum of 32).  BL is
 about the right size, won't put March dates above 100, and is a constant
 so takes little room.  EASTER2.ZIP is the INCLUDE-proof table.

 NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530             
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

rvp@cbnewsh.att.com (rob.v.phillips) (06/05/90)

In article <1044.UUL1.3#5129@willett.UUCP>, ForthNet@willett.UUCP (ForthNet articles from GEnie) writes:
>  Does anyone have a nifty algorithm that will give the month and day of
>  Easter given the year?  ...

I recall reading an algorithm, I believe in Apple or Atari Basic
in an issue of "Creative Computing" around 1978-1980 that had this
algorithm... Good Luck finding it! I think it was about 200 lines
of code.

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/06/90)

Category 3,  Topic 20
Message 97        Tue Jun 05, 1990
W.BADEN1 [Wil]               at 20:39 PDT
 
At last Thursday's Fig Bar I promised two algorithms for calculating the date
of Easter.  I gave the first the same night.  I said that the other used
UM/MOD ten times.  This is from T.H.O'Beirne's (That's O'BEIRNE) delightful
PUZZLES AND PARADOXES, Oxford Univ. Press, 1965, chapter titled "Ten Divisions
Lead to Easter."

My son programmed this for my Apple F83X some years ago, but rather than
excavating the code (I don't know where in California it is) or reproducing
O'Beirne's description, here is an executible program in ABC.

HOW TO DIVIDE dividend BY divisor GIVING quotient WITH remainder REMAINDER
   PUT floor(dividend/divisor),dividend mod divisor IN quotient, remainder

HOW TO EASTER x:
   \ Display month and day of Easter Sunday, Gregorian year x.
   DIVIDE x BY 19 GIVING junk WITH a REMAINDER
   DIVIDE x BY 100 GIVING b WITH c REMAINDER
   DIVIDE b BY 4 GIVING d WITH f REMAINDER
   DIVIDE 8*b + 13 BY 25 GIVING g WITH junk REMAINDER
   DIVIDE 19*a + b - d - g + 15 BY 30 GIVING junk WITH h REMAINDER
   DIVIDE a + 11*h BY 319 GIVING mu WITH junk REMAINDER
   DIVIDE c BY 4 GIVING i WITH k REMAINDER
   DIVIDE 2*f + 2*i - k - h + mu + 32 BY 7 GIVING junk WITH lambda REMAINDER
   DIVIDE h - mu + lambda + 90 BY 25 GIVING n WITH junk REMAINDER
   DIVIDE h - mu + lambda + n + 19 BY 32 GIVING junk WITH p REMAINDER
   WRITE {[3]: "March"; [4]: "April"}[n], p

This seems wordy, but after you define a new keyword the system prompts you
with suggestions.  E.g.,

When you start a line with "d", ABC echoes "D?ELETE ?" on top of your typing.
If you continue with "i" it suggests "DI?VIDE ? BY ? GIVING ? WITH ?
REMAINDER".  You can write over the suggestion or use tab to copy up to the
next hole, given by "?".  Notice that you do not have to shift case.

Here are some "how-to's" for stack manipulation.

HOW TO EMPTY stack
   \ Also used to make stack.
   PUT {} IN stack

HOW TO PUSH x ONTO stack
   PUT x IN stack[#stack+1]

HOW TO RETURN top stack
   RETURN stack[#stack]

HOW TO SWAP stack
   PUT stack[#stack], stack[#stack-1] IN stack[#stack-1], stack[#stack]

HOW TO DROP stack
   DELETE stack[#stack]

HOW TO DUP stack
   PUSH top stack ONTO stack

HOW TO OVER stack
   PUSH 1 th'on stack ONTO stack

HOW TO RETURN n th'on stack
   RETURN stack[#stack - n]   

Here is the clearest expression of The Sieve I've seen.

HOW TO SIEVE n
   \ Sieve of Eratosthenes.  (Not a benchmark.)
   SHARE primes
   PUT {2..n} IN primes
   PUT 2 IN prime
   PUT floor root n IN limit
   WHILE prime <= limit:
      PUT prime IN i
      WHILE i < max primes:
         PUT i + prime IN i
         IF i in primes:
            REMOVE i FROM primes
      PUT prime min primes IN prime
   WRITE "There are `#primes` primes <= `n`."

"SHARE primes" makes primes available globally.

Text files are treated as named tables with line number as the key and text as
the value of the key, so no I/O instructions are needed to manage them.  There
is a built-in editor for all named data: numbers, strings, compounds, lists,
and tables.

Procedamus in pace.  Wil.
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/08/90)

 Date: 06-01-90 (01:21)              Number: 3323 (Echo)
   To: MICHAEL HAM                   Refer#: 3291
 From: KENNETH O'HESKIN                Read: NO
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 MH>Well, I have an answer about Easter Sunday:  it falls on the
 MH>first Sunday following the arbitrary Paschal Full Moon, which
 MH>does not necessarily coincide with a real or astronomical full

         Hmmm. Actually the calculation of Easter was a point of
         bitter dogma and contention in the early Christian Church
         (since nobody has or had a clue as to the historic birth/death
         dates of Christ). Christmas was a straight appropriation of
         of the pagan Winter Solstice (get all those unruly Goths
         on side). The Celtic Church used a different algorithm for
         calculating Easter which annoyed the Roman Church to no end,
         and their rivalry (rather nasty at times) lasted a century.
         Accuracy of calculation had nothing to do with it; it was
         pure politics over who was going to run the store.

         Maybe this thread should be reposted in the ANSI Conference
         for the sober reflection and spiritual edification of the
         Technical Committee ... :-)
 ---
  ~ EZ 1.26 ~ You never leave the bus -- Ken Keasy

 NET/Mail : British Columbia Forth Board - Burnaby BC - (604)434-5886   
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/08/90)

 Date: 05-31-90 (18:42)              Number: 628 (Echo)
   To: MICHAEL HAM                   Refer#: 610
 From: JOHN SOMERVILLE                 Read: NO
 Subj: EASTER IDENTIFICATION         Status: PUBLIC MESSAGE

 I remember reading somewhere that Greenwich uses the Testament to 
 determine the date. No algorithm. As a point of interest, one of the 
 Easters in the last tens years was observed one the wrong Sunday. 
 .
 Strange, but true. 
 regards j

 NET/Mail : British Columbia Forth Board - Burnaby BC - (604)434-5886   
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/08/90)

 Date: 06-06-90 (10:48)              Number: 3324 (Echo)
   To: ALL                           Refer#: NONE
 From: CHARLIE HITSELBERGER            Read: (N/A)
 Subj: PRIME NUMBERS                 Status: PUBLIC MESSAGE

 I was just sort of messing around the other day, trying to write a
 primes generator in Forth83.  Here's what I came up with:

 2VARIABLE NUMER  3. NUMER 2!
 VARIABLE DENOM
 : PRIMES   ( -- ) CR
     BEGIN   3 DENOM !  FALSE
         BEGIN
             DROP  NUMER 2@  DENOM @
             UM/MOD DROP  DUP
             IF
                 DENOM @ DUP M*
                 NUMER 2@  D>
                 2 DENOM +!
             ELSE
                 TRUE
             THEN
         UNTIL
         IF
             NUMER 2@  20 D.R
         THEN
         NUMER 2@  2 M+  NUMER 2!
         ?TERMINAL
     UNTIL
 ;

 here's the BASIC equivalent:
 10 N=3
 20 D=3
 30 IF N/D>INT(N/D) THEN 50
 40 N=N+2:GOTO 20
 50 IF D*D<N THEN D=D+2:GOTO 30
 60 PRINT N,:GOTO 40

 Is my method a pretty "elegant" approach?  What does the standards
 committee think that "1000000. 3 UM/MOD" is supposed to leave on the
 stack?  I'd leave a "1 65535" myself (the modulo and an overflow flag). 
 Of course, my implementation doesn't do that.  It leaves invalid results
 (the remainder is bigger than the divisor!)  Also, what is a good way to
 generate primes in Forth83?  I wrote this as a benchmark, and sort of as
 a way to get my feet wet again.  Any comments would be appreciated.

 Charlie Hitselberger
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/10/90)

 Date: 06-06-90 (07:31)              Number: 3329 (Echo)
   To: KENNETH O'HESKIN              Refer#: 3323
 From: MICHAEL HAM                     Read: NO
 Subj: EASTER LOCATION               Status: PUBLIC MESSAGE

 There is one group that is strongly advocating that Easter be made the
 second Sunday of April, which cuts the Gordian knot of the various
 algorithms, which can have the Eastern Church celebrating Easter one,
 two, three, four, or even five weeks after the Western Church.  My
 search was simply for an algorithm that would give the Easter Sunday
 date for the US, as part of a staff scheduling program I am writing.

 NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530             
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/11/90)

Category 3,  Topic 20
Message 104       Sat Jun 09, 1990
W.BADEN1 [Wil]               at 14:26 PDT
 
Oops.

Examining last week's "paschalfullmoon" it is apparent that something is wrong
with the next-to-last line: the code is incompatible with the stack comments.

Restoring the lost ">" it should have been:

: paschalfullmoon ( year -- marchDay)
   DUP golden# >R    centuryterm ( n)
   R@ 11 * +   30 MOD    DUP 0= ( n f)
   OVER 1 = ( n f f') R> 11 > AND
   OR ( n f) - ( n) 50 - NEGATE ;

"easter" was also sick -- it yielded April 0 instead of March 31.

: easter ( year -- mo da)
   DUP >R   paschalfullmoon ( n) 3 OVER ( n mar n)
   R> wday - ( palmSunday) 7 +   3 SWAP ( mo da)
   DUP 31 > IF   1 +under   31 -   THEN ; 

I'm very sorry and I won't do it anymore.
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/11/90)

 Date: 06-09-90 (14:07)              Number: 3337 (Echo)
   To: W.BADEN1 [WIL]                Refer#: 3305
 From: MICHAEL HAM                     Read: NO
 Subj: EASTER AGAIN                  Status: PUBLIC MESSAGE

 Wil, I took a slightly different approach, though I am intrigued by the
 way you did it.  Here's mine:

 My approach to the Easter problem was to construct a table of the
 values--I believed that this approach offered advantages in speed
 and probably in memory room as well.  I was wrong about the
 memory:  a useful set of words using the computational approach
 shown below is 142 bytes versus 224 for the table apprach, but
 the speed advantage is all to the table:  4.12 seconds for 10,000
 Easter computations versus .49 seconds for 10,000 Easter lookups,
 with the result biased by the difference in speed for 3DROP
 versus 2DROP--not enough to account for the difference.

 The table of dates is given below, along with two example words:
 one to fetch the Easter date and one to display it.  The table is
 normalized to 1901 (i.e., entry number 0 (lower-case k, as you
 see) is the entry for 1901), with the Easter Sunday date for
 each year (through 2076) stored in a single byte.

 Initially I tried using the date of the month with 0 prefixed for
 dates in March and 1 for dates in April  (for example, 028 for 28
 March; 120 for 20 April).  However, UR/FORTH's INCLUDE (used to
 load files) forces bytes to a minimum value of 32, which messed
 up the March dates.  I therefore added BL to each March date to
 make it immune to alteration by INCLUDE.

 The UR/FORTH word ," stores into memory the (uncounted) string
 that follows, up to but not including the delimiting ".  In the
 screen dump below, the lines break at the end of each screen
 line, but the table is one contiguous string of 176 (non-blank)
 characters.

 CREATE ETABLE  \ INCLUDE-proof table of Easter Sundays 1901-2076

 ," k>pg{s?wo;tk7ph{l?xh;texphul?xi;teyp<um8qi}meyj<um9qivneyj=uf
 zr=vn:rj=ofzr>vn:sjwogzk>wg:s?wogtk>ph{s?xo;tl7ph|l?xi;teyphum?x
 i<teyq<um9qi}neyj=um9rivnfyj=vfzr>vn:sj=ogzr>wn:skw"

 : @EASTER ( yr - da mon | flag )  DUP  1901 <  OVER  2076 >  OR  
      IF ." The year " U. ." is out of range for this table. "  0
      ELSE 1901 - ETABLE + C@ DUP 100 >
         IF 100 -  4 ( Apr )  ELSE BL -  3 ( Mar ) THEN THEN ;

 : .EASTER ( yr - ) DUP @EASTER ?DUP
      IF 4 = IF ." April "  ELSE ." March " THEN  0 .R ." , " .   
      ELSE  DROP ( yr ) THEN ;

 The table was constructed using the following words, which are
 merely scaffolding to be discarded once the tiny edifice of the
 table is complete.

   3 CONSTANT MAR         \ for readability
   4 CONSTANT APR

 : |  ( n1 n2 - )  , , ;  \ for readability 

  CREATE 'PFM     14 APR |  3 APR | 23 MAR | 11 APR | 31 MAR |
  ( Paschal   )   18 APR |  8 APR | 28 MAR | 16 APR |  5 APR |
  ( Full Moon )   25 MAR | 13 APR |  2 APR | 22 MAR | 10 APR |
  ( table     )   30 MAR | 17 APR |  7 APR | 27 MAR |

 : CK-PFM  PRINTER 19 0 DO I 4 * 'PFM + 2@  3 =
       IF ." March" ELSE ." April" THEN 3 .R CR LOOP
       12 EMIT CONSOLE ;

 It is very handy for any table to have a way to dump the entries
 to hard copy in readable form to simplify proofreading.

 : UMOD ( u1 u2 - urem )  0 SWAP UM/MOD DROP ;
    \ 0 SWAP converts the single u1 to a double, for UM/MOD

 : PFM ( yr - day mon ) \ yr in, day/mon of Paschal Full Moon out
       19 MOD 4 * 'PFM + 2@ ;

 : EASTER ( yr - day mon yr ) \ given year, gives date of Easter
     DUP PFM ROT >CENT  DUP 7 UMOD  7 SWAP - + CENT> ;

 The word >CENT in my calendar routine converts   day mon yr  to a
 century date, an offset from 1/1/1900 (accurate from 3/1/1900--
 1900 is not a leap year, but the simple algorithm I use is
 ignorant of the subtleties of the Gregorian scheme).  CENT>
 converts a century date to day month year.  (George Shaw pointed
 out to me that you can check a date's validity by converting it
 to century format and back:  the date is valid if and only if the
 initial and final values match.)  

 Using 7 UMOD on a century date gives the day of the week, by
 happy chance Sunday being 0.  By subtracting the weekday value
 (which thus happens to be the offset from Sunday) from 7 and
 adding it to the date, we get the next Sunday.

   CREATE EASTERS 176 ALLOT

 : FILL-TABLE  176 0 DO 1901 I + EASTER  DROP 4 =
     IF 100 +  ELSE BL + THEN EASTERS I + C! LOOP ;

 Once the table was created, it was easy to store it into the
 appropriate block with CMOVE.
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/14/90)

 Date: 06-11-90 (06:58)              Number: 639 (Echo)
   To: JOHN SOMERVILLE               Refer#: 638
 From: MICHAEL HAM                     Read: NO
 Subj: PROJECT MANAGEMENT            Status: PUBLIC MESSAGE

 I would think that the best way to load a set of small files is a series
 of INCLUDE statements in the main file:  INCLUDE ABC.EFG will load the
 file ABC.EFG.  Note that the extension must be included in the filename.
  Note also that INCLUDE will force bytes to a minimum value of 32 (ASCII
 blank), so if you have data tables, for example, with bytes lower in
 value, beware.

 NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530             
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/14/90)

 Date: 06-11-90 (08:56)              Number: 640 (Echo)
   To: JOHN SOMERVILLE               Refer#: 638
 From: RAY DUNCAN                      Read: NO
 Subj: PROJECT MANAGEMENT            Status: PUBLIC MESSAGE

 The best solution is to have one "master" file that just contains a
 bunch of INCLUDE statements for other files.  We use this technique
 quite a bit here at LMI.

 NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530             
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/16/90)

 Date: 06-13-90 (20:37)              Number: 644 (Echo)
   To: MICHAEL HAM                   Refer#: 639
 From: JOHN SOMERVILLE                 Read: NO
 Subj: PROJECT MANAGEMENT            Status: PUBLIC MESSAGE

 Thanks that will probably do. Most tables that I use I could copy to the
 main file. 
 .
 I have been racking my brains trying to recall where I read about the 
 Easter holiday reckoning at Greenwich. I was astonished when I read it, 
 but assumed the information was ( about the Testament was correct, maybe
 it is.) Paschal comes from what. 

 By the way I have enjoyed your articles a lot.

 regards j

 NET/Mail : British Columbia Forth Board - Burnaby BC - (604)434-5886   
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.UUCP (ForthNet articles from GEnie) (06/16/90)

 Date: 06-13-90 (20:42)              Number: 645 (Echo)
   To: RAY DUNCAN                    Refer#: 640
 From: JOHN SOMERVILLE                 Read: NO
 Subj: PROJECT MANAGEMENT            Status: PUBLIC MESSAGE

 Thanks Michael Ham suggested the same thing. 
 .
 I received 1.1 yesterday. I have started to read the manual, and 
 understand why you recommend getting it. Note page I - 24. 

 I tried the example on J - 541 and it didn't link is that because I am 
 using LINK 3.05?. Also Map0.obj is non-existent; I presume MAP.OBJ is 
 its replacement.

 regards j

 NET/Mail : British Columbia Forth Board - Burnaby BC - (604)434-5886   
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or willett!dwp@hobbes.cert.sei.cmu.edu

ForthNet@willett.pgh.pa.us (ForthNet articles from GEnie) (09/12/90)

 Date: 09-08-90 (10:53)              Number: 484 (Echo)
   To: ALL                           Refer#: NONE
 From: DARRYL BIECH                    Read: (N/A)
 Subj: CONTROL STRUCTURES            Status: PUBLIC MESSAGE

 Being new to FORTH, but experienced in several other languages, a couple
 of things puzzle me about the FORTH strings and control structures
 proposals/debates:
 >
 1.) What is wrong with using the three conventional looping constructs 
     DO FOR, DO WHILE, and DO UNTIL, and combining them with IF THEN
     (ELSE) to create the more complicated control structures that I
     noticed at the X3J14 Vancouver Conference. Using iterative and
     "decide before the body of the loop" and "decide after the body of
     the loop" constructs are enough for any language.
     (I am referring to technical comment C89-279.1)
  2.) Why not have counted strings that are optionally null-terminated?

 NET/Mail : British Columbia Forth Board - Burnaby BC - (604)434-5886   
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or dwp@willett.pgh.pa.us

ForthNet@willett.pgh.pa.us (ForthNet articles from GEnie) (09/13/90)

Category 3,  Topic 20
Message 115       Wed Sep 12, 1990
D.RUFFER [Dennis]            at 00:29 EDT
 
Re: DARRYL BIECH

 > 1.) What is wrong with using the three conventional looping
 > constructs DO FOR, DO WHILE, and DO UNTIL, and combining them with
 > IF THEN (ELSE) to create the more complicated control structures

I don't rmember the comment you refer to, but what we now have, IMHO is very
close you what you are suggesting.  Forth uses different commands, so here are
the equivalents:

        Traditional        Forth
        DO FOR          -> DO LOOP
        DO WHILE        -> BEGIN WHILE REPEAT
        DO UNTIL        -> BEGIN UNTIL
        IF THEN (ELSE)  -> IF (ELSE) THEN

There seems to be a lot of confusion about how these individual operators can
be combined, and my understanding is that the current BASIS does not even
reflect what it should in this regard (i.e. what has already been passed by
the TC).  Perhaps only experimentation with a compliant system will tell the
real answer, but I have been assured that the following work:

        BEGIN WHILE UNTIL THEN

Thus creating a loop that has two exit points.  I made a proposal very early
in the proccess for a similar construction.  It was rejected in favor of the
more powerful generalizations that we have now.  I think that is what you are
looking for also.

 > 2.) Why not have counted strings that are optionally null-
 > terminated?

Tradition?  It would be a counted string if it was null-terminated. Why not
terminate strings with a $?  What about a user selectable character?  Where
would it all end?  :-)

DaR
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or dwp@willett.pgh.pa.us

cwpjr@cbnewse.att.com (clyde.w.jr.phillips) (09/13/90)

In article <1716.UUL1.3#5129@willett.pgh.pa.us>, ForthNet@willett.pgh.pa.us (ForthNet articles from GEnie) writes:
> 
>   2.) Why not have counted strings that are optionally null-terminated?

I agree we should have it but ynot is because it's bowing to C peer pressure.
I think having to "scan" a string to determine it's length is bad ( its Bahhd ).
We have a little overhead for sureties sake.

However if we make a null terminator manditory AND "counted"
a little more overhead ( stop on nulls ) might add a "good" flavor
to our strings ( I would have said spaghetti but you never know what
type of person is reading this! )
I'll get around to assessing this sooner or later. Clyde

a684@mindlink.UUCP (Nick Janow) (09/14/90)

In article <1716.UUL1.3#5129@willett.pgh.pa.us>, ForthNet@willett.pgh.pa.us
(ForthNet articles from GEnie) writes:

>    2.) Why not have counted strings that are optionally null-terminated?

I wouldn't put them in ANS FORTH, since null-termination of a counted string
would be redundant information.  It's something that isn't used all that often.

The nice thing about FORTH is that if your application needs null-terminated
counted strings, uncounted packed strings or uncounted strings terminated with
Japanese Haikum (who knows what someone might need?), you have the tools to add
words to handle them.

Go FORTH and write your null-terminated counted string package!  :-)

wmb@MITCH.ENG.SUN.COM (09/14/90)

>   2.) Why not have counted strings that are optionally null-terminated?

In my system, counted strings are *always* null-terminated.  The null
is not included in the count.  This makes it easy to pass strings to C.

HOWEVER, I do not recommend this!  I recommend that counted strings be
*eliminated entirely*.  Forth should only have one visible string
representation (currently it has 4), and that representation should be
"adr len" on the stack.  The "adr len" representation is by far the
most flexible, and does not suffer from the fundamental problems of
counted strings or null-terminated strings.

Those problems are:

1) Counted strings have an inherent length limitation.
2) You can't just point to some memory and say it's a counted string or
   a null-terminated string; instead you have to copy it somewhere so you
   can insert either the count byte or the null byte.
3) Null-terminated strings cannot represent byte arrays containing the
   null byte.
4) Extraction of substrings of counted strings and null-terminated strings
   requires copying.

The only down side of "adr len" strings is the stack manipulations required,
and that turns out not to be too bad once you get used to using "2dup"
and "2swap".

Over time, I am weeding out all externally-visible uses of counted strings
in my system.

Mitch Bradley, wmb@Eng.Sun.COM

ForthNet@willett.pgh.pa.us (ForthNet articles from GEnie) (09/15/90)

 Date: 09-13-90 (10:57)              Number: 3770 (Echo)
   To: CHARLIE HITSELBERGER          Refer#: 3746
 From: GENE LEFAVE                     Read: NO
 Subj: IS THIS COMMONLY DONE?        Status: PUBLIC MESSAGE

 CH>what I wound up with.  My question is, is the " 0 BEGIN DROP " a
 CH>commonly used thing for loops that leave a value on the stack upon exit?

 I woundn't know if it's commonly done, but I use it all the time. 8-)

 ---
  ~ EZ-Reader 1.13 ~ 
-----
This message came from GEnie via willett through a semi-automated process.
Report problems to: uunet!willett!dwp or dwp@willett.pgh.pa.us

andrew@idacom.uucp (Andrew Scott) (09/20/90)

Mitch Bradley writes:
> Forth should only have one visible string
> representation (currently it has 4), and that representation should be
> "adr len" on the stack.

How do I get "adr len" on the stack?  The operation is defined for strings
defined with " , but what about strings in memory?  I can only get the
address of a string buffer defined with CREATE, for example.  I must use
COUNT, or perhaps STRLEN for a null terminated string, to get the length.
I do not want to have to declare a seperate VARIABLE for the length of
each string buffer I use.
-- 
Andrew Scott	| mail:		andrew@idacom.uucp
		| - or -	..!uunet!ubc-cs!alberta!idacom!andrew

wmb@MITCH.ENG.SUN.COM (09/22/90)

> How do I get "adr len" on the stack?  The operation is defined for strings
> defined with " , but what about strings in memory?  I can only get the
> address of a string buffer defined with CREATE, for example.  I must use
> COUNT, or perhaps STRLEN for a null terminated string, to get the length.
> I do not want to have to declare a seperate VARIABLE for the length of
> each string buffer I use.

: string:  \ name  ( max-size -- )
   create  0 ,  allot
   does>           ( pfa -- adr len )
   dup cell+  swap @
;

The operators for manipulating strings should be as general as possible,
and independent of how those strings happen to be encoded when stored
in memory.  One might reasonably choose different memory encodings for
different applications, but the stack representation should always be
the same, so that we could build upon a single set of string operators,
rather than having the piecemeal set of operators, split among several
different string representations, that we have now.

Mitch Bradley, wmb@Eng.Sun.COM

shri@ncst.ernet.in (H.Shrikumar) (10/02/90)

In article <9009220053.AA13718@ucbvax.Berkeley.EDU>
 wmb%MITCH.ENG.SUN.COM@SCFVM.GSFC.NASA.GOV replies to ...

>> How do I get "adr len" on the stack?  The operation is defined for strings
>> defined with " , but what about strings in memory?  I can only get the
>
>The operators for manipulating strings should be as general as possible,
>and independent of how those strings happen to be encoded when stored
>in memory.  

   Yup. Also could overload the same ideogram for same action on
strings of differnt types, the correct word being selected by the 
value of a variable called TYPE, (much as numbers are interpretted
according to current value of BASE). (* I saw a feature with similar
intensions first in Mikael Patels xforth.)

   Also, another thing I am trying out in myForth is that all operators
which take a pointer, should return a pointer.

   The idea is  ... say a word that takes a string and replaces "$1" by
"gus" ("fun$1prat" becomes "fungusprat") would take a pointer to the
string, do its job and return a pointer to the new string.

   The retuned pointer may or may not be the same, the program must not
make assumptions about it (sorry hackers :-).

   This is not too difficult to implement, only a little inefficient,
and gives a clean semantics. (IMHO, worth it.)

   For eg. the string could be in ROM, and when somebody tried to
modify it, the word could (if so designed) copy it into RAM
"transparently", change it and return a new pointer. This could also
become the basis for several other features (memory de-fragmentation
etc.)

-- shrikumar ( shri@ncst.in )

dwp@willett.pgh.pa.us (Doug Philips) (10/04/90)

In <978@shakti.ncst.ernet.in>, shri@ncst.ernet.in (H.Shrikumar) writes:
>    Also, another thing I am trying out in myForth is that all operators
> which take a pointer, should return a pointer.
> 
>    The idea is  ... say a word that takes a string and replaces "$1" by
> "gus" ("fun$1prat" becomes "fungusprat") would take a pointer to the
> string, do its job and return a pointer to the new string.
> 
>    The retuned pointer may or may not be the same, the program must not
> make assumptions about it (sorry hackers :-).
> 
>    This is not too difficult to implement, only a little inefficient,
> and gives a clean semantics. (IMHO, worth it.)

The only objection I see to that is that it makes data structures that
share data by pointer a pain, because anytime something happens to an
object, there can be arbitrary many pointers that need to be updated.
For that reason, and others, most systems without Virtual Memory (where
an address can be "mapped" to any other arbitrary address at will and
at run-time) go to another level of indirection, often called 'handles'.
I can see how what you are proposing could have handles nicely layered on
top of it.

-Doug
---
Preferred:  dwp@willett.pgh.pa.us	Ok:  {pitt,sei,uunet}!willett!dwp