Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Forth16e, Forth32e, "de facto" forth programming standards for embedded

1,053 views
Skip to first unread message

Raimond Dragomir

unread,
Jul 10, 2014, 5:35:12 AM7/10/14
to
Hi all,
I don't want to start another ANS forth standard war here.
It's just my own experience that for an 32bit embedded system (microcontroller class) a good simple ANS forth system or cross compiler is quite an overkill.
ANS maps quite good for a 16bit system, and that's normal. But the compatibility between 16bit and 32bit adds a big overhead for a 32bit system.

Here are two sensible areas:

1. picture numeric output.
It imposes the usage of double numbers. For a 16bit system it is about ok. You're likely to need it, and if you really want, you can add a 16bit numeric output version for where the absolute performance is needed.
But for a 32bit system it requires 64bit numbers and maths. That's huge. I never needed 64bit in my 20years of embedded, being C or forth or anything else. Also, just think that the 32bit system is not a Cortex-M, maybe it is an 8051! (I have an 8051 system which I made 32bit because it's just plain simpler to work with).
So, for picture numeric output, a "single cell" version is in fact the most usefull for embedded, and the double cell version might be an otional feature.
Why is it a problem for 32bit and not for 16 bit? Because for 16bit the single cell variant can be optional and you are ANS compliant, but for the 32bitters you can do a single cell variant but you MUST carry the double cell variant to be ANS compliant.

2. FM/MOD, SM/REM and mixed precision math.
Mixed precision has the same problem as the picture numeric output above. Again, I never needed 64 bit numbers even for scaling. And I have done a lot of applications that needed scaling, including for 32bit microcontrollers. In fact, I don't have a single application done with floating point stuff. Well, you can fake a */ like this: : */ * / ; for a 32bit system, but that's not the point.
Also, why having both FM/MOD and SM/REM? We are in 2014, living in a C world. C division is SM/REM (or at least it's a hardware division and C doesn't care). My applications also don't care. Besides being optional these mixed precision words, the division should be just symmetrical, and a user needing a FM/MOD will be just a user with a problem. Anyway, I'm sure 99% of the C programmers are just unaware that there even exist two kind of division algorythms for signed numbers.

What I had over time:
- a standalone 32bit 8051 forth system
- a standalone 32bit avr forth system
Both have non-standard single cell picture numeric output (but it is 32bit)
Both don't have mixed precision math.
Both have simmetric division, and I really not care about it in fact, because I never had a need for dividing negative numbers until now
- I have now a cortex-m 32bit system (it's "almost" standalone, but it doesn't have the compiler. But everything else is in, including dictionary headers).
I made it like the 8051 and avr systems above, without any double numbers math. I don't need 64bit numbers on the cortex even that it is not quite an overkill for these mcu's. Besides, without the 64bit numbers these systems are in fact 100% compatible which is quite nice.

So, this is the context. I care only of embedded systems. I really don't care about the "host".

A "Forth16e" standard for 16bit embedded systems is quite close to the ANS if not almost it. I think not much is to discuss about it. 200x standard even had done a good step in recognizing that double cells of any kind may not even be found in severly constrained 16bit systems.

A "Forth32e" standard for 32bit embedded systems has some problems with the ANS standard. It may be already 90-95% of the ANS, maybe. It's the most interesting one to talk about.

Once again, this talking is not about the forth ANS standard. I never wanted to be compliant with the standard, because I'm not selling anything. My forths are for me solely. But I was inspired by the ANS in some of my implementation decisions over time. If you ask me, I think ANS in the 200x form is maybe 90% of what it should have to be. My personal view is that the standard has (or had?) a chance to encourage new programming and new applications, and not maintaining legacy code all over again. But that's my personal view.

All that I want to discuss here, is something like "de facto" standards for embedded. The ANS is here in the discussion as a point of reference.
For example, a "Forth32e" de-facto standard goal is to provide good compatibility between 32bit systems for:
- 8051
- AVR
- PIC16, PIC24
- PIC32
- ARM of any kind
- you name it

Bernd Paysan

unread,
Jul 10, 2014, 11:18:56 AM7/10/14
to
Raimond Dragomir wrote:

> Hi all,
> I don't want to start another ANS forth standard war here.
> It's just my own experience that for an 32bit embedded system
> (microcontroller class) a good simple ANS forth system or cross compiler
> is quite an overkill. ANS maps quite good for a 16bit system, and that's
> normal. But the compatibility between 16bit and 32bit adds a big overhead
> for a 32bit system.

Ok, so your proposal is to move the following words from core e.g. to the
double number wordset (which is optional, and if you don't like it, don't
include it:)

#
#S
#>
<#
>NUMBER (in favor of a single cell >NUMBER variant?
S>D
SM/REM
FM/MOD
UM/MOD
M*
UM*

and possible */, because it has a widening internal multiplication (in favor
of a */ variant that doesn')?

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

Raimond Dragomir

unread,
Jul 10, 2014, 11:41:00 AM7/10/14
to
Something like that.
Faking the */ is not a solution of course. I'm using a fake */ in my 32bit systems because I need it for scaling, but I should have renamed it different (I really don't know how :)
I always have values for scale under 16bit. That comes not from my older 16bit systems but from actual real life sensors.

From those words you listed, I feel that the <# # #S #> >NUMBER should have been in CORE EXT, the rest in the double number word set. But a single cell versions of these should or may be present, not necessarly in the core, could be in the core ext also.

Well, my proposal is for a hypotethycal 32bit Forth standard for embedded systems. I'm sure nobody will take me seriously in respect with the ANS.

But I really like to know what are other forthers doing in the embedded area, and if they have the same problems as I do.

Bernd Paysan

unread,
Jul 10, 2014, 11:55:31 AM7/10/14
to
Raimond Dragomir wrote:
> But I really like to know what are other forthers doing in the embedded
> area, and if they have the same problems as I do.

Usually, you find 32 bit embedded Forths only on 32 bit platforms, e.g. the
mecrisp-stellaris from Matthias Koch. There is no severe space limitation,
so the double words simply go in. I think that's why nobody complained so
far: For 16 bit systems, the double words are necessary, and for 32 bit
Forths, they aren't a burden. There is enough space for them.

Raimond Dragomir

unread,
Jul 10, 2014, 12:02:18 PM7/10/14
to
For quite a long time, I didn't care much about portability of my applications. They were 16bit all (even if they were C), with very few 32bit operations for scaling.
But when the first arm7tdmi micros appeared (lpc2106 and the like) I started thinking more about a 32bit system. I have done one for 8051 and one for my AVR boards. It turned that the 32bit system was cleaner, with less words (no need with lots of double number words) even if the basic system was slower.
After the cortex chips appeared, I have done some applications with them, in C. I found that I still don't need double numbers (long longs), even if these applications was bigger.
Now I'm porting a 32bit system for the cortex. And if I want portability of my previous work, it's natural to make the system "standard".
But it's my "standard".
I was thinking to make the cortex system ANS compatible. But it breaks the compatibility with the other systems, and making my other systems ANS compatible is just out of questions (I can't even think of 64bit math for the poor 8051 or avr).
That's why I want to here other opinions.
Maybe there are few people indeed that do what I'm doing (32bit systems for 8 or 16bitters) indeed.
But I like more my 32bit system as it is, than an ANS 16bit one.

bruce.m...@gmail.com

unread,
Jul 10, 2014, 12:06:44 PM7/10/14
to
On Thursday, July 10, 2014 5:35:12 AM UTC-4, Raimond Dragomir wrote:
> Hi all,

> Here are two sensible areas:
>
> 1. picture numeric output.
>
> It imposes the usage of double numbers. For a 16bit system it is about ok. You're likely to need it, and if you really want, you can add a 16bit numeric output version for where the absolute performance is needed.
>
> But for a 32bit system it requires 64bit numbers and maths. That's huge. I never needed 64bit in my 20years of embedded, being C or forth or anything else. Also, just think that the 32bit system is not a Cortex-M, maybe it is an 8051! (I have an 8051 system which I made 32bit because it's just plain simpler to work with).
>
> So, for picture numeric output, a "single cell" version is in fact the most usefull for embedded, and the double cell version might be an otional feature.
>
> Why is it a problem for 32bit and not for 16 bit? Because for 16bit the single cell variant can be optional and you are ANS compliant, but for the 32bitters you can do a single cell variant but you MUST carry the double cell variant to be ANS compliant.

But you can include the single cell version ~ say they are called ## ##S and ##> ~ in the binary, and provide source for # #S and #> and still be compliant.

So the issue is more of reserving a standard name for the single cell versions of # #S and #>

> 2. FM/MOD, SM/REM and mixed precision math.

> Mixed precision has the same problem as the picture numeric output above. Again, I never needed 64 bit numbers even for scaling. And I have done a lot of applications that needed scaling, including for 32bit microcontrollers. In fact, I don't have a single application done with floating point stuff. Well, you can fake a */ like this: : */ * / ; for a 32bit system, but that's not the point.

I wouldn't personally have any trouble with changing "producing the intermediate double-cell result d." to "producing the intermediate result d with a size of at least 32 bits."

But reducing programmer entitlements under the existing standard is always an issue, and while there may not be much need in embedded applications for an intermediate precision in excess of 32 bits, it would be less surprising if there were desktop applications that relied on it.

The most direct solution is to standardize a version of */ under a new name that has the "producing the intermediate result d with a size of at least 32 bits." behavior, and systems that wish to include that in the binary and leave */ to a source file may do so.

It seems that W*/ or L*/ would be evocative names for that.

Or else a version which would also be faster on 16 bit implementations on a processor with hardware 16 bit multiple with carry, "single-cell times divide":

``S*/ ( n1 n2 n3 -- n4 ) CORE EXT
Multiply n1 by n2 producing the intermediate single-cell result d. ...''

> Also, why having both FM/MOD and SM/REM? We are in 2014, living in a C world. C division is SM/REM (or at least it's a hardware division and C doesn't care). My applications also don't care. Besides being optional these mixed precision words, the division should be just symmetrical, and a user needing a FM/MOD will be just a user with a problem. Anyway, I'm sure 99% of the C programmers are just unaware that there even exist two kind of division algorythms for signed numbers.

A system that is based on SM/REM including source for an FM/MOD does not seem to me like its a big ask, since its a definition that can be found by hunting around online.

> Both have symmetric division, and I really not care about it in fact, because I never had a need for dividing negative numbers until now

Many of the scientific applications where SM/REM is broken and FM/MOD has to be defined if its not available are unlikely to be required in an embedded applications, but in unit conversions for data logging, it matters, as SM/REM introduces an over-representation of 0's, resulting in false results when regressing the numbers. It also biases the the slope of a regression function most strongly precisely when regressing over a limited range of data, so getting the poorest fit precisely when getting an unbiased fit is most important to distinguish statistically significant from statistically not significant results.

Typically in long term remote site data logging, getting the right number logged is more important than getting the wrong number logged faster.

> - I have now a cortex-m 32bit system (it's "almost" standalone, but it doesn't have the compiler. But everything else is in, including dictionary headers).
>
> I made it like the 8051 and avr systems above, without any double numbers math. I don't need 64bit numbers on the cortex even that it is not quite an overkill for these mcu's. Besides, without the 64bit numbers these systems are in fact 100% compatible which is quite nice.
>

> So, this is the context. I care only of embedded systems. I really don't care about the "host".
>
> A "Forth16e" standard for 16bit embedded systems is quite close to the ANS if not almost it. I think not much is to discuss about it. 200x standard even had done a good step in recognizing that double cells of any kind may not even be found in severely constrained 16bit systems.
>
> A "Forth32e" standard for 32bit embedded systems has some problems with the ANS standard. It may be already 90-95% of the ANS, maybe. It's the most interesting one to talk about.

> Once again, this talking is not about the forth ANS standard. I never wanted to be compliant with the standard, because I'm not selling anything. My forths are for me solely.

The other reason to want to be compliant with the standard is because you are sharing something. In my mind, that is the more important reason, though those engaged in selling something could well disagree.

But quite often, Forth compliance is a matter of simply using different names when you want to do something different to what the standard specifies. The main exceptions are when Forth94 specifies a minimum buffer or length requirement that is unsuitable for an implementation, in which case one can always say an implementation is "Forth aligned, except the text input buffer is 63 bytes, the maximum word size is 15 chars and, and PAD is simply the space available two cells above HERE, which is not guaranteed to provide 84 characters of space".

Andrew Haley

unread,
Jul 10, 2014, 1:48:14 PM7/10/14
to
Raimond Dragomir <raimond....@gmail.com> wrote:

> Also, why having both FM/MOD and SM/REM? We are in 2014, living in a
> C world. C division is SM/REM (or at least it's a hardware division
> and C doesn't care). My applications also don't care. Besides being
> optional these mixed precision words, the division should be just
> symmetrical, and a user needing a FM/MOD will be just a user with a
> problem. Anyway, I'm sure 99% of the C programmers are just unaware
> that there even exist two kind of division algorythms for signed
> numbers.

I can answer that one: it's to do with the application areas for which
Forth was designed, and it's still true today.

SM/REM has a discontinuity about zero which produces a jog in the slope
of a line. "Discontinuity can present a problem in as ordinary an
example as moving a robot arm through physical space. The application
might make use of virtual co-ordinates such that the arm would have to
traverse an imaginary zero point. If the physical co-ordinates are
computed by addition or subtraction of the virtual co-ordinates, the
arm will jump or stall whenever it crosses the virtual zero point." [1]

Andrew.

[1] Division, Relationals, and Loops, Leo Brodie and Dean Sanderson,
FORTH, Inc. Proc. Rochester Forth Standards Conference, 1981.

Raimond Dragomir

unread,
Jul 10, 2014, 2:12:18 PM7/10/14
to
> The other reason to want to be compliant with the standard is because you are sharing something. In my mind, that is the more important reason, though those engaged in selling something could well disagree.
>
Yup, that comes to my mid too.

The most annoying is the <# # #> thing. It looks like it is suppose to be working everywere, anytime, and it is, until the "0" that comes for doubling the otherwise single cell unsigned number...

That zero makes my stuff not compatible with existing stuff. I did not like this even for a 16bit system. Why force 32bit operations for 8 bit microcontrollers, when you know that you have 16bit numeric output? You specifically put with your own hand the 0 to make it double.

Here comes some forth paradoxes: on one hand, forth have different name for different types on operators, for unsigned, for floats, etc.
On the other hand we want single words that should work on more than one type: this is the picture numeric output: have one for doubles, because it will work for singles too. Yes, but with BIG overheads.

BruceMcF

unread,
Jul 10, 2014, 2:30:00 PM7/10/14
to
On Thursday, July 10, 2014 2:12:18 PM UTC-4, Raimond Dragomir wrote:
> On the other hand we want single words that should work on more than one type: this is the picture numeric output: have one for doubles, because it will work for singles too. Yes, but with BIG overheads.

But an equally concise single celled version just rests on having a punctuation character you are willing to devote to the single cell equivalent of # ... if & then:
<& & HOLD &S &>

... in the implementation and the problem is fixed ... and if there is <# # #S and #> defined in a source file somewhere, then you've "provided" those CORE words.

Andrew's experience with motor control matches my experience with data logging ~ its the identical problem, the discontinuity around 0 ...

... and it seems like a part of the reason that SM/REM is fine for you is that you've have the range of values where the flaw with SM/REM comes up.

There's a lot of people for whom the difference doesn't make a difference, but on the other hand *among* those for whom it makes a difference, more need the FM/MOD version than the SM/REM version ... so SM/REM provides a way to export a hardware symmetric divide under a standard name so that people who need an FM/MOD are able to make the conversion.

Making FM/MOD CORE means that an implementer that doesn't include it in the binary of their system really ought to include source for the FM/MOD word for the use of those who need it.

Raimond Dragomir

unread,
Jul 10, 2014, 2:33:28 PM7/10/14
to
> I can answer that one: it's to do with the application areas for which
>
> Forth was designed, and it's still true today.
>
>
>
> SM/REM has a discontinuity about zero which produces a jog in the slope
>
> of a line. "Discontinuity can present a problem in as ordinary an
>
> example as moving a robot arm through physical space. The application
>
> might make use of virtual co-ordinates such that the arm would have to
>
> traverse an imaginary zero point. If the physical co-ordinates are
>
> computed by addition or subtraction of the virtual co-ordinates, the
>
> arm will jump or stall whenever it crosses the virtual zero point." [1]
>
>
>
> Andrew.
>
>
>
> [1] Division, Relationals, and Loops, Leo Brodie and Dean Sanderson,
>
> FORTH, Inc. Proc. Rochester Forth Standards Conference, 1981.

I'm sure there are applications for FM/MOD. But I think Forth care too much about it, when the rest of the world even doesn't care or works out the problem quietly (I don't think they use forth when they need floored division :)

Raimond Dragomir

unread,
Jul 10, 2014, 2:59:02 PM7/10/14
to
> ... in the implementation and the problem is fixed ... and if there is <# # #S and #> defined in a source file somewhere, then you've "provided" those CORE words.

> Making FM/MOD CORE means that an implementer that doesn't include it in the binary of their system really ought to include source for the FM/MOD word for the use of those who need it.

Personally, I have a big problems with this kind of solution: providing in source form anything that you don't provide. And this seems to be the solution for everything.

To me this sounds like: "I really don't have this XXX word. But if you really want it, and you don't know how to write it in terms of the other words that I do have, or if you really tried hard to find an implementation over internet but didn't find anything, take this source, I wrote it for you".

I will give you one single example: For a FM/MOD in source form, only the threading overhead (I have a token threading for the cortex, others may have ITC or DTC) is going to take longer than the whole routine written in assembly.

Nevertheless, I could provide this kind of words in source form:

\ these definitions will be inlined by the optimizing compiler
: nop ( -- ) ;
: 1+ ( x -- x ) 1 + ;
: 1- ( x -- x ) -1 + ;
: cell+ ( x -- x ) 4 + ;
: cell- ( x -- x ) -4 + ;
: cells ( x -- x ) 4 * ;
: 2* ( x -- x ) 2 * ;
: bl ( -- 32 ) 32 ;
: false ( -- 0 ) 0 ;
: true ( -- -1 ) -1 ;

\ these definitions will take only dictionary space
synonym char+ 1+
synonym chars nop
synonym i r@

\ loops
: ilim ( -- x ) 1 rpick ;
: j ( -- x ) 2 rpick ;
: jlim ( -- x ) 3 rpick ;
: k ( -- x ) 4 rpick ;
: klim ( -- x ) 5 rpick ;

\
: erase ( addr u -- ) 0 fill ;

\ terminal i/o
: cr ( -- ) 13 emit 10 emit ;
: space ( -- ) bl emit ;


But double numbers math and <# # #> for doubles are a different story....

Albert van der Horst

unread,
Jul 10, 2014, 3:53:42 PM7/10/14
to
In article <lpmd1j$mnc$1...@online.de>, Bernd Paysan <bernd....@gmx.de> wrote:
>Raimond Dragomir wrote:
>> But I really like to know what are other forthers doing in the embedded
>> area, and if they have the same problems as I do.
>
>Usually, you find 32 bit embedded Forths only on 32 bit platforms, e.g. the
>mecrisp-stellaris from Matthias Koch. There is no severe space limitation,
>so the double words simply go in. I think that's why nobody complained so
>far: For 16 bit systems, the double words are necessary, and for 32 bit
>Forths, they aren't a burden. There is enough space for them.

For 64 bit systems, they are over the top, unless ...
I'm very happy with all those double precision words for number
theoretical applications (read projecteuler.net )

>
>--
>Bernd Paysan
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

m...@iae.nl

unread,
Jul 10, 2014, 3:54:55 PM7/10/14
to
On Thursday, July 10, 2014 8:59:02 PM UTC+2, Raimond Dragomir wrote:
>
> Personally, I have a big problems with this kind of solution: providing in
> source form anything that you don't provide. And this seems to be the
> solution for everything.
>
> To me this sounds like: "I really don't have this XXX word. But if you really
> want it, and you don't know how to write it in terms of the other words that
> I do have, or if you really tried hard to find an implementation over
> internet but didn't find anything, take this source, I wrote it for you".
[..]
When an implementer choses this way out he can be as system-specific
as he likes. He can provide you with a bunch of CODE x $yy c, .. END-CODE definitions that will make you perfectly happen.

-marcel


bruce.m...@gmail.com

unread,
Jul 10, 2014, 3:56:49 PM7/10/14
to
On Thursday, July 10, 2014 2:59:02 PM UTC-4, Raimond Dragomir wrote:
> To me this sounds like: "I really don't have this XXX word. But if you really want it, and you don't know how to write it in terms of the other words that I do have, or if you really tried hard to find an implementation over internet but didn't find anything, take this source, I wrote it for you".

To me it sounds like, "in case you need FM/MOD, here is a working FM/MOD definition that is based on SM/REM." So no need to invest the time remembering how symmetric to modular signed division works, and no need to even be connected to the internet.

> I will give you one single example: For a FM/MOD in source form, only the threading overhead (I have a token threading for the cortex, others may have ITC or DTC) is going to take longer than the whole routine written in assembly.

So? If your SM/REM is that fast, I'd rather have an FM/MOD written based on that than a FM/MOD written from scratch. Andreas, one of the previous times this came up, had:

: FM/MOD \ ( d m -- r q ) signed floored division
DUP >R SM/REM 2DUP 0< AND IF 1- SWAP R> + SWAP ELSE R> DROP THEN ;

... if there is more threading overhead in there than processing time, then that would imply there is a reasonably fast SM/REM ... and leveraging that fast SM/REM is *precisely what someone who needs FM/MOD would want to do*.

A two liner definition which is easy to get a corner case wrong is exactly sometime I would be happy to find if an implementation told me:
? FM/MOD

> Nevertheless, I could provide this kind of words in source form:
...

> But double numbers math and <# # #> for doubles are a different story....

To be sure they can be more like three or four line definitions, but since its for I/O, if the extra time for processing is not worth it, the source can be ported to use the single-cell words.

Coos Haak

unread,
Jul 10, 2014, 3:57:28 PM7/10/14
to
Op Thu, 10 Jul 2014 11:12:18 -0700 (PDT) schreef Raimond Dragomir:

>> The other reason to want to be compliant with the standard is because you are sharing something. In my mind, that is the more important reason, though those engaged in selling something could well disagree.
>>
> Yup, that comes to my mid too.
>
> The most annoying is the <# # #> thing. It looks like it is suppose to be working everywere, anytime, and it is, until the "0" that comes for doubling the otherwise single cell unsigned number...
>
> That zero makes my stuff not compatible with existing stuff. I did not like this even for a 16bit system. Why force 32bit operations for 8 bit microcontrollers, when you know that you have 16bit numeric output? You specifically put with your own hand the 0 to make it double.
Do you never work with signed numbers? Then you have to use S>D instead of
zero.
>
> Here comes some forth paradoxes: on one hand, forth have different name for different types on operators, for unsigned, for floats, etc.
> On the other hand we want single words that should work on more than one type: this is the picture numeric output: have one for doubles, because it will work for singles too. Yes, but with BIG overheads.
What about addressing characters with C@ C! and cells with @ ! +!.
Do you really have trouble with these? Overloading operators is a C++
thing, not Forth's.

--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Albert van der Horst

unread,
Jul 10, 2014, 4:12:15 PM7/10/14
to
In article <ccb1d2d4-3f31-4f2c...@googlegroups.com>,
BruceMcF <agi...@netscape.net> wrote:
>On Thursday, July 10, 2014 2:12:18 PM UTC-4, Raimond Dragomir wrote:
>> On the other hand we want single words that should work on more than
>one type: this is the picture numeric output: have one for doubles,
>because it will work for singles too. Yes, but with BIG overheads.
>
>But an equally concise single celled version just rests on having a
>punctuation character you are willing to devote to the single cell
>equivalent of # ... if & then:
> <& & HOLD &S &>

I would go for <% % %S %> as &S is sometimes used for CHAR S.
(Was in iforth, maybe still, and has always been in ciforth.)

>
>... in the implementation and the problem is fixed ... and if there is
><# # #S and #> defined in a source file somewhere, then you've
>"provided" those CORE words.
>
>Andrew's experience with motor control matches my experience with data
>logging ~ its the identical problem, the discontinuity around 0 ...
>
>... and it seems like a part of the reason that SM/REM is fine for you
>is that you've have the range of values where the flaw with SM/REM comes
>up.
>
>There's a lot of people for whom the difference doesn't make a
>difference, but on the other hand *among* those for whom it makes a
>difference, more need the FM/MOD version than the SM/REM version ... so
>SM/REM provides a way to export a hardware symmetric divide under a
>standard name so that people who need an FM/MOD are able to make the
>conversion.
>
>Making FM/MOD CORE means that an implementer that doesn't include it in
>the binary of their system really ought to include source for the FM/MOD
>word for the use of those who need it.

See also
http://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division-in-c

Summary:
The consensus now is that truncating division is a mistake, e.g.
Python mandates floored division. Not to speak of more math languages
like Haskell.
It is a thorn in the side of the mathematician, having 2n equivalence
classes, and this translate to many practical issues. ( Some of which
have been mentioned in this thread.)

In the first C-standard it was implementation defined how % works.

That newer C standards prescribe truncated comes from FORTRAN compatibility.
As we all know FORTRAN was thrown together haphazardly and never
cleaned up. ;-)

Admittedly SM/REM is occasionally useful in control applications. Well that's
why we have it.

Groetjes Albert

Albert van der Horst

unread,
Jul 10, 2014, 4:18:14 PM7/10/14
to
In article <fb6046ef-72a1-45b2...@googlegroups.com>,
Raimond Dragomir <raimond....@gmail.com> wrote:
>> ... in the implementation and the problem is fixed ... and if there is
><# # #S and #> defined in a source file somewhere, then you've
>"provided" those CORE words.
>
>> Making FM/MOD CORE means that an implementer that doesn't include it
>in the binary of their system really ought to include source for the
>FM/MOD word for the use of those who need it.
>
>Personally, I have a big problems with this kind of solution: providing
>in source form anything that you don't provide. And this seems to be the
>solution for everything.
>
>To me this sounds like: "I really don't have this XXX word. But if you
>really want it, and you don't know how to write it in terms of the other
>words that I do have, or if you really tried hard to find an
>implementation over internet but didn't find anything, take this source,
>I wrote it for you".
>
>I will give you one single example: For a FM/MOD in source form, only
>the threading overhead (I have a token threading for the cortex, others
>may have ITC or DTC) is going to take longer than the whole routine
>written in assembly.

Since when is source equivalent to no assembly allowed?

Or even

CODE FM/MOD
5A C,
5B C,
58 C,
...

NEXT,
END-CODE

bruce.m...@gmail.com

unread,
Jul 10, 2014, 4:19:07 PM7/10/14
to
I meant, of course, definitions for UD/MOD based on smaller division ... obviously, given that:

: # ( ud1 -- ud2 ) BASE @ UD/MOD ROT >digit HOLD ;
: #S ( ud1 -- ud2 ) BEGIN # 2DUP OR 0= UNTIL ;

... are more one-liners.

bruce.m...@gmail.com

unread,
Jul 10, 2014, 4:49:34 PM7/10/14
to
On Thursday, July 10, 2014 4:12:15 PM UTC-4, Albert van der Horst wrote:
> I would go for <% % %S %> as &S is sometimes used for CHAR S.

I was grabbing a punctuation at random, but in sense of a percentage normally being a pure ratio, like divided by like, there is a faint connotation rationale for using % for the single-cell integer being divided by a single-cell BASE.

Given that it acts on an integer and doesn't deliver a string until it's done, I don't see any way that it would interact with the use of %token% for pattern replacement.

Coos Haak

unread,
Jul 10, 2014, 5:01:41 PM7/10/14
to
Op Thu, 10 Jul 2014 13:19:07 -0700 (PDT) schreef bruce.m...@gmail.com:
: # 0 BASE @ UM/MOD >R BASE @ UM/MOD SWAP >digit HOLD R> ;
Somewhat longer, but no need to define UD/MOD which is used nowhere else.

Elizabeth D. Rather

unread,
Jul 10, 2014, 5:31:56 PM7/10/14
to
Well, there's prior art here that you can use. Since Open Firmware had
minimum cell size of 32 bits, they used single-precision number
formatting words <# u# u#s sign hold and u#> (with the double words # #s
and #> defined but not used; IMO it's perfectly acceptable to have them
available in an auxiliary, optional load).

Anyway, if you're going to have single versions, IMO you should use
these names.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Bernd Paysan

unread,
Jul 10, 2014, 5:35:20 PM7/10/14
to
Raimond Dragomir wrote:
> I'm sure there are applications for FM/MOD. But I think Forth care too
> much about it, when the rest of the world even doesn't care or works out
> the problem quietly (I don't think they use forth when they need floored
> division :)

No, a significant portion of the rest of the world has followed our lead.
Like Python, which now requires floored division. Python is one of the most
important non-C-derived programming languages, and the C family has some
pressure to stay compatible with the garbage the C standard team decided 15
years ago ;-).

Guido van Rossum's blog post on that topic is nearly 4 years old now:

http://python-history.blogspot.de/2010/08/why-pythons-integer-division-floors.html

Forth's discussion about floored divions is in the order of 30 years old
(about standards, with some chaos when Forth-79 was symmetric, Forth-83 was
floored, and ANS Forth allowed both). You can't expect everybody to
understand immediately, but as time goes by, it sinks in.

bruce.m...@gmail.com

unread,
Jul 10, 2014, 7:29:07 PM7/10/14
to
On Thursday, July 10, 2014 5:01:41 PM UTC-4, Coos Haak wrote:
> BruceMcF:
>> I meant, of course, definitions for UD/MOD based on smaller division ... obviously, given that:

>>: # ( ud1 -- ud2 ) BASE @ UD/MOD ROT >digit HOLD ;
>>: #S ( ud1 -- ud2 ) BEGIN # 2DUP OR 0= UNTIL ;

>> ... are more one-liners.

> : # 0 BASE @ UM/MOD >R BASE @ UM/MOD SWAP >digit HOLD R> ;

> Somewhat longer, but no need to define UD/MOD which is used nowhere else.

I should have cited the source ~ those were Brad Rodriguez's Camel Forth for 8086 ~ and yes, for illustrative purposes. Even if fitting into 63 char lines and including stack comment, that is only a two-liner.

How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't know off the top of my head, but I can't imagine it would be as hard as writing UM/MOD in assembler, so I guess if I was pressed, I'd work it out.

bruce.m...@gmail.com

unread,
Jul 10, 2014, 7:30:37 PM7/10/14
to
On Thursday, July 10, 2014 5:31:56 PM UTC-4, Elizabeth D. Rather wrote:

> Well, there's prior art here that you can use. Since Open Firmware had
> minimum cell size of 32 bits, they used single-precision number
> formatting words <# u# u#s sign hold and u#> (with the double words # #s
> and #> defined but not used; IMO it's perfectly acceptable to have them
> available in an auxiliary, optional load).

There you go, problem already solved by Open Firmware, <# U# U#S SIGN HOLD and U#> it is, then.

Coos Haak

unread,
Jul 10, 2014, 8:15:01 PM7/10/14
to
Op Thu, 10 Jul 2014 16:29:07 -0700 (PDT) schreef bruce.m...@gmail.com:
Adding the single precision:
: U# ( u1 -- u2 ) 0 BASE @ UM/MOD SWAP >digit HOLD ;

Aside: Camel Forth for the 1802 used big endian for the data and the return
stack, but little endian for the data stack. This way >R and @ etc. are
faster. Both stack grow downwards.
FigForth for the 1802 had stacks growing to each other with the terminal
input buffer in the middle. All addresses were bigendian, but the data
stack was slower than Camelforth, and was ITC instead of DTC. If it had
existed in 1981, my ELF II would still be running...

Elizabeth D. Rather

unread,
Jul 10, 2014, 9:45:47 PM7/10/14
to
On 7/10/14 5:41 AM, Raimond Dragomir wrote:
> joi, 10 iulie 2014, 18:18:56 UTC+3, Bernd Paysan a scris:
>> Raimond Dragomir wrote:
>>
>>> Hi all,
>>
>>> I don't want to start another ANS forth standard war here.
>>> It's just my own experience that for an 32bit embedded system
>>> (microcontroller class) a good simple ANS forth system or cross compiler
>>> is quite an overkill. ANS maps quite good for a 16bit system, and that's
>>> normal. But the compatibility between 16bit and 32bit adds a big overhead
>>> for a 32bit system.
...
> Faking the */ is not a solution of course. I'm using a fake */ in my 32bit systems because I need it for scaling, but I should have renamed it different (I really don't know how :)
> I always have values for scale under 16bit. That comes not from my older 16bit systems but from actual real life sensors.
>
> From those words you listed, I feel that the <# # #S #> >NUMBER should have been in CORE EXT, the rest in the double number word set. But a single cell versions of these should or may be present, not necessarly in the core, could be in the core ext also.
>
> Well, my proposal is for a hypotethycal 32bit Forth standard for embedded systems. I'm sure nobody will take me seriously in respect with the ANS.
>
> But I really like to know what are other forthers doing in the embedded area, and if they have the same problems as I do.

Well, FORTH, Inc. has been supporting products and writing custom
applications for embedded systems since 1974. Obviously the technology
has changed dramatically, but we have successfully followed that
evolution with evolving Forth systems aimed at professional programmers.

Until the early 80's, all of or systems used a 16-bit cell size. With
the advent of the x86 and 68K families of processors, we began
supporting both 16-bit and 32-bit implementations, and developed
programming styles and practices to minimize the difficulties.

We currently support 12 different processor families with our SwiftX
cross-compilers, ranging from 8051's to i386, ARM, and 68K variants.
Most of the 8-bit and 16-bit processors use a 16-bit Forth, although we
have done a 32-bit 8051 implementation for a special project.

Frankly, it has not been our experience that maintaining a reasonable
level of compatibility across implementations of different cell sizes
adds "a big overhead." We have over 30 files of source for kernel
features that run without change on every processor we support.
Individual processors additionally have about 20 files of source for
processor-specific features, including an optimizing compiler, plus some
for board-level features. Our priorities in our implementations are
performance and programmer convenience second.

We helped develop a draft cross-compiler standard (jointly with MPE)
some years ago. I believe some people in the current Forth200x group are
interested in updating it, but I don't know the current status. It does
not, however, address cell size much beyond the strategies originally
developed for Forth94.

bruce.m...@gmail.com

unread,
Jul 10, 2014, 11:00:05 PM7/10/14
to
On Thursday, July 10, 2014 8:15:01 PM UTC-4, Coos Haak wrote:
> Aside: Camel Forth for the 1802 used big endian for the data and the return
> stack, but little endian for the data stack. This way >R and @ etc. are
> faster. Both stack grow downwards.

Big endian for return, little endian for data?

I presume that is to make effective use of the indirect register with auto-increment address mode? I have never had the joy of coding the 1802 ... that is to say, the Wikipedia page makes it sound like a joy.

> FigForth for the 1802 had stacks growing to each other with the terminal
> input buffer in the middle. All addresses were bigendian, but the data
> stack was slower than Camelforth, and was ITC instead of DTC. If it had
> existed in 1981, my ELF II would still be running...

I like having data and return stacks growing toward each other, but I've never thought to have the console input buffer in between the two.

Elizabeth D. Rather

unread,
Jul 10, 2014, 11:56:45 PM7/10/14
to
Historically, FORTH, Inc. systems have the dictionary grow from low
memory upward. The return stack is at the top, growing towards low
memory. The data stack is lower and growing towards low memory, with TIB
extending up from the bottom of the data stack towards the Return Stack
(with some guard cells). This way the stacks have plenty of space, as
they're growing towards memory that is likely to be available
(typically, the terminal buffer is short when the Return Stack is
deeper), with a modest amount of dedicated memory.

Back in the day when there were block buffers, they were in high memory
above the Return Stack.

Raimond Dragomir

unread,
Jul 11, 2014, 12:30:24 AM7/11/14
to
>
> Well, there's prior art here that you can use. Since Open Firmware had
>
> minimum cell size of 32 bits, they used single-precision number
>
> formatting words <# u# u#s sign hold and u#> (with the double words # #s
>
> and #> defined but not used; IMO it's perfectly acceptable to have them
>
> available in an auxiliary, optional load).
>
>
>
> Anyway, if you're going to have single versions, IMO you should use
>
> these names.
>
>
>
> Cheers,
>
> Elizabeth
>
>
>
> --
>
> ==================================================
>
> Elizabeth D. Rather (US & Canada) 800-55-FORTH
>
> FORTH Inc. +1 310.999.6784
>
> 5959 West Century Blvd. Suite 700
>
> Los Angeles, CA 90045
>
> http://www.forth.com
>
>
>
> "Forth-based products and Services for real-time
>
> applications since 1973."
>
> ==================================================

Thank you, I didn't know.
So my words are not #, #S, #> but U#, U#S, U#>.
I'm perfectly ok with that.

Best regards,


Raimond Dragomir

unread,
Jul 11, 2014, 12:44:34 AM7/11/14
to
Forth 200x recognizes severly constrained embedded systems. It's a pleasant surprise for me. But I may add: In addition to severly constrained 16bit systems, there may be severly constrained 32bit systems also. 32bit systems like the old 8051. Or take a more modern and very popular AVR. 64bit multiplication a division is not something that I want my AVR to use on everyday application.

It's just weird that double cell multiplication and divisions are "a must" for the current standard (core), but the D+ and D- are optional doubles :)

You remainded me about that cross-compiler documents. I have them somewhere and I will read them. I have some plans for cross-compiling my newest cortex system.

Raimond Dragomir

unread,
Jul 11, 2014, 12:51:40 AM7/11/14
to
Ok, both SM/REM and FM/MOD have their applications. In fact my biggest problem is not that they are two, but that they are at all, any of them, because they are double :)

There is a whole class of 32bit applications that really don't need any 64bit operations. And 32bit forth systems in that class are really nice.
32bit forth "lite" systems which don't have doubles (in the sens of double word math, not cell pairs).

Elizabeth D. Rather

unread,
Jul 11, 2014, 12:53:48 AM7/11/14
to
On 7/10/14 6:44 PM, Raimond Dragomir wrote:
> Forth 200x recognizes severly constrained embedded systems. It's a pleasant surprise for me. But I may add: In addition to severly constrained 16bit systems, there may be severly constrained 32bit systems also. 32bit systems like the old 8051. Or take a more modern and very popular AVR. 64bit multiplication a division is not something that I want my AVR to use on everyday application.
>
> It's just weird that double cell multiplication and divisions are "a must" for the current standard (core), but the D+ and D- are optional doubles :)

At least, */ is trivial to implement with a double intermediate product,
because on most processors MUL leaves a double product in registers, and
DIV takes a double dividend in the same registers. So it's a no-brainer
to do in code. And it's an incredibly useful word.

Mark Wills

unread,
Jul 11, 2014, 3:59:43 AM7/11/14
to
On Thursday, 10 July 2014 16:41:00 UTC+1, Raimond Dragomir wrote:
> From those words you listed, I feel that the <# # #S #> >NUMBER should have been in CORE EXT, the rest in the double number word set. But a single cell versions of these should or may be present, not necessarly in the core, could be in the core ext also.

Fully agree. As you pointed out, it does make sense that in 16-bit systems, <# #S #> and friends are 32-bit. I fully agree that it is overkill in the 32-bit world.

The committee shouldn't be afraid to deviate from previous standards on this issue.

Mark Wills

unread,
Jul 11, 2014, 4:11:15 AM7/11/14
to
Oh that's cool. I wasn't aware of that. That's a neat solution for me in the 16-bit world, where I have numbers that I wish to format, but I know they are <= 16-bits.

Gerry Jackson

unread,
Jul 11, 2014, 5:28:55 AM7/11/14
to
On 10/07/2014 20:56, bruce.m...@gmail.com wrote:
> So? If your SM/REM is that fast, I'd rather have an FM/MOD written based on that than a FM/MOD written from scratch. Andreas, one of the previous times this came up, had:
>
> : FM/MOD \ ( d m -- r q ) signed floored division
> DUP >R SM/REM 2DUP 0< AND IF 1- SWAP R> + SWAP ELSE R> DROP THEN ;
>
> .... if there is more threading overhead in there than processing time, then that would imply there is a reasonably fast SM/REM ... and leveraging that fast SM/REM is*precisely what someone who needs FM/MOD would want to do*.
>
> A two liner definition which is easy to get a corner case wrong is exactly sometime I would be happy to find if an implementation told me:
> ? FM/MOD

Well in that case I wouldn't use the above definition, it is flawed
(pardon the pun) e.g.

~~~~~~~~~~
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
: FM/MOD \ ( d m -- r q ) signed floored division compiled
DUP >R SM/REM 2DUP 0< AND IF 1- SWAP R> + SWAP ELSE R> DROP THEN ;
redefined fm/mod with FM/MOD ok
-10. 15 fm/mod .s <2> -10 0 ok
~~~~~~~~~~

but the correct answer is ( 5 -1 )

I think this has been pointed out before.

This seems to work but there ought to be a better solution

: fm/mod dup >r 2dup xor 0< >r sm/rem
over r> and if 1- swap r> + swap else r> drop then
;

--
Gerry

Matthias Koch

unread,
Jul 11, 2014, 6:30:56 AM7/11/14
to
All the parts you mentioned are at least doable given enough code space and work, and I want to put two technical implementation problems into the discussion one more time:

CREATE with a default action and DOES> that can rewrite this action, multiple times. This is a real hassle with one-time-writeable memory. Mikael Nordmann pointed out that Flash write buffers solve the issue successfully, see FlashForth, but in worst case they need erase cycles.

For standalone embedded systems offering direct compilation into "large paged" Flash memory as in STM32F407 a CREATE with unchangeable default action and an old style <BUILDS DOES> that cannot be redefined multiple times solve the issue.

The second issue is collecting the Flags. ANS defines IMMEDIATE which can be placed outside of a definition, but as I am having additional flags for inlining, foldability, instruction set optimisations, compile-only and RAM-allocation, I need to bundle them together somehow before the flag field can be written (one time). Having the flags inside of the definition is a great help.

But basically, I am fine. The standard helps to have a common base and a few lines of documentation are enough to clarify what is different in a particular implementation.
Matthias

PS: Floored division for symmetric cores, for Mecrisp for MSP430 and usable on Mecrisp-Stellaris on ARM Cortex, too. You can omit the inline and foldable flags:

: sm/rem ( d1 n1 -- n2 n3 ) m/mod inline 3-foldable ;

: fm/mod ( d1 n1 -- n2 n3 floored signed div'n courtesy of Ed Smeda )
dup >r
sm/rem 2dup 1 < and
if swap r@ + swap 1- then
r>
drop
3-foldable ;


-3. 2 sm/rem . . -1 -1 ok.
-3. 2 fm/mod . . -2 1 ok.

Gerry Jackson

unread,
Jul 11, 2014, 6:56:16 AM7/11/14
to
On 11/07/2014 11:30, Matthias Koch wrote:
> PS: Floored division for symmetric cores, for Mecrisp for MSP430 and
> usable on Mecrisp-Stellaris on ARM Cortex, too. You can omit the inline
> and foldable flags:
>
> : sm/rem ( d1 n1 -- n2 n3 ) m/mod inline 3-foldable ;
>
> : fm/mod ( d1 n1 -- n2 n3 floored signed div'n courtesy of Ed Smeda )
> dup >r
> sm/rem 2dup 1 < and
> if swap r@ + swap 1- then
> r>
> drop
> 3-foldable ;
>
>
> -3. 2 sm/rem . . -1 -1 ok.
> -3. 2 fm/mod . . -2 1 ok.

I don't know what M/MOD does but if inline and 3-foldable are only flags
and can be omitted the above implies it is the same as SM/REM. If that
is true then:

2. 3 fm/mod . . -1 5 ok \ Is not ok

See my earlier reply to Bruce McFarling

--
Gerry

Andrew Haley

unread,
Jul 11, 2014, 8:08:52 AM7/11/14
to
And, for a bit more info, my posting of twenty years ago. :-)

https://groups.google.com/d/msg/comp.lang.forth/QBtluXNh7J0/tpkvAYv2ytQJ

Andrew.

Anton Ertl

unread,
Jul 11, 2014, 8:12:57 AM7/11/14
to
bruce.m...@gmail.com writes:
>How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't know off the top of my head, but I can't imagine it would be as hard as writing UM/MOD in assembler, so I guess if I was pressed, I'd work it out.

I think it's harder. When I ported Gforth to the Alpha in 1995, our
first 64-bit port, we found out that GCC was buggy and did not
implement long long as documented (later they fixed the
documentation), so we had to do our own implementations of double and
mixed primitives. For UM/MOD I looked around and eventually settled
on implementing division with shifts and subtracts, the way I had
learned it on the 6502 (and FM/MOD and SM/REM are based on the UM/MOD
implementation).

Admittedly building on top of single-by-single division is not very
attractive on the Alpha, because the Alpha has no hardware division,
but my implementation was also intended and used for other 64-bit
platforms.

Much later (in 2006), we reworked the mixed division implementation
for more performance and looked at what various books said and what
others had programmed, and this all resulted in a huge piece of messy
code: Look at umdiv() ff. in

http://git.savannah.gnu.org/cgit/gforth.git/tree/engine/support.c

which uses macros defined in

http://git.savannah.gnu.org/cgit/gforth.git/tree/engine/longlong.h

(only 1356 lines of macros, used only for mixed division).

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2014: http://www.euroforth.org/ef14/

Anton Ertl

unread,
Jul 11, 2014, 8:59:10 AM7/11/14
to
"Elizabeth D. Rather" <era...@forth.com> writes:
>At least, */ is trivial to implement with a double intermediate product,
>because on most processors MUL leaves a double product in registers, and
>DIV takes a double dividend in the same registers.

When I actually looked, it was not that many. Looking at the
platforms supported by Gforth (non-EC):

yes 386
no alpha (mixed multiplication, but no division)
yes amd64
no? arm
no? hppa (probably no division)
no? ia64 (certainly not used in Gforth)
yes m68k
yes mips (has two special-purpose registers for this)
no power (no mixed mul/div support at all)
yes sparc (mul/div step support, later full muls)

>So it's a no-brainer
>to do in code.

If I had known how messy it is in advance, I probably would not have
reworked the mixed division words in 2006.

bruce.m...@gmail.com

unread,
Jul 11, 2014, 9:28:12 AM7/11/14
to
On Friday, July 11, 2014 5:28:55 AM UTC-4, Gerry wrote:
> Well in that case I wouldn't use the above definition, it is flawed
> (pardon the pun) e.g.

See the benefit of having a tested solution in source as opposed to expecting people to Google for a definition? Not all definitions that one googles for are the correct definition.

Andrew Haley

unread,
Jul 11, 2014, 10:33:07 AM7/11/14
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> "Elizabeth D. Rather" <era...@forth.com> writes:
>>At least, */ is trivial to implement with a double intermediate product,
>>because on most processors MUL leaves a double product in registers, and
>>DIV takes a double dividend in the same registers.
>
> When I actually looked, it was not that many. Looking at the
> platforms supported by Gforth (non-EC):
>
> yes 386
> no alpha (mixed multiplication, but no division)
> yes amd64
> no? arm

I agree. ARM has MUL for the low part and MULH for the high part.
Division is still something of a problem: I don't think there's any
easy way to do it.

Andrew.

bruce.m...@gmail.com

unread,
Jul 11, 2014, 10:41:22 AM7/11/14
to
On Friday, July 11, 2014 8:12:57 AM UTC-4, Anton Ertl wrote:
> BruceMcF writes:

> >How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't know off the top of my head, but I can't imagine it would be as hard as writing UM/MOD in assembler, so I guess if I was pressed, I'd work it out.

> I think it's harder. ...

> Admittedly building on top of single-by-single division is not very
> attractive on the Alpha, because the Alpha has no hardware division,
> but my implementation was also intended and used for other 64-bit
> platforms.

> Much later (in 2006), we reworked the mixed division implementation
> for more performance ...

But (1) you are rewriting for more performance and (2) in C ... for a portability layer to support <# # #> I/O, performance should be balanced against code size. A long division algorithm would have 4 ``M/MOD'' consuming the first three intermediate result mods as it goes to build the next dividend and reserving the intermediate quotients underneath to build into the final quotient.

Anton Ertl

unread,
Jul 11, 2014, 11:56:25 AM7/11/14
to
bruce.m...@gmail.com writes:
>On Friday, July 11, 2014 8:12:57 AM UTC-4, Anton Ertl wrote:
>> BruceMcF writes:
>
>> >How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't kn=
>ow off the top of my head, but I can't imagine it would be as hard as writi=
>ng UM/MOD in assembler, so I guess if I was pressed, I'd work it out.
>
>> I think it's harder. ...
>
>> Admittedly building on top of single-by-single division is not very=20
>> attractive on the Alpha, because the Alpha has no hardware division,
>> but my implementation was also intended and used for other 64-bit
>> platforms.
>
>> Much later (in 2006), we reworked the mixed division implementation=20
>> for more performance ...=20
>
>But (1) you are rewriting for more performance and (2) in C ...

The performance is in comparison with double-by-double division (what
we did before on platforms where long long was implemented correctly),
so that's not a very aggressive performance goal. And the original
poster also had performance in mind.

> A long division algorithm would have 4 ``M/MOD'' consuming the =
>first three intermediate result mods as it goes to build the next dividend =
>and reserving the intermediate quotients underneath to build into the final=
> quotient.

I am eagerly expecting your implementation. If I had found an
attractive mixed division algorithm that's based on single division, I
would have used it (instead of shift-and-subtract) on the first
implementation, and also on the reworking of mixed division. I don't
like the big mess that this stuff is now (with architecture-specific
ifdefs and lots of inline assembly language).

bruce.m...@gmail.com

unread,
Jul 11, 2014, 12:26:22 PM7/11/14
to
On Friday, July 11, 2014 11:56:25 AM UTC-4, Anton Ertl wrote:
> BruceMcF writes:

> I am eagerly expecting your implementation.

I can tell you in advance that, no, you aren't ^_^ ... a long division seems like it is almost always going to be slower than what you've got ... and in the rare case that its not, now you are just spilling the conditional compilation from C into Forth.

But if I have time this weekend, I'll see if I can convert a 16/8=8:8 to 32/16=16:16 into a 32/16=16:16 to 64/32=32:32, since a flat 32/32=32:32 M/MOD on a 32 bit Forth can of course serve as a 32/16=16:16 (although for a 32 bit forth on a 16 bit processor in a space-constrained implementation, one might have a 32/16=16:16 primitive as its more compact, and for operations in its range, more efficient).

> If I had found an attractive mixed division algorithm that's based on single
> division, I would have used it (instead of shift-and-subtract) on the first
> implementation, and also on the reworking of mixed division. I don't
> like the big mess that this stuff is now (with architecture-specific
> ifdefs and lots of inline assembly language).

The key word there is "attractive". You wouldn't want to make that space/speed trade-off for the general division operation for gforth.

Elizabeth D. Rather

unread,
Jul 11, 2014, 1:33:07 PM7/11/14
to
On 7/11/14 2:59 AM, Anton Ertl wrote:
> "Elizabeth D. Rather" <era...@forth.com> writes:
>> At least, */ is trivial to implement with a double intermediate product,
>> because on most processors MUL leaves a double product in registers, and
>> DIV takes a double dividend in the same registers.
>
> When I actually looked, it was not that many. Looking at the
> platforms supported by Gforth (non-EC):
>
> yes 386
> no alpha (mixed multiplication, but no division)
> yes amd64
> no? arm
> no? hppa (probably no division)
> no? ia64 (certainly not used in Gforth)
> yes m68k
> yes mips (has two special-purpose registers for this)
> no power (no mixed mul/div support at all)
> yes sparc (mul/div step support, later full muls)
>
>> So it's a no-brainer
>> to do in code.
>
> If I had known how messy it is in advance, I probably would not have
> reworked the mixed division words in 2006.

That's very interesting. I am not familiar with some of those. My
observation was certainly true some years ago (the 386/68K/SPARC
generation and before).

AKK

unread,
Jul 11, 2014, 2:05:24 PM7/11/14
to
I dug out the following ugly beast from some dusty archive. The
bit-shifting for-loop is only 32 bit wide because it can be cut short
when the divident has only 32 bit.

void mf_mudivmod(MF_ADDR* mfsp) // ( udl udh u -- qdl qdh r )
{
#if MF_ASM
__asm { push ebp
push ebx
mov ebp, [mfsp]
mov ebx, [ebp]
mov edx, [ebp-4]
mov eax, [ebp-8]
mov ecx, eax
mov eax, edx
xor edx, edx
div ebx
xchg eax, ecx
div ebx
mov [ebp], edx
mov [ebp-4], ecx
mov [ebp-8], eax
pop ebx
pop ebp }
#elif MF_MATH64
MF_DADDR *ud = (MF_DADDR*)(mfsp-2); MF_ADDR tos = MF_TOS;
MF_TOS = *ud % tos, *ud /= tos;
#else // partial radix 2
int i; MF_ADDR a,b,c,d;
b = MF_THIRD, c = MF_SECOND, d = MF_TOS;
if (c == 0)
MF_THIRD = b / d, MF_TOS = b % d;
else
{ a = c / d, c %= d;
for (i=0; i<32; i++)
{ d = ((MF_CELL)c < 0);
c = (c << 1) | ((MF_CELL)b < 0);
b = (b << 1) | ((MF_CELL)a < 0);
a = (a << 1);
if ((c >= MF_TOS) | d) c -= MF_TOS, a += 1; }
MF_THIRD = a, MF_SECOND = b, MF_TOS = c; }
#endif
}


BruceMcF

unread,
Jul 11, 2014, 8:50:47 PM7/11/14
to
On Friday, July 11, 2014 6:56:16 AM UTC-4, Gerry wrote:
>> -3. 2 sm/rem . . -1 -1 ok.
>> -3. 2 fm/mod . . -2 1 ok.
>
> I don't know what M/MOD does but if inline and 3-foldable are only flags
> and can be omitted the above implies it is the same as SM/REM. If that
> is true then:
>
> 2. 3 fm/mod . . -1 5 ok \ Is not ok
>
> See my earlier reply to Bruce McFarling

And my prior reference to the benefit of having words tested on a system for tricky corner cases versus what had been presented as the presumed first recourse of googling for definitions ~ indeed, not necessarily googling, since I find that I have both definitions in various source files on the hard drive of my play netbook upstairs.

visua...@rocketmail.com

unread,
Jul 11, 2014, 11:32:06 PM7/11/14
to
On Thursday, July 10, 2014 9:45:47 PM UTC-4, Elizabeth D. Rather wrote:

> Well, FORTH, Inc. has been supporting products and writing custom
> applications for embedded systems since 1974. Obviously the technology
> has changed dramatically, but we have successfully followed that
> evolution with evolving Forth systems aimed at professional programmers.

I started ten years later, 1984, using RSC-Forth, but I can confirm, the technology obviously has changed dramatically: while Rockwell's 6511AQ only had a serial line and timers on chip, nowadays microcontrollers have all sorts of hardware I/O on chip.

In my opinion it would be helpful, especially for people new to Forth, if there would be words like @ADC, !DAC, !PWM, !SPI, @SPI and so forth supported. Then a program probably would still run when changing to another microprocessor model.

I am sorry, I never worked with Swift Forth. Does Swift Forth support these words - @ADC, !DAC, !PWM, !SPI, @SPI as example?

I know this is a challenge. It would be great if there would be some kind of standard to make microcontroller Forth programs portable.

Elizabeth D Rather

unread,
Jul 12, 2014, 12:02:12 AM7/12/14
to
SwiftX is our product for embedded systems. It's an interactive
cross-compiler that runs as a SwiftForth application (Win, Linux, OSX)
and supports many boards on the most popular microcontrollers.

SwiftX supports the I/O on each board, with demo apps that use it, and
all source is available so you can adapt to different hardware. The
concept of "standardizing" functions like that is interesting, but in my
experience there's too much variance in the actual hardware to make it
completely portable.

bruce.m...@gmail.com

unread,
Jul 12, 2014, 4:38:00 AM7/12/14
to
On Friday, July 11, 2014 11:56:25 AM UTC-4, Anton Ertl wrote:
> I am eagerly expecting your implementation.

I think its something along the lines below, though I'm sure there's a bug in there somewhere.

You'll see the problem with long division for the general case instantly ... since you have to work with a divisor half the width of a cell to ensure that the modulus will fit into the top half of the cell, doing it for a general mixed division routine is an interpolation ... if B is larger than half the cell width, then for n such that int(B/2^n) does fit in the lower half of the cell:
partial_quotient = int(A/(int(B/2^n)+1))/2^n)
NB. partial_quotient < quotient
increment = A - B*partial_quotient
Repeat:
B*2^n for n=1,2,.. until [B*2^n]>increment
partial' := partial+B*2^(n-1)
increment' := increment - B*2^(n-1)
until increment<B

Then mod = A - B*quotient

So for the general case, its normally reasonably well behaved, but when its badly behaved, its pretty bad.

However, for the applications at hand ... # and #S ... half a cell is plenty to divide by base. Hence Unsigned, Mixed, "Word" divide and modulus, UMW/MOD

I'm sure I've messed something up trying to simplify this, but I don't have any more time to work on this, I have to fight the closure of a railway corridor tomorrow.

\ UMWMOD.F
\ for testing purposes ~ in reality this would be primitive
\ for hardware 32/32=32:32 division operation.

: U/MOD ( u1 u2 -- u3 u4 ) 0 SWAP UM/MOD ;

\ for testing purposes ~ in reality this would be a hardware
\ cell-wide add with carry set/clear giving high cell 1/0
\ due to eForth ~ may sometimes be known as +'

: UM+ ( u1 u2 -- ud ) 0 SWAP M+ ;

HEX FFFFFFFF CONSTANT MAX-U32
: low16 ( u1 -- u2 ) FFFF AND ;

DECIMAL
: hi16 ( u1 -- u2 ) 16 RSHIFT ;
: lo>hi16 ( u1 -- u2 )
16 LSHIFT ( for testing on 64 bit systems: ) MAX-U32 AND ;
: ?quotient-error ( u -- ) ABORT" UMW/MOD quotient too large." ;

\ Divide 64 bit double in 32 bit system by 16 bit word
: UMW/MOD ( ud w1 -- w2 u )
2DUP < 0= ?quotient-error >R \ high cell must be smaller than divisor
lo>hi16 OVER hi16 OR R@ U/MOD DUP hi16 ?quotient-error ROT ROT
lo>hi16 SWAP low16 OR R> U/MOD ROT UM+ ?quotient-error ;

bruce.m...@gmail.com

unread,
Jul 12, 2014, 5:00:26 AM7/12/14
to
On Saturday, July 12, 2014 4:38:00 AM UTC-4, bruce.m...@gmail.com wrote:

Of course, that's quite wrong because the stack picture was written wrong as a factor for # ... it should be a double divided by a word for a word modulus and a double result

\ UMW/MOD ( ud1 w1 -- ud2 w2 ) \ ud2 quotient, w2 remainder


\ for testing purposes ~ in reality this would be primitive
\ for hardware 32/32=32:32 division operation.
: U/MOD ( u1 u2 -- u3 u4 ) 0 SWAP UM/MOD ;

\ for testing purposes ~ in reality this would be a hardware
\ cell-wide add with carry set/clear giving high cell 1/0

\ due to eForth ~ may sometimes be known as +'

: UM+ ( u1 u2 -- ud ) 0 SWAP M+ ;

\ must run on a 32 bit cell system

HEX
: low16 ( u1 -- u2 ) FFFF AND ;
DECIMAL
: hi16 ( u1 -- u2 ) 16 RSHIFT ;
: lo>hi16 ( u1 -- u2 ) 16 LSHIFT ;

\ Divide 64 bit double in 32 bit system by 16 bit word
\ for 64 bit result and 16 bit or less modulus
\ pre-alpha

: UMW/MOD ( ud1 w1 -- ud2 w2 )
DUP >R U/MOD SWAP >R SWAP ( res1 ud1lo R: w1 mod1 )
DUP hi16 R> lo>hi16 OR R@ U/MOD SWAP >R SWAP ( res1 res2 ud1lo R: w1 mod2 )
lo16 R> lo>h116 OR R> U/MOD SWAP >R ( res1 res2 res3 R: mod3 )
OVER lo>hi16 UM+ ROT hi16 + ROT UM+ ABORT" UMW/MOD quotient too large" R> ;

Paul E Bennett

unread,
Jul 12, 2014, 6:54:45 AM7/12/14
to
I think these words (or very similar) exist on some systems but they have
been connected with specific boards and attached Forth products. I have
worked on some systems that had used the Triangle Digital Services TDS
modules where these words were part of the basic provision. Unfortunately,
Peter Rush has now retired and folded the company.

--
********************************************************************
Paul E. Bennett IEng MIET.....<email://Paul_E....@topmail.co.uk>
Forth based HIDECS Consultancy.............<http://www.hidecs.co.uk>
Mob: +44 (0)7811-639972
Tel: +44 (0)1235-510979
Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..
********************************************************************

Gerry Jackson

unread,
Jul 12, 2014, 1:46:00 PM7/12/14
to
On 11/07/2014 13:08, Andrew Haley wrote:
> And, for a bit more info, my posting of twenty years ago. :-)
>
> https://groups.google.com/d/msg/comp.lang.forth/QBtluXNh7J0/tpkvAYv2ytQJ

An implementation of FM/MOD using your method putting the -m/mod in-line is:

: fm/mod-1 ( d n -- r q )
dup 0< dup >r if negate >r dnegate r> then
over 0< if dup >r + r> then um/mod
r> if swap negate swap then
;

Compare this with the version I posted elsewhere (slightly modified):

: fm/mod-2 ( d n -- r q )
dup >r 2dup xor 0< >r sm/rem
over r> and if 1- swap r> + swap exit then r> drop
;

They both give the same results with the numbers I've used to test them

fm/mod-2 is a bit shorter with fewer IFs. It looks like the method you
posted is a neat idea spoiled somewhat by having to deal with all
combinations of positive and negative numbers.

Of course fm/mod-1 can be simplified a bit by restoring -m/mod as a factor

: -m/mod ( d +n -- r q ) over 0< if dup >r + r> then um/mod ;

: fm/mod-1a ( d n -- r q )
dup 0<
if negate >r dnegate r> -m/mod swap negate swap exit then
-m/mod
;

--
Gerry

hughag...@yahoo.com

unread,
Jul 12, 2014, 10:01:31 PM7/12/14
to
On Thursday, July 10, 2014 11:59:02 AM UTC-7, Raimond Dragomir wrote:
> I will give you one single example: For a FM/MOD in source form, only the threading overhead (I have a token threading for the cortex, others may have ITC or DTC) is going to take longer than the whole routine written in assembly.

I have D/ in the novice package, written in ANS-Forth. D/ should be in the standard so that it would be written in assembly-language by the compiler-writer. Writing such a low-level word in high-level Forth results in abysmal performance. It can be in an optional word-set so it can be ignored by those who don't need it --- but it should be in the standard so everybody provides it in the same way --- when such things don't get put in the standard, they end up being implemented differently by everybody, and this doesn't allow programs to port from one system to another (which is the point of having a standard).

What I have (everything in the CF.4TH file) was written by Nathaniel Grosman in an FD article in the 1980s for 16-bit Forth-83 --- all I did was upgrade it to work on a 32-bit ANS-Forth system --- this was a trivial upgrade.

D/ was provided in CF.4TH for use in continued fractions, which are typically calculated at compile-time, so speed isn't an issue in this case. I wouldn't recommend using my D/ on any speed-critical program --- it would be best to write it in assembly-language and abandon ANS-Forth compliance.

Raimond Dragomir

unread,
Jul 13, 2014, 12:56:23 AM7/13/14
to
Some early conclusions:

- Pictured numeric output:
<# U# U#S U#> for single
<# # #S #> for double

If you look at these a cleaner naming would be:
<# # #S #> for single
<# D# D#S D#> for double
But it's too late for this I think

FM/MOD: Not clear. I'm glad I don't need it.

I think all double math should be optional. As Hugh said, defined but optional.
As I said before, I didn't know how to define my single cell numeric output words. So I didn't renamed at all and use <# # #> but this breaks the compatibility.

I think it's better to just don't have some words at all (even if they are CORE in the standard) than having standard names with non-standard behaviour.

bruce.m...@gmail.com

unread,
Jul 13, 2014, 2:12:29 AM7/13/14
to
On Sunday, July 13, 2014 12:56:23 AM UTC-4, Raimond Dragomir wrote:
> Some early conclusions:

> - Pictured numeric output:
> <# U# U#S U#> for single
> <# # #S #> for double

> If you look at these a cleaner naming would be:

> <# # #S #> for single
> <# D# D#S D#> for double

> But it's too late for this I think

Something like 40 years too late ... de facto and informal standards had already evolved around the state of the art when embedded programming was dominated by 16 bit address space processors. I think the single line % for single cell and doubled line # for double cell is a bit evocative, but better to go with existing practice.

> FM/MOD: Not clear. I'm glad I don't need it.
But remember that the "M" in SM/REM means "mixed", since its:
SM/REM ( d1 n2 -- n2 n3 )

... so if you are going to have single cell division alone, and its going to be symmetric, call it /MOD, and document that its symmetric.

If you want to claim the system is a Forth94 system, it needs to have FM/MOD and SM/REM, if only in included source, but there's certainly nothing wrong with omitting those if you only wish to be "aligned" with Forth94 (as with eForth ... is it v2.0? or v3.0? I can't recall off the top of my head).

> I think all double math should be optional. As Hugh said, defined but optional.

It is optional for it to be included in the binary of a Forth94 system. And its optional whether you want to make a system a Forth94 system, for which you would have to at least provide it in source. So, for all real world intents and purposes, its optional.

> I think it's better to just don't have some words at all (even if they are CORE in the standard) than having standard names with non-standard behaviour.

Yes. Source that assumes a word is present failing, because the word is not found is an early fail, and quite explicit:
FM/MOD ?

... and you can work out whether you can write around the absence of the word or not.

If you have source that is written to be cross-platform but it works within the range of /MOD then whether or not a /MOD that is really ``/REM'' is more likely to require some thinking than the fact that you have to change 2>R and 2SWAP to >R and SWAP.

Albert van der Horst

unread,
Jul 13, 2014, 5:31:49 AM7/13/14
to
In article <04c46e11-aca2-4c6c...@googlegroups.com>,
<bruce.m...@gmail.com> wrote:
<SNIP>
>
>How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't
>know off the top of my head, but I can't imagine it would be as hard as
>writing UM/MOD in assembler, so I guess if I was pressed, I'd work it
>out.

Doing UM/MOD in assembler is fairly straightforward, while the
jumbling of U/MOD 's parameters makes your head spin.
(Of course if you don't have any familiarity with the machine it is
different. A Forth implementor probably has.)

One emulates the long division. Dividing 2n bits by n bits giving
a quotient and remainder of n bits is natural.

The basic idea is to work on the m.s. word while
shifting the l.s. word and m.s. word together.
Then there is a mask, representing the bit to be set in the quotient.
It starts at the m.s. bit, is shifted right and if it runs out, the
loop is over. The remainder is at a variable place, but ends up in
the m.s. word.

You actually need one bit more for the unsigned subtracting, be it a
carry or on the DEC Alpha an extra register. It doesn't play a role
in the subtracting itself, only to decide whether to subtract.

If you subtract, you also set the mask in the quotient.

That's about it. With some help of m4, I find my DEC Alpha version
quite readable.

Groetjes Albert
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Albert van der Horst

unread,
Jul 13, 2014, 6:42:27 AM7/13/14
to
In article <67a7fe7a-48e4-4d76...@googlegroups.com>,
Raimond Dragomir <raimond....@gmail.com> wrote:
>Some early conclusions:
>
>- Pictured numeric output:
><# U# U#S U#> for single
><# # #S #> for double
>
>If you look at these a cleaner naming would be:
><# # #S #> for single
><# D# D#S D#> for double
>But it's too late for this I think

What we still can do is to introduce those words, and make
# #S #> obsolescent.

The U words can be used for signed numbers, which is a bit
strange.

My exercise with yourforth has learned me that
in order to be able to print an unsigned 32 bit, you
still need 64 by 32 bit division. (or dedicated unsigned operators).
FM/MOD (on Intel SM/REM) and M* are still the primitives of choice for
very simple systems with no regard for efficiency.

>
>FM/MOD: Not clear. I'm glad I don't need it.

Actually it is the most simple operation.
When you were in school, you multiplied two 3 digit numbers, and got
a 6 digit number, and were quite used to it.

In computers there is the abstraction that a register holds numbers
of indefinite size.

>
>I think all double math should be optional. As Hugh said, defined but optional.
>As I said before, I didn't know how to define my single cell numeric
>output words. So I didn't renamed at all and use <# # #> but this breaks
>the compatibility.

Agreed but note that unsigned math presents the same kind of problems.
Even on 64 bit systems negative addresses don't want to go away.

>
>I think it's better to just don't have some words at all (even if they
>are CORE in the standard) than having standard names with non-standard
>behaviour.
>

Who wouldn't agree with you? Still I'm guilty of cutting a corner
here and there.

Bernd Paysan

unread,
Jul 13, 2014, 7:54:23 AM7/13/14
to
Albert van der Horst wrote:

> In article <67a7fe7a-48e4-4d76...@googlegroups.com>,
> Raimond Dragomir <raimond....@gmail.com> wrote:
>>Some early conclusions:
>>
>>- Pictured numeric output:
>><# U# U#S U#> for single
>><# # #S #> for double
>>
>>If you look at these a cleaner naming would be:
>><# # #S #> for single
>><# D# D#S D#> for double
>>But it's too late for this I think
>
> What we still can do is to introduce those words, and make
> # #S #> obsolescent.
>
> The U words can be used for signed numbers, which is a bit
> strange.

Actuall, not. If you want to convert a signed number, you need to do

dup abs <# u#s swap sign u#>

Just like with #s, which also needs

tuck dabs <# #s rot sign #>

for signed input.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

bruce.m...@gmail.com

unread,
Jul 13, 2014, 10:02:54 AM7/13/14
to
On Sunday, July 13, 2014 5:31:49 AM UTC-4, Albert van der Horst wrote:
> In article <04c46e11-aca2-4c6c...@googlegroups.com>,
> BruceMcF wrote:
> <SNIP>
> >
> >How to write a UM/MOD out of an ``U/MOD ( u1 u2 -- u3 u4 )'', I don't
> >know off the top of my head, but I can't imagine it would be as hard as
> >writing UM/MOD in assembler, so I guess if I was pressed, I'd work it
> >out.
>
> Doing UM/MOD in assembler is fairly straightforward, while the
> jumbling of U/MOD 's parameters makes your head spin.
> (Of course if you don't have any familiarity with the machine it is
> different. A Forth implementor probably has.)

But the context of the comment was an implementor *not* including UM/MOD *in any form*, with the user left to their own devices to implement it. When I am writing in the first person there, it is with respect to a Forth user who emphatically has no familiarity with any of these machines at assembly language level. The last assembly language I learned was the Z80, when I got my Geneva to take with me to Grenada to teach secondary school Maths.

If I was pressed to adapt for a source base that used UM/MOD, and an eForth style division was not sufficiently fast, having to learn the processor's Forth-style assembler and adapting some existing routine from the standard assembler to Forth-style assembler would typically mean I would put that implementation in the "too hard to use" pile.

Raimond Dragomir

unread,
Jul 13, 2014, 12:35:42 PM7/13/14
to
> But the context of the comment was an implementor *not* including UM/MOD *in any form*, with the user left to their own devices to implement it. When I am writing in the first person there, it is with respect to a Forth user who emphatically has no familiarity with any of these machines at assembly language level. The last assembly language I learned was the Z80, when I got my Geneva to take with me to Grenada to teach secondary school Maths.
>
>
I'm talking about a 32bit system not providing doubles in any form, and a user not needing them either.
Think of an 32bit system on an 8bit microcontroller. AVR can do it resonably well, some newer 8051's also.
But no 64bit math (or mixed 32/64).
If the user finds that it needs the 64bit operations, it's the wrong microcontroller choice in the first place. Go back and take an usual cortex-m mcu and you are done.

bruce.m...@gmail.com

unread,
Jul 13, 2014, 12:57:33 PM7/13/14
to
So, to summarize ...

On Thursday, July 10, 2014 5:35:12 AM UTC-4, Raimond Dragomir wrote:

> ANS maps quite good for a 16bit system, and that's normal. But the compatibility between 16bit and 32bit adds a big overhead for a 32bit system.

So Forth94 "aligned", "sub-CORE" cross-implementation wordsets.

> Here are two sensible areas:

> 1. picture numeric output.

<# U# SIGN U#S U#> implemented in both, <# # SIGN #S #> reserved names in the 32bit, implemented in the 16bit.

> 2. FM/MOD, SM/REM and mixed precision math.
> Also, why having both FM/MOD and SM/REM? ...

Because when they are needed they are necessary, but:

Forth94 /MOD implemented, symmetric or floored at the implementers option (as in Fort94) ... you just need to do a signed ``/'' with a 0 result for one and a -1 result for the other to flag which one it is ... and:

* U/MOD implemented in both, UM/MOD implemented in the 16bit.
* S*/ S*/MOD implemented in both, */ */MOD implemented in the 16bit.
* S>NUMBER implemented in both, >NUMBER implemented in the 16bit
* SM/REM, FM/MOD, S/REM, and F/MOD reserved names in both, and words not implemented in the 32bit required in the 16bit are reserved names.

> A "Forth16e" standard for 16bit embedded systems is quite close to the ANS if not almost it. I think not much is to discuss about it. 200x standard even had done a good step in recognizing that double cells of any kind may not even be found in severely constrained 16bit systems.

> A "Forth32e" standard for 32bit embedded systems has some problems with the ANS standard. It may be already 90-95% of the ANS, maybe. It's the most interesting one to talk about.

Two load constants, in 16bit, Forth16e TRUE, Forth32e FALSE, visa versa in 32bit.

QUESTIONS:
Flash issues: CREATE DOES> IMMEDIATE

Pair operations: I use these heavily for non-double operations: 2@ 2DUP 2DROP 2OVER 2SWAP 2>R 2R> 2R@ but I'm not an implementer, so its a question of what the implementer(s) of the de facto standard wish to implement.

DO-LOOPS: some minimal system implementers skip DO-LOOPS and rely on FOR-NEXT instead. Another one determined by what the implementer(s) elect to implement.

ENVIRONMENT? ~ the implementer may prefer to specify specific system constants to cover the range of distinct features that may have to be accounted for.

WORD/FIND ~ the implementer may wish to specify a pair that does not require a buffer in addition to the console input buffer.

Setting those aside implies that both Forth16e and Forth32e implementations include CORE:

! ' ( * + +! , - . ." / /MOD 0< 0= 1+ 1- 2! 2* 2/ : ; < = > >BODY >IN >NUMER >R ?DUP @ ABORT ABS ACCEPT ALIGN ALIGNED ALLOT AND BASE BEGIN BL C! C@ CELL+ CELLS CHAR CHAR+ CHARS CONSTANT COUNT CR DECIMAL DROP DUP ELSE EMIT EVALUATE EXECUTE EXIT FILL HERE HOLD IF INVERT KEY LITERAL LSHIFT MAX MIN MOD MOVE NEGATE OR OVER POSTPONE QUIT R> R@ RECURSE REPEAT ROT RSHIFT S" SIGN SOURCE SPACE SPACES STATE SWAP THEN TYPE U. U< UNTIL VARIABLE WHILE XOR [ ['] [CHAR] ]

I would suggest that including [DEFINED] and [UNDEFINED] as well as a word to conditionally interpret the rest of the line, perhaps:
\ ?\ ( fl <...EOL>|<> -- ) IMMEDIATE ~ if fl is TRUE, skip the rest of the line

... can go a long way in simple conditional compilation tasks if, eg, streaming a source to a Forth console interpreter over some sort of serial link.

bruce.m...@gmail.com

unread,
Jul 13, 2014, 1:02:47 PM7/13/14
to
On Sunday, July 13, 2014 12:35:42 PM UTC-4, Raimond Dragomir wrote:
> I'm talking about a 32bit system not providing doubles in any form, and a user not needing them either.

There is likely to be more unpredictability about what a future user may or may not need when laying out a set of words to be assumed in shared source than when an implementer is also the sole user of the system.

Andrew Haley

unread,
Jul 13, 2014, 1:18:19 PM7/13/14
to
Raimond Dragomir <raimond....@gmail.com> wrote:
>>
> I'm talking about a 32bit system not providing doubles in any form,
> and a user not needing them either. Think of an 32bit system on an
> 8bit microcontroller. AVR can do it resonably well, some newer
> 8051's also.

I don't really understand this. What is a 32-bit Forth on an 8051
for? Even addition is going to be painful 8 bits at a time, and
there's no need for 64-bit addressing. A 16-bit Forth with mixed-
precision arithmetic is surely a better fit.

Andrew.

Raimond Dragomir

unread,
Jul 13, 2014, 1:45:15 PM7/13/14
to
For me is a simpler, cleaner system, with fewer words. For 16bit addresses I have PUSH and POP if I wanted the addresses on the return stack. >R and the like cannot be used when you really want the return addresses.
The 32bit forth system is for big applications, which you still can do with an 8051.
For small applications you may find even the 16bit system be an overkill. I had done many small aplications on the 8051 that barely had one or two 16bit variables. The rest were all 8bits. An 8bit forth system with 16bit double numbers would had been just perfect!

Elizabeth D. Rather

unread,
Jul 13, 2014, 2:02:34 PM7/13/14
to
Having actually worked on a 32-bit Forth on 8051's (for a special
project) I completely agree with Andrew. Why penalize absolutely
everything you do (most of which doesn't require 32 bits)? If you write
sensible application code (using the CELL words for address manipulation
as appropriate, etc.) there is very little difficulty in porting
application code between 16-bit and 32-bit Forths.

Elizabeth D. Rather

unread,
Jul 13, 2014, 2:06:27 PM7/13/14
to
An 8-bit Forth has severe limitations for things like loop indices, and
it's a royal pain to treat addresses (2 bytes) differently from other
stack items.

Yes, 8-bit variables are good, which is why we use CVARIANLE, C@, C!
etc. But for the rest of your computing needs, a simple 16-bit
implementation works great with minimal overhead.

Matthias Koch

unread,
Jul 14, 2014, 9:50:59 AM7/14/14
to
Hi Andrew, Hi Gerry, thank you for pointing me to this ! Matthias

bruce.m...@gmail.com

unread,
Jul 14, 2014, 8:32:47 PM7/14/14
to
On Friday, July 11, 2014 6:30:56 AM UTC-4, Matthias Koch wrote:
> For standalone embedded systems offering direct compilation into "large paged" Flash memory as in STM32F407 a CREATE with unchangeable default action and an old style <BUILDS DOES> that cannot be redefined multiple times solve the issue.

... though under some distinctive names, like:

<ACTOR ... ACTION>

... given that an effective means of guarding against an attempt to use a source that does a redefining CREATE ... DOES> is to issue a warning for DOES> used by the source.

> The second issue is collecting the Flags. ANS defines IMMEDIATE which can be placed outside of a definition, but as I am having additional flags for inlining, foldability, instruction set optimisations, compile-only and RAM-allocation, I need to bundle them together somehow before the flag field can be written (one time). Having the flags inside of the definition is a great help.

... so a semantic like:

: <name> ... ;[ IMM COMP-ONLY OPIMIZE <etc> ... ];

where:

;[ ( compilingg: -- word-status-id )
complete the compilation of the current definition, enter interpretation state, place on the stack the word-status-id of the default word status.

]; ( word-status-id -- )
enter the most recent definition into the dictionary with the status indicated by word-status-id on the top of stack.

... and a bunch of, ``IMM ( word-status-id1 -- word-status-id2 )''

... where, again, ``IMMEDIATE'' can give a warning.

jacko

unread,
Jul 15, 2014, 8:15:51 AM7/15/14
to
On Thursday, 10 July 2014 20:53:42 UTC+1, Albert van der Horst wrote:
>
> I'm very happy with all those double precision words for number
>
> theoretical applications (read projecteuler.net )
>

Certainly very useful in this arena. one of the reasons I added Q/ and Q* to a forth I was writing at the time but have not developed to working.

hughag...@yahoo.com

unread,
Jul 16, 2014, 1:18:05 AM7/16/14
to
This was discussed way back in 2009 when I was implementing the continued fraction code:
https://groups.google.com/forum/#!topic/comp.lang.forth/BcWvGxFFuzA%5B1-25-false%5D

This thread was actually my very first contact with the dynamic duo of Elizabeth Rather and John Passaniti (I didn't know that Passaniti was homosexual at the time, but he would burst out of the closet later on in this thread). Elizabeth Rather and I had this exchange:

On Friday, November 20, 2009 12:07:12 AM UTC-7, Elizabeth D Rather wrote:
> Hugh Aguilar wrote:
> ...
> > The problem is the ANS-Forth standard. Really, how obvious was the
> > need for double-precision arithmetic? This could have been an
> > extension to the language similar to floating-point. Compiler-writers
> > working on small microprocessors could decline to implement it if they
> > didn't want to.
> >
> > I am frustrated with the ANS-Forth standard because I believe that the
> > bad design of the standard is the #1 reason for the failure of Forth
> > to become an important language. Forth was doing pretty well in the
> > 1980s, but we needed a standard. What we got was Forth-83, and then
> > ANS-Forth-94, both of which were badly designed. With some more
> > thoughtful leadership we could have succeeded.

> There are D+, D-, M*, M/, and M*/ (and the unsigned operators). These
> were adequate in a very wide variety of projects over a 30 year period,
> many of which were extremely computation-intensive and running on slow
> 16-bit processors.
>
> Forth's design is pragmatic: it has functions that have been needed and
> that have proven their usefulness *in Forth*, not necessarily those that
> have been required in other languages. Generally speaking, Forth has
> the most flexible set of *integer* arithmetic operators of any language.
> In particular, M*/ was one of Chuck's most brilliant innovations. I'm
> sure if Chuck were trying to do your continued fractions that is what he
> would rely on. Yes, that sometimes requires thinking differently, like
> many other things in Forth.
>
> Cheers,
> Elizabeth

I think that it is pretty obvious that the reason why ANS-Forth doesn't have D/ is because nobody at Forth Inc. could figure out how to implement it.

Note that Elizabeth Rather doesn't tell me how to implement my continued fraction program using M*/ --- she just says that Chuck Moore is brilliant and would be able to do so somehow --- in all likelihood, she doesn't know what continued fractions are. I ended up implementing D/ myself in high-level Forth in order to get the continued fraction program to work --- I haven't the slightest idea how to get this program to work with M*/ --- I'm not brilliant at all!

Raimond Dragomir

unread,
Jul 16, 2014, 3:01:50 AM7/16/14
to
> > > The problem is the ANS-Forth standard. Really, how obvious was the
>
> > > need for double-precision arithmetic? This could have been an
>
> > > extension to the language similar to floating-point. Compiler-writers
>
> > > working on small microprocessors could decline to implement it if they
>
> > > didn't want to.
>
Exactly.
I will concentrate on cortex-m microcontrollers (m0, m3, m4) but even so I don't like the 64bit math, because I just don't need it. But a 32bit system is usefull for smaller microcontrollers also. Even that noone seems to agree this for an 8051 or avr (avr is quite decent though) I can think of elegant implementations for MSP430 or PIC24 which are 16bitters.

Anyway, forth has this single cell/double cell "compatibility" kind of view, which is nice, but not all the time.
C had, and still has the same kind of thing regarding the "int". The "int" may be 16bit or 32bit, depending on the cpu architecture. The compiler writer choose this by design, in an obvious way.
But C does recognize the need of specifying the size of objects directly. That's why it has int8_t, int16_t, int32_t, int64_t and the unsigned uint... etc, even that this is done with some defines or typedefs.
However, almost all c programmers have personal preferences and don't use the <std> types... They instead use u16, u32, U08, BYTE, WORD or god knows what else...

The idea is: sometimes you need an "int", a forth "cell". You don't care what the size is because you really know it is enough (a small index, or other variable) and you want it to be the most easy thing the system can deal with.
But many times you need specific sizes. For example, I have an application with large tables of 16bit values. I choose the 16bit value despite the cpu being 32bit, because it saved me lot of ram. That brings me the real need of having half cells in my 32bit forth, H@, H!.

The point is: Using (only) the terms "single" and "double" "cell" for portability is not enough in itself without the direct size specifiers.
Now I'm having H@ H! for my 32bit forth, but these are just not possible in a 16bit forth. Also, for "doubles", if I use doubles in a 16bit systems, those will compile as 64bit objects in a 32bit forth system.

People using doubles in the 16bit forths are using them because they need 32bits. Why forcing them to use 64bits in a 32bit forth system? People do not need "doubles". They need specific sizes that cover their needs, and use the double because this is what they have at hand. It is used with care anyway.

Well, long story for quite a short subject. CELL compatibility is needed, and a good to have. For forth is almost a must because of the stacks. But it must stop here. "Doubles" shouldn't exist. Along with CELL, it must exists byte/char/int8, in16, int32, int64 or any better names you can find for forth. They will use N CELLS of stack each and this is a problem of documenting the system (ENVIRONMENT? queries)

hughag...@yahoo.com

unread,
Jul 16, 2014, 9:25:29 PM7/16/14
to
On Wednesday, July 16, 2014 12:01:50 AM UTC-7, Raimond Dragomir wrote:
> The idea is: sometimes you need an "int", a forth "cell". You don't care what the size is because you really know it is enough (a small index, or other variable) and you want it to be the most easy thing the system can deal with.

Agreed. You may need "at least" 16-bits for an index or whatever. This doesn't mean that you necessarily want a 16-bit though --- on most 32-bit processors, using a 16-bit register is slower than using a 32-bit register --- for stuff like this, you are best off to use the "natural" size.

> But many times you need specific sizes. For example, I have an application with large tables of 16bit values. I choose the 16bit value despite the cpu being 32bit, because it saved me lot of ram. That brings me the real need of having half cells in my 32bit forth, H@, H!.

Agreed. The size of the data is inherent in the data --- it is irrelevant whether the processor is 16-bit or 32-bit. You should be able to port a program from a 16-bit processor to a 32-bit processor without your memory usage doubling for no point. This can be an issue when you have a huge amount of data.

With my language, I have abandoned the ANS-Forth idea of the language running on any size of processor. I require a 64-bit processor.

I actually have two languages. HostForth is 64-bit and runs on desktop computers. TargForth is a cross-compiler written in HostForth that targets micro-controllers. These may be 16-bit or 32-bit. HostForth and TargForth are not compatible --- it is unrealistic to expect the same language to run on a big desktop computer and a little micro-controller --- the environments are just too different.

I will give some thought to your suggestions in regard to TargForth so that programs can easily be ported between 16-bit and 32-bit micro-controllers. This discussion isn't relevant to HostForth however, because it is fixed at 64-bit.

bruce.m...@gmail.com

unread,
Jul 16, 2014, 11:51:37 PM7/16/14
to
On Wednesday, July 16, 2014 3:01:50 AM UTC-4, Raimond Dragomir wrote:

> I will concentrate on cortex-m microcontrollers (m0, m3, m4) but even so I don't like the 64bit math, because I just don't need it. But a 32bit system is usefull for smaller microcontrollers also. Even that noone seems to agree this for an 8051 or avr (avr is quite decent though) I can think of elegant implementations for MSP430 or PIC24 which are 16bitters.

It seems rather that whatever you are viewing as elegant, most prefer their Forth to map more closely to their processor. And then, under that preference, the double is not as striking an issue, since they have not defined all of their single cells operations to work on double processor words, so their double operations are double processor word operations, not quadruple processor word operations.

> Anyway, forth has this single cell/double cell "compatibility" kind of view, which is nice, but not all the time.

> But C does recognize the need of specifying the size of objects directly. That's why it has int8_t, int16_t, int32_t, int64_t and the unsigned uint... etc, even that this is done with some defines or typedefs.
Yes, as Forth systems have normally done, though with the flexibility of Forth those have been more commonly target specific words than abstract sizes.

> The idea is: sometimes you need an "int", a forth "cell". You don't care what the size is because you really know it is enough (a small index, or other variable) and you want it to be the most easy thing the system can deal with.

> But many times you need specific sizes. For example, I have an application with large tables of 16bit values. I choose the 16bit value despite the cpu being 32bit, because it saved me lot of ram. That brings me the real need of having half cells in my 32bit forth, H@, H!.

Yes, that is the normal Forth approach to that situation. There is a complete Forth200x proposal reserving a whole bucket of word size and big endian / little endian names, along those lines.

> The point is: Using (only) the terms "single" and "double" "cell" for portability is not enough in itself without the direct size specifiers.
It depends on portability to what. Having the direct size specifiers are not sufficient for portability either, since there is still big v little endian, compacted versus aligned, and so on.

> Now I'm having H@ H! for my 32bit forth, but these are just not possible in a 16bit forth.
But if you define unsigned 16s as "W"s, and name them W@ W!, they are possible whether in 16, 18, 20, 32, or 64 bits. And if 16 bits of unsigned range is sufficient for that algorithm, it will work on any of those.

> Also, for "doubles", if I use doubles in a 16bit systems, those will compile as 64bit objects in a 32bit forth system.

Which is precisely what many people who would only use a 32bit Forth on a 32bit processor would wish to have happen.

> People using doubles in the 16bit forths are using them because they need 32bits. Why forcing them to use 64bits in a 32bit forth system?

But as we have seen in the discussion, this is only partly true. People use 64bits intermediate product in a 32bit */ for largely the same reason they use a 32bit intermediate product in a 16bit */ ... because that is the natural range of a 32 bit multiply. If you don't WANT the intermediate product to be 64 bits, you can always do * and / in succession in the process clip the range, and still have */ for any occasion where you do not want to risk clipping the range.

> People do not need "doubles". They need specific sizes that cover their needs, and use the double because this is what they have at hand. It is used with care anyway.

You seem to enjoy double word operations so much that you have written Forth systems for 16bit word processors in which every operand is a double word. That implies you feel you can do without the single word operations.

And if your stack cells are already intrinsically double words, it makes sense for efficiency's sake, to dispense with doubling it up again, so you'd only need double operations for paired-cell operations, like:
: PARSE-NAME ( -- ca u ) in$ ws-skip 2DUP ws-scan chop 2SWAP >in$ ;

> Well, long story for quite a short subject. CELL compatibility is needed, and a good to have. For forth is almost a must because of the stacks. But it must stop here. "Doubles" shouldn't exist.

You were aiming to arrive at this conclusion, and so along the way made assertions about what "people need" which seem more to be what you find you need after you have baked double word operations into every single cell operation.

> Along with CELL, it must exists byte/char/int8, in16, int32, int64 or any better names you can find for forth.

For accessing specific hardware and for writing specific externally-defined data formats, certainly. But there are certain intrinsic relationships that followed from integer arithmetic, including the fact that for a cell size of 2^n bits, the intrinsic range of unsigned multiplication is 2^[2n] bits. While there may be a manner of elegance in carrying around those extra n bits all the time in order to avoid the inelegance of mixed size operations, there is also a different manner of elegance in tuning the cell size to the word size of the processor and only availing of those extra n bits when required.

Virtually,

@BruceMcF

Alexander Skobelev

unread,
Jul 17, 2014, 2:21:48 AM7/17/14
to
hughag...@yahoo.com writes:

> [...]
> With my language, I have abandoned the ANS-Forth idea of the language
> running on any size of processor. I require a 64-bit processor.
>
> I actually have two languages. HostForth is 64-bit and runs on desktop
> computers. TargForth is a cross-compiler written in HostForth that
> targets micro-controllers. These may be 16-bit or 32-bit. HostForth
> and TargForth are not compatible --- it is unrealistic to expect the
> same language to run on a big desktop computer and a little
> micro-controller --- the environments are just too different.
>
> I will give some thought to your suggestions in regard to TargForth so
> that programs can easily be ported between 16-bit and 32-bit
> micro-controllers. This discussion isn't relevant to HostForth
> however, because it is fixed at 64-bit.

I don't understand and just wonder if your language supposed to be used
for writing programs for PCs or only for micro-controllers? And if so,
do I've got it properly that in this case one can do it with only
HostForth without TargForth? (Or how to write programs for 64-bit
platforms?) I ask you about this because, if my memory serves me well,
somewhere earlier you wrote that HostForth is sort of low-lewel language
intended to host languages for the target platforms.

Raimond Dragomir

unread,
Jul 17, 2014, 3:32:46 AM7/17/14
to
> I will give some thought to your suggestions in regard to TargForth so that programs can easily be ported between 16-bit and 32-bit micro-controllers. This discussion isn't relevant to HostForth however, because it is fixed at 64-bit.

Maybe you would be dissapointed. I gave up the idea long time ago. That's why I have 32bit forth systems in place of otherwise normal 16bit systems.
Forth cannot hide the size for operators, do you cannot have a "+" that work on single cells or double cells.

But I thought that at least the data size in declarations to be "portable". Also, in my "32bit forths that should be 16bit forths" some kind of optimized 16bit operators may be an idea. For example, having a "H+" for 16bit add will save some cycles on the 8bit/16bit cpu, and on a 32bit cpu will be just aliased to "+". But I'm afraid is a step back, because my elegant 32bit forth will become a mess of half-cell and cell operators, likewise the 16bit forths are a mess of single and double-cell operators.

16bit forths and 32bit forths compatibility in forth is a dream. In a 16bit forth even if you have a "portable" 32bit data variable, fetching it will take two cells instead of one for 32bit forth, and it's all over.

By the way, why do you say your host should be 64bit? Do you require intel host processors that supports 64bit? And you kinda do what I'm doing for my embedded 32bit systems ? :) Meaning you just double it from the start, and don't want to support mixed sizes 32bit/64bit ?

Raimond Dragomir

unread,
Jul 17, 2014, 3:36:02 AM7/17/14
to

> By the way, why do you say your host should be 64bit? Do you require intel host processors that supports 64bit? And you kinda do what I'm doing for my embedded 32bit systems ? :) Meaning you just double it from the start, and don't want to support mixed sizes 32bit/64bit ?

Or you want to support 128 bit doubles ? :-O

Elizabeth D. Rather

unread,
Jul 17, 2014, 4:55:33 AM7/17/14
to
On 7/16/14 9:32 PM, Raimond Dragomir wrote:
>> I will give some thought to your suggestions in regard to TargForth so that programs can easily be ported between 16-bit and 32-bit micro-controllers. This discussion isn't relevant to HostForth however, because it is fixed at 64-bit.
>
> Maybe you would be dissapointed. I gave up the idea long time ago. That's why I have 32bit forth systems in place of otherwise normal 16bit systems.
> Forth cannot hide the size for operators, do you cannot have a "+" that work on single cells or double cells.

There was a time when, on 32-bit Forths, we had operators like H@/H! to
access half-cells (in addition, of course, to B@/B! for bytes). However,
we never really saw a need for different arithmetic operators other that
the single-cell, double-cell, and mixed operators in the standards.

> But I thought that at least the data size in declarations to be "portable". Also, in my "32bit forths that should be 16bit forths" some kind of optimized 16bit operators may be an idea. For example, having a "H+" for 16bit add will save some cycles on the 8bit/16bit cpu, and on a 32bit cpu will be just aliased to "+". But I'm afraid is a step back, because my elegant 32bit forth will become a mess of half-cell and cell operators, likewise the 16bit forths are a mess of single and double-cell operators.
>
> 16bit forths and 32bit forths compatibility in forth is a dream. In a 16bit forth even if you have a "portable" 32bit data variable, fetching it will take two cells instead of one for 32bit forth, and it's all over.

Really, it is not a dream! It is entirely practical. We have worked that
way for almost 30 years, through may versions of systems and many
complex applications.

> By the way, why do you say your host should be 64bit? Do you require intel host processors that supports 64bit? And you kinda do what I'm doing for my embedded 32bit systems ? :) Meaning you just double it from the start, and don't want to support mixed sizes 32bit/64bit ?
>

Good question. I really see no need for a 64-bit host.

Anton Ertl

unread,
Jul 17, 2014, 6:16:40 AM7/17/14
to
Raimond Dragomir <raimond....@gmail.com> writes:
>16bit forths and 32bit forths compatibility in forth is a dream. In a 16bit=
> forth even if you have a "portable" 32bit data variable, fetching it will =
>take two cells instead of one for 32bit forth, and it's all over.

Just have a DL@ ( addr -- d ) or maybe UDL@ ( addr -- ud ) that
accesses 32 bits. You can implement that on 16-bit systems, 32-bit
systems and 64-bit systems.

My experience is that Forth portability between 32-bit and 64-bit
platforms works very well (better than C portability); I don't see a
reason why a program should not be portable from a 16-bit system to a
32-bit system (the other way round can be harder, if the 32-bit system
supports more words and the program uses these words).

> Meaning you just double it from the start, and=
> don't want to support mixed sizes 32bit/64bit ?

Gforth on 32-bit platforms has 32-bit cells and 64-bit doubles; Gforth
on 64-bit platforms has 64-bit cells and 128-bit doubles.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2014: http://www.euroforth.org/ef14/

hughag...@yahoo.com

unread,
Jul 17, 2014, 6:56:19 PM7/17/14
to
On Wednesday, July 16, 2014 11:21:48 PM UTC-7, Alexander Skobelev wrote:
> hughag...@yahoo.com writes:
> > With my language, I have abandoned the ANS-Forth idea of the language
> > running on any size of processor. I require a 64-bit processor.
>
> > I actually have two languages. HostForth is 64-bit and runs on desktop
> > computers. TargForth is a cross-compiler written in HostForth that
> > targets micro-controllers. These may be 16-bit or 32-bit. HostForth
> > and TargForth are not compatible --- it is unrealistic to expect the
> > same language to run on a big desktop computer and a little
> > micro-controller --- the environments are just too different.

> I don't understand and just wonder if your language supposed to be used
> for writing programs for PCs or only for micro-controllers? And if so,
> do I've got it properly that in this case one can do it with only
> HostForth without TargForth? (Or how to write programs for 64-bit
> platforms?) I ask you about this because, if my memory serves me well,
> somewhere earlier you wrote that HostForth is sort of low-lewel language
> intended to host languages for the target platforms.

My language is primarily for micro-controllers. The user writes his program in TargForth, which is a cross-compiler targeting whatever micro-controller he is using. TargForth is written in HostForth, and HostForth is a pretty-much-traditional stand-alone Forth system.

Novice-level users don't have to learn HostForth at all; they can write applications in TargForth without knowing how TargForth is implemented (it is written in HostForth). Intermediate-level users (those who write meta-compiling code) will have to learn enough HostForth to write their compile-time code. Advanced-level users (those who want to upgrade TargForth to a new micro-controller) will have to learn HostForth thoroughly so they can upgrade TargForth for a new target (TargForth is a large program written in HostForth).

For the most part, I'm not planning on supporting development of desktop-computer software. It is possible to write desktop-computer software in HostForth however. I myself will write a CAM program in HostForth (CAM means: Computer-Aided-Manufacture; this is generating gcode for CNC machines). I have no interest in internet server stuff, which is what most of the world uses desktop-computers for --- and there are already myriad dynamic-OOP languages available for this. I will most likely have a "sister language," which will be either Factor or one of the Scheme systems, and I will encourage people to write desktop-computer utility programs in it rather than HostForth, so I don't get bogged down writing wrappers for a lot of desktop-computer libraries that I don't understand very well and have little or no interest in. For my own part, I want to concentrate on writing TargForth versions in HostForth, and writing my own CAM software in HostForth --- the two subjects that I am reasonably knowledgeable in (unlike the typical Forth-200x committee member, I don't pretend to be an expert on everything).

hughag...@yahoo.com

unread,
Jul 17, 2014, 7:13:23 PM7/17/14
to
On Thursday, July 17, 2014 3:16:40 AM UTC-7, Anton Ertl wrote:
> My experience is that Forth portability between 32-bit and 64-bit
> platforms works very well (better than C portability); I don't see a
> reason why a program should not be portable from a 16-bit system to a
> 32-bit system (the other way round can be harder, if the 32-bit system
> supports more words and the program uses these words).

Porting from a 16-bit system to a 32-bit system is easy if you are willing to double your memory usage (every datum that had previously occupied two bytes now occupies four bytes), which I already described as being problematic (a 32-bit processor doesn't necessarily have more memory than a 16-bit processor).

Difficulty occurs when a program's data is naturally 32-bit (the +-32KB range of a 16-bit integer is pretty restrictive, and a lot of times you just need the +-2GB range of 32-bit numbers), but the processor is 16-bit. There are two solutions. The first solution is to write the program in a 16-bit Forth, but use double-precision integers for the data. This can make for some rather cumbersome code. The second solution is to use a 32-bit Forth on the 16-bit processor, and use single-precision integers for the data. The latter solution is what Raimond is advocating, and I agree with him that this makes the user's job easier. The compiler-writer's job is harder, because he has to write a 32-bit cross-compiler for a 16-bit processor, that is has likely already written a 16-bit cross-compiler for --- but the cross-compiler writer is likely to be me, and I don't mind extra work so long as I'm getting paid --- if the user wants a 32-bit cross-compiler for a 16-bit processor because it makes his life easier, and he is willing to pay for it, then why not?

hughag...@yahoo.com

unread,
Jul 17, 2014, 7:34:46 PM7/17/14
to
On Thursday, July 17, 2014 1:55:33 AM UTC-7, Elizabeth D. Rather wrote:
> On 7/16/14 9:32 PM, Raimond Dragomir wrote:
> > By the way, why do you say your host should be 64bit? Do you require intel host processors that supports 64bit? And you kinda do what I'm doing for my embedded 32bit systems ? :) Meaning you just double it from the start, and don't want to support mixed sizes 32bit/64bit ?
>
> Good question. I really see no need for a 64-bit host.

I considered making HostForth a 32-bit system. Over on CLAX said that my vision of the future was that 32-bit x86 (typically with multi-cores) would be standard, but that 64-bit x86 would always be an esoteric side-line. Everybody told me that I was wrong --- the future (actually, the present) involves 64-bit x86, and that the future mostly involves multi-core 64-bit systems --- 32-bit systems are largely obsolete. Everybody told me to focus on 64-bit x86 assembly-language and ignore 32-bit x86, even if my data is primarily 32-bit. So I decided, what the heck, I would just make HostForth a 64-bit system --- having 16 rather than 8 registers makes my life a lot easier --- why should I hamstring myself supporting 32-bit x86 when nobody in the real-world (or, at least nobody north of the Rio Grande) has a 32-bit x86 computer?

Also, just by writing HostForth in 64-bit x86 assembly rather than 32-bit x86 assembly, I have taken a big step toward defeating Pelc who is mired in the obsolete 32-bit x86 world. Defeating Forth Inc. is too easy, as SwiftForth is slow as molasses --- defeating MPE is much more difficult --- but it should be possible, especially for programs that deal primarily in 64-bit data. How much fun would that be? A lot! ;-)

hughag...@yahoo.com

unread,
Jul 17, 2014, 7:52:45 PM7/17/14
to
On Thursday, July 17, 2014 12:36:02 AM UTC-7, Raimond Dragomir wrote:
> > By the way, why do you say your host should be 64bit? Do you require intel host processors that supports 64bit? And you kinda do what I'm doing for my embedded 32bit systems ? :) Meaning you just double it from the start, and don't want to support mixed sizes 32bit/64bit ?
>
> Or you want to support 128 bit doubles ? :-O

I will have 128-bit doubles in HostForth. I doubt that anybody other than myself will ever use them.

The primary use for 128-bit doubles, is my continued-fraction program. It is necessary to do the calculation in twice the precision that the end result will be provided in. To get 64-bit rational approximations, I need the program to do 128-bit arithmetic. The user needs 64-bit ratios (because he is programming a 64-bit system), so I have to support 128-bit arithmetic. If the user only needs 32-bit ratios however, then the continued-fraction program can be 64-bit.

All in all, I think that making HostForth 64-bit will simplify a lot of issues --- it could be done in 32-bit, but why hamstring myself? --- WalMart has 64-bit computers for $300, so why should I break my back for the poor devil who doesn't even have the $300 entry fee?

Alexander Skobelev

unread,
Jul 18, 2014, 1:35:25 AM7/18/14
to
OK, I see your point. Thank you for the detailed response.

Stephen Pelc

unread,
Jul 18, 2014, 10:30:34 AM7/18/14
to
On Thu, 17 Jul 2014 16:34:46 -0700 (PDT), hughag...@yahoo.com
wrote:

>Also, just by writing HostForth in 64-bit x86 assembly rather than 32-bit x=
>86 assembly, I have taken a big step toward defeating Pelc who is mired in =
>the obsolete 32-bit x86 world. Defeating Forth Inc. is too easy, as SwiftFo=
>rth is slow as molasses --- defeating MPE is much more difficult --- but it=
> should be possible, especially for programs that deal primarily in 64-bit =
>data. How much fun would that be? A lot! ;-)

It's difficult to argue against your vapourware.

It's certainly true that 64 bit CPUs are good for applications
that use a lot of 64 bit data. Outside the scientific domains
there does not seem to be a great demand for 64 bit data.
We only have one client who can show a need for much better
processing of 64/128 bit data.

Stephen


--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

Anton Ertl

unread,
Jul 18, 2014, 10:40:10 AM7/18/14
to
steph...@mpeforth.com (Stephen Pelc) writes:
>It's certainly true that 64 bit CPUs are good for applications
>that use a lot of 64 bit data. Outside the scientific domains
>there does not seem to be a great demand for 64 bit data.

64-bit CPUs and 64-bit Forth systems are good for applications that
use more data than can be addressed with 32 bits. On the usual OSs
the 32-bit limit is 2-3GB of data.

Alex McDonald

unread,
Jul 18, 2014, 11:05:17 AM7/18/14
to
on 18/07/2014 16:40:13, wrote:
> steph...@mpeforth.com (Stephen Pelc) writes:
>>It's certainly true that 64 bit CPUs are good for applications
>>that use a lot of 64 bit data. Outside the scientific domains
>>there does not seem to be a great demand for 64 bit data.
>
> 64-bit CPUs and 64-bit Forth systems are good for applications that
> use more data than can be addressed with 32 bits. On the usual OSs
> the 32-bit limit is 2-3GB of data.
>
> - anton

The default operand size on x64 in 64 bit mode is 32 bits. Your OS may
use ths mode; Windows does. A long int is 32 bits. Linux and other Unices
seem to be uniformly 64/64.

Anton Ertl

unread,
Jul 18, 2014, 1:26:02 PM7/18/14
to
You seem to be conflating and confusing a number of things.

In the AMD64 architecture (called x64 in the Windows world) there are
8-bit, 16-bit, 32-bit, and 64-bit variants of many instructions (but
addresses are always 64-bit, so, e.g., LEA always produces 64-bit
results). The 16-bit and 64-bit variants of the instructions are
encoded by preprending a prefix to the 32-bit version of the
instruction (8-bit has a bit in the instruction). That is true
whichever OS you are using on AMD64. And while there are many modes
in AMD64, there is only one for 64-bit user-mode programs (the 64-bit
mode), and it has this property. 64-bit programs run in this mode on
any OS.

The other thing is that the C API/ABI for Win64 defines long int to be
32 bits. Apparently that allowed easier porting of Win32 programs to
Win64. That is independent of the architecture (e.g., it is also the
case on IA-64). In any case, this is C stuff and does not really
concern us in Forth (except when we interface to C).. In Forth cells
are as big as adresses, i.e., on Win64 you have 64-bit cells.

Bernd Paysan

unread,
Jul 18, 2014, 6:37:10 PM7/18/14
to
Stephen Pelc wrote:
> It's certainly true that 64 bit CPUs are good for applications
> that use a lot of 64 bit data. Outside the scientific domains
> there does not seem to be a great demand for 64 bit data.
> We only have one client who can show a need for much better
> processing of 64/128 bit data.

The most time consuming part in net2o is Keccak, which I use for symmetric
encryption. It is designed so that it runs perfect on 64 bit CPUs, and
still "good" in 32 bit mode. The speedup of Keccak in 64 bit is more than a
factor 2. Partially, because there are more registers, partially because it
simply can churn 2 times the data.

The other critical operation is Ed25519, an elliptic curve, which is used
for signing and diffie hellman key exchange. The speedup here is even
bigger (would be a factor of more than 4, because Ed25519 is wide
multiplication dominated, but thanks to SSE, it's less than that).

This is all C code, which I access as library, so it's not related to Forth.
This is by far the most time consuming part of net2o (the next biggest is
the Linux kernel passing UDP packets around, which takes nearly as long as
the entire encryption, and a lot longer than the net2o protocol overhead!).

So apart from scientific domains, encryption wants 64 bits, too. So if I
had to choose between Gforth and VFX from a performance point of view, VFX
would accelerate the 20% that is actually spent in Forth code by a factor 2
or more. But of the rest, 50% would slow down by a factor >2, due to the 32
bit limitation.

And we are already having smartphones with 64 bit CPUs out there: iPhone 5s.
Android L supports 64 bits, too, so 64 bit Android phones will come, soon.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

Paul Rubin

unread,
Jul 18, 2014, 7:30:36 PM7/18/14
to
Bernd Paysan <bernd....@gmx.de> writes:
> So apart from scientific domains, encryption wants 64 bits, too.

Anything that shovels a lot of data around does better with 64 bits. I
worked on a search engine for a while, and it was much faster on 64 bit
machines than 32 bits. Also, most floating point computation (not just
for scientific purposes) is probably best done with doubles unless
there's reasonable justification that singles won't cause too much
roundoff error etc. E.g. financial calculations generally use doubles
if they use floating point. For many apps, 23 bits of single precision
mantissa is too little resolution, so small errors can accumulate into
noticable ones.

Bernd Paysan

unread,
Jul 18, 2014, 7:40:43 PM7/18/14
to
The last is a non-issue here, floating points don't become bigger (or double
calculations don't become faster) when you use the 64 bit mode of x86-64.
You can argue that there is no SSE/AVX vectorizer in VFX, though.

Programs with lots of pointers even become slower in 64 bit mode, because
they need twice the memory.

Paul Rubin

unread,
Jul 18, 2014, 8:00:49 PM7/18/14
to
Bernd Paysan <bernd....@gmx.de> writes:
> The last is a non-issue here, floating points don't become bigger (or double
> calculations don't become faster) when you use the 64 bit mode of x86-64.

Well I thought this was also about the Forth cell size. It's nice if
floats and ints fit in the same cells.

hughag...@yahoo.com

unread,
Jul 19, 2014, 1:59:11 AM7/19/14
to
On Friday, July 18, 2014 7:30:34 AM UTC-7, Stephen Pelc wrote:
> On Thu, 17 Jul 2014 16:34:46 -0700 (PDT), hughag...@yahoo.com
> >Also, just by writing HostForth in 64-bit x86 assembly rather than 32-bit x=
> >86 assembly, I have taken a big step toward defeating Pelc who is mired in =
> >the obsolete 32-bit x86 world. Defeating Forth Inc. is too easy, as SwiftFo=
> >rth is slow as molasses --- defeating MPE is much more difficult --- but it=
> > should be possible, especially for programs that deal primarily in 64-bit =
> >data. How much fun would that be? A lot! ;-)

> It's difficult to argue against your vapourware.

I'm taking my time with it. You are moving at glacial speed on Forth-200x, and what you are producing is just a bloated version of ANS-Forth --- I don't feel any pressure from that direction --- I don't think you are anybody to knock me for moving slowly.

I don't want to be like Forth Inc. and release code that hasn't been tested at all (such as SwiftForth-v2 in which (LOCAL) would crash the system when it was used).

Mostly, I just keep running into new ideas, and having to rethink the design. I've already started over from scratch three times.

There are good ideas that come up on comp.lang.forth. For example:
https://groups.google.com/forum/#!searchin/comp.lang.forth/lauri$20abstraction/comp.lang.forth/SaC_e4frlxs/uPzdj37wnEQJ
She was making a good point that I hadn't given any thought to, and so I think that I will do this in my language. Unfortunately, any time that anybody introduces any new thinking to comp.lang.forth, the person is attacked --- telling her to read the Wikipedia article was incredibly insulting.

Most Forths can be implemented quickly, because they are just a rework of an old Forth system from the 1970s, without any new thinking. For example, PolyForth for the 16-bit x86 didn't take advantage of the segment registers at all --- the compiler, dictionary, application program, application library --- everything --- fit into a single 64K segment. It apparently was just a direct port from a system for an old processor that was limited to 64K (most likely the PDP-11). Porting old 1970s Forth systems to new hardware seems like a waste of time to me --- I want to put together something that is innovative.

> It's certainly true that 64 bit CPUs are good for applications
> that use a lot of 64 bit data. Outside the scientific domains
> there does not seem to be a great demand for 64 bit data.
> We only have one client who can show a need for much better
> processing of 64/128 bit data.

I mentioned CAM already. If you use 32-bit numbers, and you set unity at 2^20, then you have 6 decimal digits to the right of your decimal point and 3 to the left. This is doable, but it is pretty marginal --- round-off error is going to be a problem --- and CAM is actually a pretty pedestrian application, as it deals with a physical machine that moves over a small area (maybe 8 foot square at the most) and a limited precision (+-.0005 inches at the very best).

I think that what you are doing, is relying on floating-point for applications that I would do in fixed-point. This is a bad idea. Floating-point is at least twice as slow as fixed-point, and no amount of optimizing will change this. Also, in ANS-Forth floating-point is cumbersome because it uses a different stack, and you can't store floats in locals. If you write a CAM program in VFX, it is going to be unduly slow and cumbersome --- and, like I said, CAM is a pretty pedestrian application --- this is not a "scientific domain," this is a machine-shop.

You are making your job much more difficult than necessary. Now you have to write an optimizing compiler for floating-point operations as well as fixed-point operations. By comparison, I only worry about fixed-point operations, so I have half the work that you have (this is assuming that I don't support floating-point, which I may not, although I'm undecided if I will or won't).

Albert van der Horst

unread,
Jul 19, 2014, 7:17:41 AM7/19/14
to
In article <53c928c6....@news.demon.co.uk>,
Stephen Pelc <steph...@mpeforth.com> wrote:
>On Thu, 17 Jul 2014 16:34:46 -0700 (PDT), hughag...@yahoo.com
>wrote:
>
>>Also, just by writing HostForth in 64-bit x86 assembly rather than 32-bit x=
>>86 assembly, I have taken a big step toward defeating Pelc who is mired in =
>>the obsolete 32-bit x86 world. Defeating Forth Inc. is too easy, as SwiftFo=
>>rth is slow as molasses --- defeating MPE is much more difficult --- but it=
>> should be possible, especially for programs that deal primarily in 64-bit =
>>data. How much fun would that be? A lot! ;-)
>
>It's difficult to argue against your vapourware.
>
>It's certainly true that 64 bit CPUs are good for applications
>that use a lot of 64 bit data. Outside the scientific domains
>there does not seem to be a great demand for 64 bit data.
>We only have one client who can show a need for much better
>processing of 64/128 bit data.

In the light delay tunnel of the Chili ESA space observatory (60 m),
the distance was measured in 256-th of the wavelength of an infra red
beam. (14 nm RMS deviation ). The results needed more than 32 bits.
One of the rare occasions I came across.

>
>Stephen
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

m...@iae.nl

unread,
Jul 19, 2014, 11:04:44 AM7/19/14
to
On Thursday, July 17, 2014 9:32:46 AM UTC+2, Raimond Dragomir wrote:
[..]
> Forth cannot hide the size for operators, do you cannot have a "+"
> that work on single cells or double cells.

You can use the standard word TO for this.

-marcel

Alex McDonald

unread,
Jul 19, 2014, 4:31:31 PM7/19/14
to
I was quite clear that I was describing the default *operand* size, which
is 32 bits.

The default *address* size is 64 bits, but (at least in Windows) there's
nothing stopping you from having a Win64 Forth that uses 32 bit addresses
and hence 32 bit cells. The data address space is then 32 bit, RIP
relative and is limited to 4GB; it's unlikely to be a limitation in all
except a few cases. It's also possible in a 64 bit Windows (XP, 7 anf 8)
to run a 32 bit executable that can execute code in 64 bit mode.

hughag...@yahoo.com

unread,
Jul 19, 2014, 7:36:18 PM7/19/14
to
One of the more stupid design decisions in ANS-Forth, was to make locals work with TO. In my language, locals produce an address that can then be accessed with @ and ! like any variable (I don't support TO at all). There are several advantages to this --- one of which is that floats can be stored in local variables so long as the local is at least 64-bits in size (which can be done on either a 32-bit or 64-bit Forth).

In 1994 when ANS-Forth became the standard, Forth Inc. had not figured out how to implement local variables. When they came out with SwiftForth-v2 later on, (LOCAL) would crash the system, so they obviously never tested the use of locals even once before releasing it. At the time that ANS-Forth came out in 1994, nobody at Forth Inc. knew what locals were --- they wrote the ANS-Forth standard based on vague speculation and hearsay.

I really believe that the only way for Forth to succeed, is to abandon ANS-Forth. I see no reason why there can't be two standards for a while --- ANS-Forth and my "Lambda Forth." Pelc could support both for a while. I predict that, after a while, Forth Inc. will be the only group supporting ANS-Forth and ANS-Forth will considered to be another name for SwiftForth (how I consider it now). If ANS-Forth has any value though, then other people will continue to use it, and they will ignore Lambda Forth --- may the best standard win!

Pelc has already abandoned ANS-Forth compliance in many ways. For example, he understands the problem with CREATE code comma'ing non-mutable data but then the DOES> code at run-time having to treat it like mutable code. His solution is a non-standard declaration at compile-time to declare the data non-mutable. But if he is going to abandon ANS-Forth compliance, why not go all the way and abandon ANS-Forth totally? What is the point of a halfway abandonment?

hughag...@yahoo.com

unread,
Jul 19, 2014, 8:04:28 PM7/19/14
to
On Friday, July 18, 2014 7:30:34 AM UTC-7, Stephen Pelc wrote:
> On Thu, 17 Jul 2014 16:34:46 -0700 (PDT), hughag...@yahoo.com
> wrote:
> >Also, just by writing HostForth in 64-bit x86 assembly rather than 32-bit x=
> >86 assembly, I have taken a big step toward defeating Pelc who is mired in =
> >the obsolete 32-bit x86 world. Defeating Forth Inc. is too easy, as SwiftFo=
> >rth is slow as molasses --- defeating MPE is much more difficult --- but it=
> > should be possible, especially for programs that deal primarily in 64-bit =
> >data. How much fun would that be? A lot! ;-)
>
> It's difficult to argue against your vapourware.

It is easy to call my Lambda Forth "vaporware" (or "vapourware" using your screwed up English) --- because it is vaporware at this time.

This is not a long-term plan though. Eventually I will release my system. This is assuming that I am capable of writing a cross-compiler, and I am, as I have done this before with MFX for the MiniForth.

If you stick with ANS-Forth, then you are going to get soundly defeated when Lambda Forth comes out --- because ANS-Forth has serious design flaws (it was mandated to be fully compatible with SwiftForth without any change in SwiftForth whatsoever). Upgrading to Forth-200x isn't going to help, because Forth-200x is mandated to be fully compatible with ANS-Forth --- upgrading to Forth-200x may actually make you worse off, because Forth-200x is significantly more bloated than ANS-Forth, and all of this bloat increases the difficulty of optimization rather than lessen it.

Realistically, you can't defeat me, so you might as well join me --- and the sooner that you do, the better off you will be, as you can contribute to the design rather than have to just accept it after I've written it in stone.

I'm totally baffled as to why Elizabeth Rather has any cred at all. The only Forth code she has posted on C.L.F. since C.L.F. came into being, has been taken straight out of the "Starting Forth" book. That is pathetic! Forth Inc. embarrassed the entire Forth community badly with PolyForth being crammed into a single 64K segment on the 16-bit x86 (this was actually worse than the Tiny memory-model, as the compiler and symbol table had to fit in the 64K along with the application code and data) --- this was at a time when all of the C compilers supported all six memory models. PolyForth compared badly to QBasic, and QBasic was considered to be a toy even by its proponents. Forth Inc. has never made any positive contribution to Forth --- Forth Inc. is just an ongoing scam --- they don't deserve any respect whatsoever.

Rod Pemberton

unread,
Jul 19, 2014, 9:36:25 PM7/19/14
to
On Sat, 19 Jul 2014 19:36:18 -0400, <hughag...@yahoo.com> wrote:

> One of the more stupid design decisions in ANS-Forth, was to make locals
> work with TO.

This is another thread entirely:

"Vote Hugh or vote NO on TO with locals"

> In my language, locals produce an address that can then be accessed with
> @ and ! like any variable (I don't support TO at all).

Uh... How is that any different from just using a variable?

> I really believe that the only way for Forth to succeed, is
> to abandon ANS-Forth.

Why? Please, back that up for once, like with a list.

I didn't even attempt to do ANS, yet nearly everything I implemented
passes (or did) Hayes ANS core tests. So, what is so terrible with
ANS-Forth? It's clear to me that ANS is not all that different from
pre-ANS Forth.


Rod Pemberton
It is loading more messages.
0 new messages