[comp.lang.forth] Advanced Beginners

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

 Date: 02-15-90 (08:38)              Number: 2907 (Echo)
   To: ALL                           Refer#: NONE
 From: DAVID ALBERT                    Read: (N/A)
 Subj: FORTH MODULARITY              Status: PUBLIC MESSAGE

 Hi everyone,
    I am a Modula-2 programmer who recently got into TIL languages.  The
 reason for this was that I had to build a custom 80188 computer for a
 handicapped person and I needed a quick way to get it up and running
 interactively, so I read up on TILs and then implemented one.  My TIL
 has been refined several times and now works rather well.
    I do however have several questions:  First, I have seen that several
 implementations of Forth use a small "inner interpreter loop" using
 DS:SI for example as the instructioni pointer.  I chose just to use CALL
 and RET as the entry and exit to my words.  Therfore, CS:IP is my
 instruction pointer and word pointer.  Here's the question:  Why do
 people use the separate inner interpreter loop?  It seems that the call
 and return are much more flexible and that I can more easily manipulate
 return addresses since they are just on the stack.  I use BP for my
 parameter stack pointer.
    Question number 2:  Since I have come from a Modula-2 background,
 reusable, compiled libraries are very important (to me anyway) in the
 course of developing good applications.  Due to the interpretive nature
 of TILs, I seem to be having some trouble implementing libraries.  I
 would like to allow several libraries (vocabularies) which can be
 manipulated independently and linked into my final application.  I have
 read some of the solutions on late binding, but none I've seen have been
 satisfactory.  Does anyone have any ideas, hints, etc.  Do you know how
 anyone else does it?  Any advice would be appreciated.
    Well, thanks for taking the time to read all of this and I look
 forward to your replies! See ya :-)
-----
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) (02/19/90)

Category 2,  Topic 8
Message 33        Sun Feb 18, 1990
L.ZETTEL                     at 17:31 EST
 
  To David Albert (GEnie msg 32).
       Baldly put, the advice of many Forthers on the subject of implementing
  compiled libraries would be: don't bother.  Allow me to explain.
       A good Forth compiler is as fast or faster than the linker in many
  conventional langauages.  Good Forth code is inherently modular.  If you
  can rapidly create the final product direct from source, why
  bother with compiled libraries?  If you deal with blocks (as I prefer)
  or many short files (as Mitch Bradley prefers), then using load screens
  or some equivalent lets you mix, match, and select to your heart's
  content.
       There are also some collateral advantages.  Always going from source
  solves one aspect of the "version problem": there is no doubt that the
  stuff executing matches the source.  You are also spared the temptation
  to fatten up the modules by throwing in something that you don't need
  now but might be handy some day - when some day arrives (usually much
  less often than thought) the additional stuff can be added.
       My personal preferred Forth programming style is to start with the
  minimum kernal and compile everything else up to the spot I am working
  on when I take up the problem again.  After that, at the first hint that
  something has been corrupted (because I maybe miscalculated an address,
  for instance) I trash the executable and rebuild it.  Debugging is much
  more effective because I always know where I'm at.
       This style also encourages review and revision of the lower level
  stuff as you gain more insight into what the application should really
  look like, so the final product tends to be really tight and well
  integrated.  Try it for a while!
                                -LenZ-
-----
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) (02/20/90)

Category 2,  Topic 8
Message 34        Sun Feb 18, 1990
F.SERGEANT [Frank]           at 20:39 CST
 
 To: David Albert  Re: inner interpreter (next) vs CALL/RET on 8088/8086

 The reasons some people use LODS, AX JMP, rather than CALL/RET are 
   1. the former probably runs faster
   2. the former probably takes less space.

 I say 'probably' in #1 because I've given up thinking I know how long  an
instruction takes due to variables such as the mix of instructions  affecting
whether the queue stays filled and the actual processor (eg  V20 vs 8088), and
in #1 & #2 because of a number of other variabls.  My  Intel book for the 8088
says 

      LODSW   1 byte  16 cycles       memptr16 CALL  3 bytes  29 cycles
      AX JMP  2 bytes 11 cycles                 RET  1 byte   20 cycles

 so, at first glance it seems that letting CS:IP thread thru the  address list
takes 49 cycles to DS:SI's 27 cycles.  There are a number  of complicating
factors if you use CALL/RET.  

 1st, addressing the data stack is more difficult as you need to do at  least
one pair of SP BP XCHG instructions in order to be able to use  the PUSH & POP
instructions to address the data stack.  

 2nd, addressing the return stack becomes easier since you no longer  need to
do the SP BP XCHG for it. 

 3rd, you can eliminate docol (nest) saving both time & space.  

 4th, you have a smaller, faster exit (unnest), using a 1 byte RET  rather
than a 2 byte address for a jump to a central routine.

 5th, each entry in the address list takes 3 bytes rather than 2 bytes.

 6th, colon definitions can (often) end w/ a 3 byte JMP to the final  word in
the list rather than using a 3 byte CALL followed by a 1 byte  RET.

 Where is our breakeven point?  I certainly don't know.  I would  welcome a
detailed analysis from someone(s).  Let's look just at space  in a colon
definition:  Using CALL/RET we save a 3 byte jump to nest and one byte for
unnest.  Each word in the colon definition would take  3 bytes instead of two.
The space breakeven point seems to be 4 words.   Unfortunately perhaps, the
code I write averages more than 4 words per  colon definition, so space-wise I
seem to be better off using direct  threading rather than CALL/RET.

 And, there are even more factors to consider such as in-line code and 
optimizations vs the ease of decompiling (SEE).

 I hope to do some experimenting when I get the time.

 Obviously the best solution is to cease using Intel processors.

  -- Frank
-----
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) (02/23/90)

 Date: 02-21-90 (15:06)              Number: 2939 (Echo)
   To: ALL                           Refer#: NONE
 From: IAN GREEN                       Read: HAS REPLIES
 Subj: FORTH                         Status: PUBLIC MESSAGE

    Can someone document some 'Forth' instructions for me. I want to know
 the words to STORE the top of the stack to a specified memory location 
 and a word to PUSH on the stack, the data contained in a specified 
 memory location. What I want is the equavalent to load and store 
 instructions I suppose.

 Ian Green

 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@gateway.sei.cmu.edu'

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

 Date: 02-21-90 (15:53)              Number: 2940 (Echo)
   To: IAN GREEN                     Refer#: 2601
 From: MICHAEL HOBSON                  Read: NO
 Subj: FORTH                         Status: PUBLIC MESSAGE

 re: Beginner's Forth
 There are some exellant Forth Tutorials on this board (check the file 
 areas).  For your immediate questions:

 For sixteen bit numbers:

         @    - 'fetch'  (addr - number)  replace address on top of
              stack with the value at that address.

         !    - 'store'  (number addr - ) stores number below top of 
              stack into address at top of stack.  Both values are 
              consumed (POPed).

 For eight bit numbers:

         C@   - 'c-fetch' (addr - char)  rreplace address at top of stack
              character value at that address.  For iapx86 machines, the 
              value is zero-extended into an unsigned integer.

         C!   - 'c-store' (char addr - )  store character value below top
              of stack into address at top of stack (byte store).  Both 
              items are consumed (POPed) 

 Good luck with RTX2001A kit, Ian.

 "The Elf" [^]-[^]
            \---/
 Elf - A wise and helpful variety of magical being.

 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@gateway.sei.cmu.edu'

koopman@a.gp.cs.cmu.edu (Philip Koopman) (02/23/90)

In article <514.UUL1.3#5129@willett.UUCP>, ForthNet@willett.UUCP (ForthNet articles from GEnie) writes:
> F.SERGEANT [Frank]           at 20:39 CST
>  To: David Albert  Re: inner interpreter (next) vs CALL/RET on 8088/8086
> in #1 & #2 because of a number of other variabls.  My  Intel book for the 8088
> says 

I have recently seen some work that suggests that the Intel numbers for 80x86
series processors are extremely optimistic on real programs.  The
book claims that you should add about 5% for prefetch delays, etc.
Apparently some folks took measurements that suggest the real number
is 30%-40% on an 80C286.

If you are thinking of tuning your Forth for clock cycles, get an
80286 reference manual and use it as well since there are an
awful lot of ATs out there.  You will find out
that the clock cycle counts are considerably different for
almost all instructions.  Harris makes an 80C286 and will probably
ship you an "80C286 Hardware Reference Manual" if you call the
800 sales line.

PUSH reg = 3 clocks
POP reg = 5 clocks
LODS = 9 clocks
CALL = about 9 clocks (depends on prefetch fill)
RET = about 13 clocks
JMP reg = about 9 clocks

  Phil Koopman                koopman@greyhound.ece.cmu.edu   Arpanet
  2525A Wexford Run Rd.
  Wexford, PA  15090
Senior Scientist at Harris Semiconductor, adjunct professor at CMU.
I don't speak for them, and they don't speak for me.

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

 Date: 02-22-90 (08:50)              Number: 2941 (Echo)
   To: IAN GREEN                     Refer#: 2939
 From: STEVE PALINCSAR                 Read: NO
 Subj: FORTH                         Status: PUBLIC MESSAGE

 Ian, the words are ! (store) and @ (fetch).  Before discussing their 
 usage, I must explain that the default behavior of a forth variable is 
 to place its address on the stack.  Now let's define a variable: 
 VARIABLE SNIP <cr>
 When we invoke SNIP what we do is place its address on the stack.
 To store 5 at the memory location we've established with SNIP we simply 
 put 5 on the stack, put SNIP's address on the stack by invoking its 
 name, and then use the ! operator:  5 SNIP !   The stack diagram for !
 is ( n addr -- ) which indicates that it wants an integer value with
 an address on top of it as its stack arguments; after execution, no
 arguments are returned.

 SNIP @ will put the value stored at SNIP on the stack.  @'s stack 
 diagram is ( addr -- n ).
-----
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) (02/24/90)

 Date: 02-22-90 (08:41)              Number: 2947 (Echo)
   To: MICHAEL HOBSON                Refer#: 2940
 From: IAN GREEN                       Read: 02-22-90 (10:10)
 Subj: FORTH                         Status: PUBLIC MESSAGE

    Thanks, for the clarification. I assume that the address can be a 
 symbol like 'HERE' or 'THERE' or 'CONTAINER' etc. As an extremely crude 
 example, lets try the following.

 CONSTANT UARTBASE 3F8 ;

 : CLR8250 6 FOR UARTBASE + 0 ! NEXT;

 Is this correct, the logic I am attempting to do is to write 0's to each
 register in the UART located at $3F8. If not could you fix up the word 
 so I can understand the control structure. If I am going to use the RTX 
 I am going to need to be able to use Forth. Thanks again.

 Ian Green

 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@gateway.sei.cmu.edu'

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

 Date: 02-22-90 (10:15)              Number: 2948 (Echo)
   To: IAN GREEN                     Refer#: 2605
 From: MICHAEL HOBSON                  Read: 02-22-90 (20:20)
 Subj: FORTH                         Status: PUBLIC MESSAGE

 >   Thanks, for the clarification. I assume that the address can be a 
 >symbol like 'HERE' or 'THERE' or 'CONTAINER' etc. As an extremely crude
 >example, lets try the following.
 >
 >CONSTANT UARTBASE 3F8 ;
 >
 >: CLR8250 6 FOR UARTBASE + 0 ! NEXT;
 >
 >Is this correct, the logic I am attempting to do is to write 0's to eac

 This example should be more like the following:

 HEX    ( Set Base to Hexadecimal )
 3F8 CONSTANT UARTBASE   ( CONSTANT expects a value on the stack. No
                           semicolon is needed here, because the text
                           scan for the constant's name terminates with
                           at the first whitespace character )

 : CLR8250  6 ( # of registers to clear )
            FOR

                0    ( value to store must be pushed first )

                UARTBASE I +    ( add loop index to base address )

                !               ( write zero to port address )

            NEXT   ;     ( semi-colon is a WORD and MUST be separated by
                           whitespace, the open-paren for defining these
                           comments is also a WORD and MUST be separated 
                           by whitespace. )

 Of course, the 8250 base address will be whatever you decide to decode 
 from the RTX 2001A address lines, so substitute as appropriate.
 I hope this helps somewhat.
 "The Elf" [^]-[^]
            \---/
 Elf - A wise and helpful variety of magical being.

 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@gateway.sei.cmu.edu'

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

 Date: 02-22-90 (20:23)              Number: 2949 (Echo)
   To: MICHAEL HOBSON                Refer#: 2606
 From: IAN GREEN                       Read: NO
 Subj: FORTH                         Status: PUBLIC MESSAGE

    Thanks for clarifying my attempt to understand an elemantary control 
 structure. As a novice to the language, I appreciate the assistance 
 greatly.
    I assume that inside the loop structure, I can substitute any 
 sequence of instructions I desire. My next question is how would I 
 implement a nested FOR loop. In pseudo code:

    for control1 = 1 to limit1
       for control2 = 1 to limit2
          for control3 = 1 to limit3
             dosomething
          next
       next
    next

 If it is not a problem, perhaps we could start a thread that others can 
 use to try to move from a 'conventional' language to Forth. With this 
 contest as the carrot, I feel that learning at least some degree of 
 Forth would be a valuable addition to my experience in programming. It 
 would also make life a lot easier when I attempt to 'read' Forth 
 programs outlining various algorithms.

 Thank for answering my stupid questions.

 Ian Green

 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@gateway.sei.cmu.edu'

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

 Date: 02-23-90 (13:18)              Number: 2951 (Echo)
   To: IAN GREEN                     Refer#: 2949
 From: MICHAEL HOBSON                  Read: NO
 Subj: FORTH                         Status: PUBLIC MESSAGE


 >If it is not a problem, perhaps we could start a thread that others can
 >use to try to move from a 'conventional' language to Forth. With this 
 >contest as the carrot, I feel that learning at least some degree of 
 >Forth would be a valuable addition to my experience in programming. It 
 >would also make life a lot easier when I attempt to 'read' Forth 
 >programs outlining various algorithms.
 >
 >Thank for answering my stupid questions.

 Ian, you have probably already heard this before, but no question is 
 stupid!  The desire to learn more is something that I understand, and I 
 have always appreciated the patience of those who answered my 'stupid' 
 questions.
 As for a new thread on this subject, why not.  Let's ask the sysop about
 it.   Maybe we'll call it 'GOTO Forth' :-)
 "The Elf" [^]-[^]
            \---/
 Elf - A wise and helpful variety of magical being.
-----
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) (02/26/90)

Category 2,  Topic 8
Message 42        Sat Feb 24, 1990
F.SERGEANT [Frank]           at 20:30 CST
 
 To Phil Koopman

 >I have recently seen some work that suggests that the Intel numbers 
 >for 80x86 series processors are extremely optimistic on real programs.  

 Thanks for the suggestions.  I'll check into getting the '286 manual.   Some
days I want to tune for speed and other days I'm happy when the  code runs at
all.  As you say, there are a lot of ATs out there.  They  don't have to be
good if they are cheap enough.  I did enjoy the old  days of predictable
instruction cycle timings - a selling point for the  RTX 2000/1, I believe.  I
wonder how our world would be different today  if Motorola had gotten the IBM
PC contract instead of Intel.

  - Frank
-----
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) (02/26/90)

 Date: 02-24-90 (07:55)              Number: 2959 (Echo)
   To: ALL                           Refer#: NONE
 From: IAN GREEN                       Read: (N/A)
 Subj: FORTH                         Status: PUBLIC MESSAGE

    Can someone write a demo program to outline a nested FOR loop. 
 Something like the following pseudo code:

 for i = 1 to n
    for j = 1 to m
       dosomething
    next
 next

 -------

    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.

 Thanks,

 Ian Green

 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@gateway.sei.cmu.edu'

rob@idacom.uucp (Rob Chapman) (02/27/90)

>  From: IAN GREEN                       Read: (N/A)
>     Can someone write a demo program to outline a nested FOR loop. 
>  Something like the following pseudo code:
>  for i = 1 to n
>     for j = 1 to m
>        dosomething
>     next
>  next

This translates quite easily with a sprinkling of postfix to:
    n FOR  m FOR  dosomething  NEXT  NEXT

In botForth, if n or m are 0 the 'dosomething' will not be executed.
If they are nonzero, then 'dosomething' will be executed n m * times as
you wanted.

Others please correct me if I err.  In ANS Forth I believe the same code
will execute  n 1 +  m 1 +  *  times and if n or m are 0, the 'dosomething'
will be executed at least once.  To handle the 0 case ?DUP IF...THEN
construncts must be used.  I'm not sure, but I think RTXForth follows the
ANS Forth definition.  (aside to the ANS people: isn't it tougher to explain
and harder to use this way?)

>     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.

I have found queues to be a fundamental piece for interconnecting processes.
The queue definition and it's operators extracted from botForth are:

( ==== Queues ===== )
  QUEUE  ( #words -- )  create a queue with #words entries
  >Q     ( n \ queue -- )  append n to end of queue
  Q>     ( queue -- n )  return first value in queue
  Q      ( queue -- n )  get a copy of first value in queue
  0Q     ( queue -- )  remove all items from a queue
  Q?     ( queue -- flag )  return number of items in a queue

: QUEUE  ( #words -- ) ( Queues: | >insert | >remove | >end | queue... | )
   <BUILDS  HERE 6 + ,  HERE 4 + ,  1 + 2*  DUP HERE + ,  ALLOT ;

: Q?  ( queue -- n )
   @+ @+ >R  SWAP -  DUP 0< IF  R @  R> -  + 2/ EXIT ENDIF  R> DROP  2/ ;
: >Q  ( n \ queue -- )    DUP>R  @  !-  DUP 4 - R - IF R> ! EXIT ENDIF  @ R> ! ;
: Q>  ( queue -- n )  2 + DUP>R  @  @-  DUP 2 - R - IF R> ! EXIT ENDIF  @ R> ! ;
: Q  ( queue -- n )  2 + @ @ ;
: 0Q  ( queue -- )  @+ ! ;

( example )
  10 QUEUE dataq	( queue to hold 10 data items )

  dataq 0Q  1 dataq >Q  2 dataq >Q  3 dataq >Q
  dataq Q? . ( emit a 3 )
  dataq Q>  dataq Q>  dataq Q>  . . .  ( emit 3 2 1 since the stack )
				       ( reverses the order )

  dataq Q? .  ( emit a 0 since it's now empty )

The above definitions have been written for speed on the RTX20xx.  Again I'm
guessing about the Forth that you are using so I've included definitions and
explanations for some non-standard but useful words:

( ==== Incrementing/Decrementing memory access ==== )
  @+  ( a -- n \ a+ )  fetch a word from address a and increment a by 2
  @-  ( a -- n \ a- )  fetch a word from address a and decrement a by 2
  !-  ( n \ a -- a- )  store a word at address a and decrement a by 2

: @+  ( a -- n \ a+ )  DUP @  SWAP 2 + ;
: @-  ( a -- n \ a- )  DUP @  SWAP 2 - ;
: !-  ( n \ a -- a- )  TUCK !  2 - ;

Well this is quite a bit already so I'll leave arrays to someone else.

rob@idacom		" It's so simple, it has to work! "

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

Category 2,  Topic 8
Message 44        Sun Feb 25, 1990
M.HAWLEY                     at 20:07 EST
 
This will be close:
 : NESTED-LOOPS
     N 1 DO
       M 1 DO
         DOSOMETHING
       LOOP
    LOOP
    ;
-----
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/01/90)

 Date: 02-27-90 (10:02)              Number: 1609 (Echo)
   To: IAN GREEN                     Refer#: 1608
 From: STEVE PALINCSAR                 Read: NO
 Subj: ADVANCED BEGINNERS            Status: PUBLIC MESSAGE

 You can't use an undefined word.  Since you're talking about variables 
 here, and since they are forth words, they need to be defined.  If you 
 tried to use an undefined word, the outer interpreter would simply give 
 you an error message.  OTOH, you don't "allocate space on the stack."  
 You put numbers on the stack, and the stack itself takes care of 
 management of the memory.  Actually, the code example given (with 
 N 1 DO ) wouldn't work with a variable (since you must use @ to get 
 the value of the variable) but would instead set up a loop that looped
 from 1 to 1 less than the numeric value of the address of the variable 
 N, which isn't what you wanted to do at all!  OTOH some forths have a 
 data structure called a VAR which instead of returning its address on 
 the stack when it is invoked instead returns the value stored at that 
 address.  Forth constants also return the value instead of the address.

 It's also useful to know that you aren't dealing with variables in a 
 loop.  The actual values for the starting and ending points of the loop 
 _as numbers_ must be on the parameter stack, since DO wants two 
 arguments; and DO puts those two values on the return stack.  Similarly,
 I (which gets at the current index of the inner loop) and J (which gets 
 at the current index of the outer loop) are not variables either, but 
 instead are words which copy the current index value from the Rstack.
-----
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/01/90)

 Date: 02-27-90 (23:55)              Number: 1610 (Echo)
   To: IAN GREEN                     Refer#: 1608
 From: NICK JANOW                      Read: NO
 Subj: ADVANCED BEGINNERS            Status: PUBLIC MESSAGE

 No, 'N' and 'M' are the maximum counts you desire; the '1's are the
 starting value.  For example:

  20 10 DO  LOOP

 Counts from 10  19.  Starting with 1 gives you the familiar 1 to n
 count.  The count index is 'I'.  Within the loop, 'I' puts the present
 count value on the top of the stack.  For nested loops, as in your
 question, 'J' returns the count value (index) of the next outer loop. 
 You don't have to declare 'I' or '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@gateway.sei.cmu.edu'

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

 Date: 02-28-90 (07:39)              Number: 1612 (Echo)
   To: NICK JANOW                    Refer#: 1610
 From: IAN GREEN                       Read: NO
 Subj: ADVANCED BEGINNERS            Status: PUBLIC MESSAGE

    OK, thanks. In the RTX docs I have, it mentions that I have a 
 FOR-NEXT loop construct, so I will use that as it seems to be vaguely 
 usable from my limited understanding of Forth. A code fragment that I 
 was given examplifies what I am aspiring to:

 HEX
 CONSTANT UART-BASE 2F8 ;       ( com2 )
 : CLEAR8250                    ( a word to reset a UART )
    6 FOR                       ( 6 registers )
       0                        ( the goose egg )
       UART-BASE                ( push the base address )
       I                        ( fetch up the loop index )
       +                        ( compute address )
       !                        ( barf because of I/O mapping ) 
    NEXT
 ;


 Now from what I understand the following is also kosher, but highly 
 wasteful of CPU cycles:

 : CLEAR8250-2                  ( mark 2 )
    3 FOR                       ( outer loop )
       2 FOR                    ( inner loop )
          0                     ( the goose egg again )
          UART-BASE             ( the invisible UART )
          I                     ( fetch up the outer loop index )
          J                     ( don't forget the inner loop )
          +                     ( compute )
          +                     ( rediculus isn't it )
          !                     ( finally )
      NEXT 
   NEXT
 ;

 From what I understand of the syntax of this basic control structure, I 
 can implement 'nested' loops to handle rasters and arrays etc. One idea 
 I have is to try to translate my fractal program into Forth as an 
 exercise. It does require floating point but as I recall, the F83 
 program has floats internally so that I should be OK.

 As for data containers I assume I can simply declare a variable as 
 follows:

 VARIABLE CONTAINER ;

 or is my syntax bogus?

 Ian Green

 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@gateway.sei.cmu.edu'

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

Category 2,  Topic 8
Message 49        Thu Mar 01, 1990
M.HAWLEY                     at 22:30 EST
 
FOR-NEXT looks like a regression to BASIC to me, but then FORTH is nothing if
not flexible. Regarding fractals you might be interested in my MANDELZEN file
( I think that is what I called it. ) Entirely integer F83.
-----
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/03/90)

Category 2,  Topic 8
Message 50        Fri Mar 02, 1990
D.RUFFER [Dennis]            at 01:03 EST
 
You've got two of them up there.  Here they are:

[(Silly Question:) Does anyone want me to port these to the Internet? -dwp]

  No. File Name      Type Address       YYMMDD    Bytes Accesses Lib
 1471 2-MANDEL.ARC    X   M.HAWLEY      890121     7560     20     6
    Desc: F-PC MANDELBROT DOUBLE PRECISION
 1247 MANDLZEN.ARC    X   M.HAWLEY      880918     6300     28     3
    Desc: One screen. Draws Mandelbrot Set.

Ian, your syntax for variable is close, but drop the ; at the end.

i.e.  VARIABLE CONTAINER

DaR
-----
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'

louis@marco.UUCP (Juergen Fluk) (03/07/90)

RRRRRR  TTTTTTT FFFFFFF M     M		could you please stop these boring
R     R    T    F       MM   MM 	questions ? there are very good books
R     R    T    F       M M M M 	(e.g. Leo Brodie's "Starting Forth")
RRRRRR     T    FFFFF   M  M  M 	which can answer all your questions.
R   R      T    F       M     M 	you could even find someone to answer
R    R     T    F       M     M 	your questions via e-mail (not me :-),
R     R    T    F       M     M 	but don't drown this newsgroup.

 louis

What about "How can I add two numbers, say 3 and 4 ..."

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

 Date: 03-20-90 (08:02)              Number: 1624 (Echo)
   To: ALL                           Refer#: NONE
 From: MARK ANDREWS                    Read: (N/A)
 Subj: D85 FORTH AND EMACS           Status: PUBLIC MESSAGE

 I have copies of D85 and the DOS version of Emacs.  I read in the D85
 docs that it was possible to have D85 call Emacs to use as its editor. 
 Unfortunately, the D85 info assumes you know Forth well enough to see
 how another Forther added the Qedit editor, and substitute Emacs in its
 place.  I can't even see how D85 can call Qedit, much less Emacs; I am
 out of my depth.  Any hints from anyone?
-----
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) (07/02/90)

Category 18,  Topic 57
Message 7         Sat Jun 30, 1990
D.RUFFER [Dennis]            at 23:18 EDT
 
Re: seg@PacBell.COM (S. E. Grove)

 > I would like a decompilation of the FORTH word U.R.

: U.R ( u n)   SWAP 0  <# #S #>  ROT OVER - SPACES  TYPE ;

This work in polyFORTH and should be pretty standard.  The main difference
will probably be on what size of number #S converts.  In polyFORTH it takes a
double number, thus the 0 is put on before conversion.  This word also does
not do any checking that the converted number is larger than the field.  I
contend that the programmer should know this fact before writing the
application, but others may disagree with me and insist on the check before
the SPACES.

Anyway, that is a start.   DaR
-----
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) (07/11/90)

 Date: 07-07-90 (23:43)              Number: 1811 (Echo)
   To: ALL                           Refer#: NONE
 From: BOB CAVANAUGH                   Read: (N/A)
 Subj: RESTART APPLICATION           Status: PUBLIC MESSAGE

 Can anybody out there give me a way to jump back to a word
 after an error condition is set? Specifically, I wrote a program
 to read either S-records or Intel hex records and burns
 EPROM on a circuit card.  When I encounter a bad checksum, I want to
 restart the program from my main menu routine, MAIN.  I tried
 ' main execute and it went into never-never land.  I am using V3.5
 Thanks
 -- Bob Cavanaugh
-----
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) (07/11/90)

Category 2,  Topic 8
Message 53        Mon Jul 09, 1990
D.RUFFER [Dennis]            at 20:32 EDT
 
Re: BOB CAVANAUGH

 > Can anybody out there give me a way to jump back to a word
 > after an error condition is set?  ...  I tried
 > ' main execute and it went into never-never land.

Bob, I'd suspect that you are overflowing your return stack when you try to do
that.  If you are doing this fairly deeply into you program and your main
routine calls a bunch of things before getting to the menu, then this is
pretty likely your problem.  You need to figure out how to reset the return
stack before executing main. Even if this is not what is hurting you yet, you
will need to deal with the return stack problem eventually.

Another possiblity is that your main was not defined when you define the '
main execute and you are executing some other definition of main that is doing
something nasty.  Check your load order to find out if that is the case.  If
so, you will need to use a DEFERed word to resolve the forward reference for
you.

 > I am using V3.5

I assume this is F-PC, but I don't use it much.  Does it have some kind if
contol over ABORT?  Realistically, your main word is nothing more than another
version of QUIT (where ABORT usually goes to). Many systems give you a way to
change where ABORT goes to so that you can define alternative QUIT's.  Check
out how ABORT or ABORT" works and you will probably find a way that you can
use.

DaR
-----
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) (07/16/90)

Category 2,  Topic 8
Message 54        Sun Jul 15, 1990
NMORGENSTERN                 at 14:53 EDT
 
Re: BOB CAVANAUGH

 > Can anybody out there give me a way to jump back to a word
 > after an error condition is set?

 In many cases a simple loop is enough. For example, if the word DO-IT leaves
TRUE on the stack if ok and FALSE if not, you can repeat until satisfactory by
this: BEGIN DO-IT UNTIL.

 If you want to do a fixup, you can use this: BEGIN DO-IT NOT WHILE FIXUP
REPEAT

 These do not permit jumping out of a nested word. Several methods have been
proposed that do just that. For example: CATCH THROW, which I believe is in
the library. I proposed a method at ACM SIGFORTH, Austin, 1989, which uses 5
words. I have tested it in F83, and it should work in F-PC, but I haven't
tried it. The idea is to set a "safety-net" that will catch you if you fall.
You can have as many nets as you need, and can change them while the program
is running. The method permits a Jump-Back-To a previous point, but you cannot
jump forward into.

: NET CREATE 0 , 0 , 0 , ; : 3!  ( n1 n2 n3 a -- ) 2DUP ! 2+ NIP 2! ; : 3@  (
a -- n1 n2 n3) DUP 2+ 2@ ROT @ ; : SET-NET ( net -- ) R@ SP@ ROT  RP@ SWAP 3!
; : FALL ( net -- ) 2+ RP! SWAP >R 4 + SP! ;

 For example: To declare a net:
    NET SAFETY1 To set the net
     ...  SAFETY1 SET-NET ( point A ) FOO FAH ....

To go back to point A from any word nested within FOO or FAH simply
incorporate the phrase SAFETY1 FALL The data stack and return stack will be
restored to their original depth and the program will take off from point A.

It is possible to incorporate a net in ABORT". The details are given in the
Austin paper. I have recently modified this scheme in several ways, mainly to
permit recursion, but have not completed all the details.
-----
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