I'm interested in starting to learn Forth and I'd like to find a good
tutorial on-line which could guide me through the first few steps. I've
read some history and a little bit of code, but nothing really
tutorialistic. I'd like to avoid buying any books yet, but if that is my
only option than I guess I will do so. When recommending, please keep in
mind that I only program in x86 assembly so far. Of course I've picked up
a smattering of Pascal, C/C++, etc. while programming in assembly and fixing
other people's x86 code, but I cannot say that I really know any HLLs on
their own (I cannot help but think in assembly and see HLL commands as the
built up assembly instructions they really are). I am finding myself quite
intrigued by what I've read of Forth, especially the dynamic word defining
abilities of the language, but I am also finding it pretty difficult to find
any Forth tutorial websites or webpages. I am finding the syntax
remarkably intuitive and easy, though it seems odd compared to other
languages (I've read why, and I certainly see how).
My questions are:
1) Where can I find a good, free (or low-cost) Forth system (I understand
it is much more than a language, I do not need information about everything
that it is) to use on an x86 machine (486, WinNT 4.0)?
2) Where can I find some good tutorial websites, preferably with code
examples?
3) Are there many Forth systems out there to choose from (not versions, but
variety of systems based on the current version... Kind of like the way
that TASM, MASM, NASM and A386 are all assemblers which can be used with the
x86 family, from 8086 instructions through present arch. instructions), and
if so which ones are the best and why, as well as which ones are the worst
and why?
Thanks for any info.!!! Feel free to e-mail me responses (though I
will be checking with this ng), but please do not use the 'Reply' button
since I use a bogus address there because of the sheer volume of spam I was
receiving. Instead, please write to qtc...@hotmail.com Thanks again!!!
Regards,
Seth Koster
[ deleted ]
Try my web page http://Landau1.phys.virginia.edu/classes/551/
Although the course is about number-crunching and programming techniques
useful to physicsists (or astronomers, engineers, etc.), the Forth stuff
may be of use to you. Esp. the "Beginner's Guide to Forth," and the
"Links to various Forth-related sites." Good Forthing.
Some of the programs in "Forth system and example programs" may be
useful guides to style, etc. but I must warn you they are idio-
syncratic,being aimed toward the subject matter of my class.
--
Julian V. Noble
j...@virginia.edu
"Elegance is for tailors!" -- Ludwig Boltzmann
Try the 30-day evaluation version of SwiftForth available on our website (addr
below), which comes with a great deal of electronic documentation. Of course,
we'll hope you get "hooked" and want to purchase the system (which is fairly
inexpensive) to continue.
Cheers,
Elizabeth
--
===============================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-372-8493
111 N. Sepulveda Blvd. Fax: +1 310-318-7130
Manhattan Beach, CA 90266
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
===============================================
I happened across some of your work last night as I was snooping around
various Forth websites I found referenced in the FAQ for this ng, and I
downloaded the 'Forth Primer' w/ EFORTH and F-PC, as well as some tutorials.
I assume that this 'Beginner's Guide To Forth' you speak of being on your
website is the same one I found in Do_2nd.exe, since you are the author of
the one I found.
Presuming I am correct in said assumption, is the version on your site
updated from the version found in the primer, or are they the same?
Thank you for the information so far.
Elizabeth D. Rather <era...@forth.com> wrote in message
news:37F7BFE1...@forth.com...
Shameless plug: try http://www.jwdt.com/~paysan/bigforth.html or
http://www.jwdt.com/~paysan/gforth.html. NT is perhaps good enough (much
better than 95 anyway), but Linux is preferred ;-).
--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/
I'm about half to two thirds of the way done with the first version,
and instead of using EFORTH I used F-PC since I wanted to try some things
which the tutorial said were not available in EFORTH. I'll switch to the
newer version and try it out. Thanks! I presume you want input about the
newer version, please correct me if that is wrong.
Stephen Pelc <s...@mpeltd.demon.co.uk> wrote in message
news:MPLT449...@mpeltd.demon.co.uk...
> Seth wrote in message <7t732t$8qn$1...@ash.prod.itd.earthlink.net>...
> >1) Where can I find a good, free (or low-cost) Forth system (I
> understand
> >it is much more than a language, I do not need information about
> everything
> >that it is) to use on an x86 machine (486, WinNT 4.0)?
Something which comes to mind immediately is the use of NOS. I just
noticed it's use in the newer tutorial and I remember being a bit bothered
by it when reading the first tutorial because it is pretty abstract. Why
not use TOS, 2OS, 3OS, etc., so as to better denote the position of NOS?
I'm still not sure if NOS always refers to '2nd on stack' or just 'next on
stack', I believe I saw it used both ways (I could be wrong about that).
Thanks for giving me the chance to voice my comments! In the future, after
I finish more of the tutorial, would you like me to post further comments
here or somewhere else? If elsewhere, where?
First, it does not suck. There is one more matter I've run into which
I'd like to bring to your attention, but it is only because the tutorial is
as good as it is that I do so. Most tutorials I've run into, regardless of
subject, tend to leave me with more confusion than I came to them with...
Though this may be because I tend to read tutorials about somewhat confusing
subjects (I'm trying hard to give them the benefit of the doubt).
In the tutorial I read:
8.2 Definite loops
Most Forths allow indexed loops using DO...LOOP (or +LOOP or /LOOP).
These are permitted only within definitions
: BY-ONES ( n --) 0 TUCK DO CR DUP . 1 + LOOP DROP
;
The words CR DUP . 1 + will be executed n times as the lower
limit, 0, increases in unit steps to n-1.
To step by 2's, we use the phrase 2 +LOOP to replace LOOP, as with
: BY-TWOS ( n --) 0 TUCK
DO CR DUP . 2 + 2 +LOOP DROP ;
The problem is that I still don't know why one needs to use +LOOP in
the second example, nor what /LOOP is for (just another form of LOOP? If
so, why do we need to use +LOOP in the second example?). A little more
explanation of the reasoning behind why I need to do something a certain way
would help me in the tutorial, though that may be something others do not
have as much of a problem with (I tend to be very inquisitive, logic and
reasons are very important to me). At this point I can faithfully and
easily reproduce the above examples, but I do not know that I could
implement the DO LOOP correctly if I were to need to define a word which
counts by threes or fours (though a couple experiments would tell me).
I hope this is helpful.
> In the tutorial I read:
> 8.2 Definite loops
> Most Forths allow indexed loops using DO...LOOP (or +LOOP or /LOOP).
> These are permitted only within definitions
> : BY-ONES ( n --) 0 TUCK DO CR DUP . 1 + LOOP DROP
>;
> The words CR DUP . 1 + will be executed n times as the lower
> limit, 0, increases in unit steps to n-1.
> To step by 2's, we use the phrase 2 +LOOP to replace LOOP, as with
> : BY-TWOS ( n --) 0 TUCK
> DO CR DUP . 2 + 2 +LOOP DROP ;
> The problem is that I still don't know why one needs to use +LOOP in
>the second example, nor what /LOOP is for (just another form of LOOP? If
>so, why do we need to use +LOOP in the second example?).
Okay.
As you know, every Forth word does its own job; there's no magic the
compiler does for it. So all I have to do to technically answer your
question is tell you what DO, LOOP, and +LOOP really do.
DO sets up a loop and an index, and remembers the limit. The starting
index and the limit are passed to DO as parameters.
LOOP tests the index, and if it's not equal to the limit it increments the
index and jumps back to the beginning of the loop. LOOP takes no
parameters.
+LOOP tests the index, and if it's not equal to the limit it adds the
increment to the index and jumps back to the beginning of the loop. +LOOP
takes an increment as a parameter.
(I haven't looked at the standard -- typos are my fault.)
Does this make sense?
So when you see "LOOP", you can think of it as being the same as the
phrase "1 +LOOP".
--
-William "Billy" Tanksley
> In the tutorial I read:
>
> 8.2 Definite loops
>
> Most Forths allow indexed loops using DO...LOOP (or +LOOP or /LOOP).
> These are permitted only within definitions
>
> : BY-ONES ( n --) 0 TUCK DO CR DUP . 1 + LOOP DROP
> ;
>
> The words CR DUP . 1 + will be executed n times as the lower
> limit, 0, increases in unit steps to n-1.
>
> To step by 2's, we use the phrase 2 +LOOP to replace LOOP, as with
>
> : BY-TWOS ( n --) 0 TUCK
> DO CR DUP . 2 + 2 +LOOP DROP ;
>
> The problem is that I still don't know why one needs to use +LOOP in
> the second example, nor what /LOOP is for (just another form of LOOP? If
> so, why do we need to use +LOOP in the second example?). A little more
> explanation of the reasoning behind why I need to do something a certain way
> would help me in the tutorial, though that may be something others do not
> have as much of a problem with (I tend to be very inquisitive, logic and
> reasons are very important to me). At this point I can faithfully and
> easily reproduce the above examples, but I do not know that I could
> implement the DO LOOP correctly if I were to need to define a word which
> counts by threes or fours (though a couple experiments would tell me).
> I hope this is helpful.
It is indeed. Billy Tanksley has already given you a partial answer, but
I will elaborate also. First, /LOOP is either obsolete or never a uni-
versal construct. It was intended to do the same thing as +LOOP except
with unsigned loop parameters (chiefly for 16-bit systems where having loops
longer than 37K might be important in, say, text processing or data bases).
N2 N1 DO \ Take two integers N1 N2 from the stack. The first is the
\ initial value of the loop counter, the second is the
\ limit. (If N1 >= N2 then the loop keeps going for 10^9
\ or so iterations.) The statements up to LOOP are
\ executed.
LOOP \ uses the integers to determine when to stop. If N1=N2
\ the loop is executed once (F-83 practice). If N1 < N2
\ the case where I = N2 is not executed. If N1 > N2 it
\ keeps on going, as noted above.
STEP +LOOP \ You might want the loop counter incremented by STEP
\ instead of +1. STEP can be negative.
N2 N1 ?DO \ Just like DO except if N1=N2 the loop is not executed.
\ (F-79 practice). It was added to maintain compatibility
\ with older code. (IMHO it is badly named since anything
\ with a ? mark in its name implies a decision, but there
\ isn't really a decision here.)
EXAMPLES:
: test1 DO I . LOOP ; 4 4 test1 4 ok
4 5 test1 BLOOEY!
: test2 ?DO I . LOOP ; 4 4 test2 ok
: test3 DO I . -1 +LOOP ; 0 5 test3 5 4 3 2 1 0 ok
: test4 ?DO I . -1 +LOOP ; 0 5 test4 5 4 3 2 1 0 ok
5 5 test4 ok
6 5 test4 BLOOEY!
I believe it makes sense to me now... If I use 3 +LOOP it will
increment by threes, etc., correct? For example:
: THREES 0 TUCK DO CR DUP . 3 + 3 +LOOP DROP ; ( One number per column)
If so, then it makes perfect sense to me. Thanks!
But I think I'd be jumping to a false conclusion if I think that /LOOP
(or \LOOP, I don't remember) is a DIV LOOP. IE: index = 8 and 2 /LOOP
Output: 8 4 2 1
Definitely a useful criticism. I have modified the file primer.txt
to take this into account.
With regard to your previous critique of NOS, I find I have used it
consistently to mean "the datum 1 cell below TOS", and I defined it ok,
so I made no change there.
Please feel free to note any more areas of confusion. I really appreciate
the feedback.
> Definitely a useful criticism. I have modified the file primer.txt
> to take this into account.
Is this the same primer.txt file located on the www.forth.org site?
Cheers,
Phil.
/LOOP never was a standard word, so not every system has it (e.g.,
Gforth doesn't).
> It was intended to do the same thing as +LOOP except
>with unsigned loop parameters
+LOOP uses circular arithmetic for its parameters, like LOOP. /LOOP
should do the same. The difference is that +LOOP interprets the
increment as signed, whereas /LOOP interprets it as unsigned.
The extended range for increments probably has little significance,
but +LOOP incurs a little more overhead per iteration or requires a
significantly more complex implementation to get the same efficiency
as /LOOP. Since +LOOP is only useful with positive increments anyway,
/LOOP would be preferable.
To show the difference in the overhead per iteration, here's Gforth's
code for (+loop):
(+loop) n -- gforth paren_plus_loop
Cell index = *rp;
/* sign bit manipulation and test: (x^y)<0 is equivalent to (x<0) != (y<0) */
/* dependent upon two's complement arithmetic */
Cell olddiff = index-rp[1];
if ((olddiff^(olddiff+n))>=0 /* the limit is not crossed */
|| (olddiff^n)>=0 /* it is a wrap-around effect */) {
... another iteration ...
}
else
... end loop ...
and the code for (-loop) (-LOOP is similar to /LOOP, except that it
decrements instead of incrementing):
(-loop) u -- gforth paren_minus_loop
Cell index = *rp;
UCell olddiff = index-rp[1];
if (olddiff>u) {
... another iteration ...
}
else
... end loop ...
- anton
--
M. Anton Ertl Some things have to be seen to be believed
an...@mips.complang.tuwien.ac.at Most things have to be believed to be seen
http://www.complang.tuwien.ac.at/anton/home.html
This is just because C doesn't support overflow checks. On a processor
or language with overflow check, (+loop) is just an addition to the loop
register, and a branch on not overflow. loop register is not the index
register as is, but computed of index and limit to make sure that the
loop register crosses the minint/maxint border on termination.
But then you have to increment two counters, or compute the index from
the loop register when I is used.
And architectures without branch-on-overflow are not that rare,
either: e.g., MIPS, Alpha, uP21.
It was invented with FORTH, Inc.'s microFORTH in the late 70's. On low-end
microprocessors an unsigned compare is significantly faster than a signed
version, and covers the majority of cases. It's intended to be pronounced
"ramp-loop," suggesting ramping up (visual interpretation of the /). Note that
since a match on the limit may not be exact, +LOOP and /LOOP have to terminate
when the index _passes_ the limit.
> > It was intended to do the same thing as +LOOP except
> >with unsigned loop parameters
>
> +LOOP uses circular arithmetic for its parameters, like LOOP. /LOOP
> should do the same. The difference is that +LOOP interprets the
> increment as signed, whereas /LOOP interprets it as unsigned.
>
> The extended range for increments probably has little significance,
> but +LOOP incurs a little more overhead per iteration or requires a
> significantly more complex implementation to get the same efficiency
> as /LOOP. Since +LOOP is only useful with positive increments anyway,
> /LOOP would be preferable.
It's certainly true that the overwhelming majority of cases use a positive
increment, but I certainly wouldn't buy a categorical statement that _only_
positive increments are useful!
AE> +LOOP uses circular arithmetic for its parameters, like LOOP.
/LOOP
AE> should do the same. The difference is that +LOOP interprets the
AE> increment as signed, whereas /LOOP interprets it as unsigned.
For application, the easiest thing to remember should be: the loop stops
as soon as, by adding the step size, the boundary of 'limit' and 'limit
- 1' is crossed, in whichever direction (assumed, the parameters to DO
are 'limit' and 'start-value'). So in fact this should work circular,
similar as WITHIN.
First acquaintance with DO..[+]LOOP mostly makes for a bit of confusion,
but the above rule should make it more transparent. Tracking the
end-condition should be implementable similar with carry-bit as with
signed-arithmetic overflow. One may as well implement it secondary and
keep the indices, such that tracking for zero of the index parameter
works. The second parameter in any case should be for calculating 'I'
and 'J' only.
Here's why:
`-1 0 ?DO i . -1 +LOOP' prints `0 -1'
` 0 0 ?DO i . -1 +LOOP' prints nothing
-LOOP is nicer (it's symmetric to /LOOP):
`-2 0 ?DO i . 1 -LOOP' prints `0 -1'
`-1 0 ?DO i . 1 -LOOP' prints `0'
` 0 0 ?DO i . 1 -LOOP' prints nothing
You can find an implementation of -LOOP in ANS Forth (with some
restrictions (see source) and without the speed advantage) in the file
loops.fs in http://www.complang.tuwien.ac.at/forth/compat.zip.
I'm sure it all makes sense to you now, Seth, but as no-one seems to
have mentioned it...
>: BY-ONES ( n --)
> 0 TUCK DO CR DUP . 1 + LOOP DROP ;
>: BY-TWOS ( n --)
> 0 TUCK DO CR DUP . 2 + 2 +LOOP DROP ;
> I believe it makes sense to me now... If I use 3 +LOOP it will
>increment by threes, etc., correct? For example:
>: THREES
> 0 TUCK DO CR DUP . 3 + 3 +LOOP DROP ; ( One number per column)
You do realise that the
DUP . 1 +
DUP . 2 +
DUP . 3 +
parts have nothing to do with the loop increment and are just there to
print numbers? This sort of thing often crops up in examples, and at
first sight the beginner may think that there is some reason for such a
correlation, where it's really just the example writer not quite
managing to see things fully from the novice's perspective.
No insults intended; I've been caught by this type of thing on both
sides.
Cheers
--
Keith Wootten