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

continue equivalent in Forth?

500 views
Skip to first unread message

program...@gmail.com

unread,
Aug 18, 2012, 10:28:42 PM8/18/12
to
When I am in a begin-while-repeat loop, I sometimes would like to go to the top of the loop. The "continue" keyword in C is what would help me perfectly here. Is there a "continue" like word in Forth?

Andrew Haley

unread,
Aug 19, 2012, 2:43:15 AM8/19/12
to
There's no exact equivalent, although any loop strucure can be written
in Forth. If you can give us an example of what sort of thing you'd
like to write, we can show how it'd be done in Forth. I'm a bit
concerned that the words you're trying to write may be too long: the
Forth way is to make them as short as possible and push the complexity
into words that are called.

Andrew.

m...@iae.nl

unread,
Aug 19, 2012, 6:40:58 AM8/19/12
to
When the application is properly factored, one doesn't
encounter the need that often.

-- C --------------

for (p = SE_SUN; p <= SE_CHIRON; p++) {
if (p == SE_EARTH) continue;
// do the coordinate calculation for this planet p
iflgret = swe_calc_ut(tjd_ut, p, iflag, x2, serr);

if (iflgret < 0) // if there is a problem, a negative value is returned
// and an error message is in serr.
printf("error: %s\n", serr); // get the name of the planet p
swe_get_planet_name(p, snam); // print the coordinates
printf("%10s\t%11.7f\t%10.7f\t%10.7f\t%10.7f\n",
snam, x2[0], x2[1], x2[2], x2[3]); }

-- Forth --------------

: CALCULATE ( planet -- ) ( F: julday -- )
DUP SE_EARTH = IF DROP FDROP EXIT ENDIF
... ;

: DEMO ( year month day -- )
...
SE_CHIRON 1+ SE_SUN ?DO I julianday CALCULATE LOOP ;

-marcel

Ed

unread,
Aug 19, 2012, 7:07:12 AM8/19/12
to
No, as generally it can be avoided. Provide a sample of what it
is that you wish to do and someone should be able to help.

That said, some forths have tools that allow one to implement
features found in other languages e.g.


: BEGIN
postpone begin 0 cs-pick cs-push ; immediate

: REPEAT
cs-pop cs-drop postpone repeat ; immediate

: CONTINUE
cs-pop 0 cs-pick postpone again cs-push ; immediate


: test ( -- )
cr cr ." Chars b d f will be ignored, ESC quits." cr
begin
cr ." Enter character> " key dup 27 -
while ( not ESC )
dup [char] b = if drop continue then
dup [char] d = if drop continue then
dup [char] f = if drop continue then
( char ) emit
repeat drop ;

test

Chars b d f will be ignored, ESC quits.

Enter character> a
Enter character>
Enter character> c
Enter character>
Enter character> e
Enter character>
Enter character> g
Enter character> h
Enter character> i
Enter character> j
Enter character> ok




Coos Haak

unread,
Aug 19, 2012, 7:55:59 AM8/19/12
to
Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:

> program...@gmail.com wrote:
>> When I am in a begin-while-repeat loop, I sometimes would like to go to the top of the loop.
>> The "continue" keyword in C is what would help me perfectly here. Is there a "continue" like
>> word in Forth?
>
> No, as generally it can be avoided. Provide a sample of what it
> is that you wish to do and someone should be able to help.
>
> That said, some forths have tools that allow one to implement
> features found in other languages e.g.
>
>
>: BEGIN
> postpone begin 0 cs-pick cs-push ; immediate
>
>: REPEAT
> cs-pop cs-drop postpone repeat ; immediate
>
>: CONTINUE
> cs-pop 0 cs-pick postpone again cs-push ; immediate
>
Some implementations may have similar constructs, but what does a beginner
do with such strange words like CS-PUSH, CS-POP, or CS-DROP? He _may_ have
CS-PICK and CS-ROLL from the Tools Extensions Wordlist, but how can he
implement the other three?
CS-DROP may sometimes be DROP, another time 2DROP or even 3DROP.

--
Coos

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

Coos Haak

unread,
Aug 19, 2012, 8:18:06 AM8/19/12
to
Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:

>: BEGIN
> postpone begin 0 cs-pick cs-push ; immediate
>
>: REPEAT
> cs-pop cs-drop postpone repeat ; immediate
>
>: CONTINUE
> cs-pop 0 cs-pick postpone again cs-push ; immediate
>
>
>: test ( -- )
> cr cr ." Chars b d f will be ignored, ESC quits." cr
> begin
> cr ." Enter character> " key dup 27 -
> while ( not ESC )
> dup [char] b = if drop continue then
> dup [char] d = if drop continue then
> dup [char] f = if drop continue then
> ( char ) emit
> repeat drop ;

A much simpler solution with standard words, as IF adds one control level
above BEGIN:

: CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE

Marcel Hendrix

unread,
Aug 19, 2012, 8:57:33 AM8/19/12
to
Coos Haak <chf...@hccnet.nl> writes Re: continue equivalent in Forth?

> Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:
[..]
> A much simpler solution with standard words, as IF adds one control level
> above BEGIN:

> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE

It works in iForth (to my big surprise), given SECURE OFF .

FORTH> see test
Flags: ANSI
$01249680 : test
$0124968A push $01247268 d#
$0124968F push #45 b#
$01249691 lea rbp, [rbp -8 +] qword
$01249695 mov [rbp 0 +] qword, $012496A2 d#
$0124969D jmp TYPE+10 ( $01139042 ) offset NEAR
$012496A2 pop rbx
$012496A3 lea rax, [rax 0 +] qword
$012496A8 push rbx
\ begin
$012496A9 push $01247298 d#
$012496AE push #19 b#
$012496B0 lea rbp, [rbp -8 +] qword
$012496B4 mov [rbp 0 +] qword, $012496C1 d#
$012496BC jmp TYPE+10 ( $01139042 ) offset NEAR
$012496C1 lea rbp, [rbp -8 +] qword
$012496C5 mov [rbp 0 +] qword, $012496D2 d#
$012496CD jmp KEY+10 ( $01138FBA ) offset NEAR
$012496D2 pop rbx
$012496D3 lea rdi, [rbx #-27 +] qword
$012496D7 cmp rdi, 0 b#
$012496DB je $0124972E offset NEAR
$012496E1 cmp rbx, #98 b#
$012496E5 jne $012496F1 offset NEAR
$012496EB mov rbx, [rsp] qword
$012496EF jmp $012496A9 offset SHORT \ begin
$012496F1 cmp rbx, #100 b#
$012496F5 jne $01249701 offset NEAR
$012496FB mov rbx, [rsp] qword
$012496FF jmp $012496A9 offset SHORT \ begin
$01249701 cmp rbx, #102 b#
$01249705 jne $01249711 offset NEAR
$0124970B mov rbx, [rsp] qword
$0124970F jmp $012496A9 offset SHORT \ begin
$01249711 push rbx
$01249712 lea rbp, [rbp -8 +] qword
$01249716 mov [rbp 0 +] qword, $01249723 d#
$0124971E jmp EMIT+10 ( $01139012 ) offset NEAR
$01249723 mov rbx, [rsp] qword
$01249727 jmp $012496A9 offset NEAR \ begin
$0124972C push rbx
$0124972D pop rbx
$0124972E ;


Coos Haak

unread,
Aug 19, 2012, 10:39:52 AM8/19/12
to
Op Sun, 19 Aug 2012 14:57:33 +0200 schreef Marcel Hendrix:

> Coos Haak <chf...@hccnet.nl> writes Re: continue equivalent in Forth?
>
>> Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:
> [..]
>> A much simpler solution with standard words, as IF adds one control level
>> above BEGIN:
>
>>: CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
>
> It works in iForth (to my big surprise), given SECURE OFF .

Of course, look at your own Ackermann benchmarks of some decades ago!

Rod Pemberton

unread,
Aug 19, 2012, 11:00:40 AM8/19/12
to
<program...@gmail.com> wrote in message
news:8cbd2bb8-ed3d-4fab...@googlegroups.com...

> When I am in a begin-while-repeat loop, I sometimes
> would like to go to the top of the loop.

From which section of the loop would you
"like to go to the top of the loop"?

1) begin-while
2) while-repeat

I'm surprised no one else asked that ...


Rod Pemberton


Coos Haak

unread,
Aug 19, 2012, 2:29:11 PM8/19/12
to
Op Sun, 19 Aug 2012 11:00:40 -0400 schreef Rod Pemberton:
It doesn't matter, the control items of BEGIN are on the top in the first
part, and WHILE puts it items under them.
Times have changed since FigForth ;-)

Mark Wills

unread,
Aug 19, 2012, 2:31:23 PM8/19/12
to
On Aug 19, 3:28 am, programmingk...@gmail.com wrote:
> When I am in a begin-while-repeat loop, I sometimes would like to go to the top of the loop. The "continue" keyword in C is what would help me perfectly here. Is there a "continue" like word in Forth?

Just use a BEGIN...UNTIL loop with a CASE block inside it.

program...@gmail.com

unread,
Aug 19, 2012, 5:09:33 PM8/19/12
to
In the while-repeat area.

program...@gmail.com

unread,
Aug 19, 2012, 5:37:37 PM8/19/12
to
Unfortunately my Forth implementation does not have a cs-push, or a cs-pop word. What exactly do they do?

What I am trying to do is to alter the INTERPRET word so it calls another kind of FIND word. The job of my FIND word is to locate local variables in definitions and substitute local variable symbols with words that are used in place of the symbol. I call it LFIND. I set the mydefer defer to LFIND's execution token because I am still testing LFIND. When I am done testing, mydefer will be replaced with LFIND. usingLocals acts like a flag to prevent mydefer from executing before it is ready. Here is the source code:

false value usingLocals
Defer mydefer

: interpret
0 >in !
begin
parse-word dup 0> \ was there a word at all?
while
usingLocals if
mydefer
if
CONTINUE \ no need to continue to $FIND or $NUMBER.
then
then
$find
if
dup flags? 0<> state @ 0= or if
execute
else
, \ compile mode && !immediate
then
else \ word is not known. maybe it's a number
2dup $number
if
span @ >in ! \ if we encountered an error, don't continue parsing
type 3a emit
-13 throw
else
-rot 2drop 1 handle-lit
then
then
depth 200 >= if -3 throw then
depth 0< if -4 throw then
rdepth 200 >= if -5 throw then
rdepth 0< if -6 throw then
repeat
2drop
;

program...@gmail.com

unread,
Aug 19, 2012, 5:43:18 PM8/19/12
to
I'm don't think that would be easy to implement.

Andrew Haley

unread,
Aug 20, 2012, 6:17:14 AM8/20/12
to
This is an example of the problem I was talking about. Forth words
should, ideally, be one or two lines long. However, that assumes a
horizontal layout, rather than the vertical layout you've used here.
So, that would correspond to about five or six lines with a vertical
layout. I'm fairly sure that if you refactor this word into sub-words
your need for CONTINUE will go away.

Andrew.

Ed

unread,
Aug 20, 2012, 8:13:12 AM8/20/12
to
Coos Haak wrote:
> ...
> Some implementations may have similar constructs, but what does a beginner
> do with such strange words like CS-PUSH, CS-POP, or CS-DROP? He _may_ have
> CS-PICK and CS-ROLL from the Tools Extensions Wordlist, but how can he
> implement the other three?

I'm told the Standard is a minimum specification.



Ed

unread,
Aug 20, 2012, 8:18:54 AM8/20/12
to
Coos Haak wrote:
> ...
> A much simpler solution with standard words, as IF adds one control level
> above BEGIN:
>
> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE

Real-world apps may not be so accommodating.



Ed

unread,
Aug 20, 2012, 8:34:48 AM8/20/12
to
program...@gmail.com wrote:
> ...
>
> Unfortunately my Forth implementation does not have a cs-push, or a cs-pop word. What
> exactly do they do?

The spec may be found here

http://dxforth.webhop.org/cfsext.html




Ed

unread,
Aug 20, 2012, 9:01:33 AM8/20/12
to
program...@gmail.com wrote:
> ...
> What I am trying to do is to alter the INTERPRET word so it calls another kind of FIND word.
> The job of my FIND word is to locate local variables in definitions and substitute local
> variable symbols with words that are used in place of the symbol. I call it LFIND. I set the
> mydefer defer to LFIND's execution token because I am still testing LFIND. When I am done
> testing, mydefer will be replaced with LFIND. usingLocals acts like a flag to prevent
> mydefer from executing before it is ready. Here is the source code:
> ...

Arrange the code so that mydefer falls through to REPEAT e.g.

...
usingLocals if
mydefer
else
$find
....
then
repeat






Rod Pemberton

unread,
Aug 21, 2012, 12:04:36 AM8/21/12
to
"Coos Haak" <chf...@hccnet.nl> wrote in message
news:krgrlza60czr$.zq0hfu8qh13x.dlg@40tude.net...
> Op Sun, 19 Aug 2012 11:00:40 -0400 schreef Rod Pemberton:
> > <program...@gmail.com> wrote in message
> > news:8cbd2bb8-ed3d-4fab...@googlegroups.com...
...

> >> When I am in a begin-while-repeat loop, I sometimes
> >> would like to go to the top of the loop.
> >
> > From which section of the loop would you
> > "like to go to the top of the loop"?
> >
> > 1) begin-while
> > 2) while-repeat
> >
> > I'm surprised no one else asked that ...
> >
>
> It doesn't matter, the control items of BEGIN are on the top
> in the first part, and WHILE puts it items under them.
>

Yes, you're correct. BEGIN's address is on top for both sections. WHILE
SWAPs or 1 CS-ROLLs. I was thinking BEGIN's address wasn't the 1st stack
item in the while-repeat section... If that had been true, it would've
required two definitions for CONTINUE.

But, I still think it does matter for another reason. I've posted the
reason in the reply to your post with your definition of CONTINUE.


Rod Pemberton



Rod Pemberton

unread,
Aug 21, 2012, 12:05:59 AM8/21/12
to
"Coos Haak" <chf...@hccnet.nl> wrote in message
news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
> Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:
>
> >: BEGIN
> > postpone begin 0 cs-pick cs-push ; immediate
> >
> >: REPEAT
> > cs-pop cs-drop postpone repeat ; immediate
> >
> >: CONTINUE
> > cs-pop 0 cs-pick postpone again cs-push ; immediate
> >
> >
> >: test ( -- )
> > cr cr ." Chars b d f will be ignored, ESC quits." cr
> > begin
> > cr ." Enter character> " key dup 27 -
> > while ( not ESC )
> > dup [char] b = if drop continue then
> > dup [char] d = if drop continue then
> > dup [char] f = if drop continue then
> > ( char ) emit
> > repeat drop ;
>
> A much simpler solution with standard words, as IF adds one control level
> above BEGIN:
>
> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
>

A separate control-flow stack isn't a requirement for ANS compliance. So,
AISI, this definition for CONTINUE will only work if the Forth in question
has a control-flow stack separate from the data stack, or the implementation
uses a data stack for both and then tracks control-flow data somehow. I
think the latter would complicate CS-ROLL and CS-PICK immensely.

AIUI, most Forths don't have a control-flow stack separate from the
parameter or data stack. They use the data stack for both. Such a simple
definition for CONTINUE will not work in such a case since BEGIN's address
could be below other stacked data. I.e., how do you locate which stack
location has BEGIN's address?


BEGIN
\ BEGIN's address on data stack
... \ other data on stack
\ how does CONTINUE get BEGIN's address here?
IF CONTINUE THEN
...
WHILE
...
IF CONTINUE THEN
...
REPEAT


Rod Pemberton



hughag...@yahoo.com

unread,
Aug 21, 2012, 12:17:45 AM8/21/12
to
On Monday, August 20, 2012 9:05:59 PM UTC-7, Rod Pemberton wrote:
> AIUI, most Forths don't have a control-flow stack separate from the
> parameter or data stack. They use the data stack for both. Such a simple
> definition for CONTINUE will not work in such a case since BEGIN's address
> could be below other stacked data. I.e., how do you locate which stack
> location has BEGIN's address?

Straight Forth will require that the control-flow stack be separate from the data stack --- this is one of the many gross mistakes of ANS-Forth that will be corrected --- the control-flow stack is used at compile-time anyway, so speed is not an issue.

Stephen Pelc

unread,
Aug 21, 2012, 4:34:38 AM8/21/12
to
On Sun, 19 Aug 2012 14:37:37 -0700 (PDT), program...@gmail.com
wrote:

>What I am trying to do is to alter the INTERPRET word so it calls another k=
>ind of FIND word. The job of my FIND word is to locate local variables in d=
>efinitions and substitute local variable symbols with words that are used i=
>n place of the symbol. I call it LFIND. I set the mydefer defer to LFIND's =
>execution token because I am still testing LFIND. When I am done testing, m=
>ydefer will be replaced with LFIND. usingLocals acts like a flag to prevent=
> mydefer from executing before it is ready. Here is the source code:=20

Let's redo the loop a bit:

> false value usingLocals
>Defer mydefer
>
>: interpret=20
> 0 >in !
> begin
> parse-word dup 0> \ was there a word at all?
> while
> usingLocals if
> mydefer
> if
> CONTINUE \ no need to continue to $FIND or $NUMBER.
> then
> then
> $find=20
if foo else bar then
checks
> repeat
> 2drop
> ;

Now we can refactor again:

false value usingLocals
Defer mydefer

: dolocal \ ??? -- ???
usingLocals dup if
drop mydefer
then
;

: interpret \ ??? -- ???
0 >in !
begin
parse-word dup 0>
while
dolocal 0= if
$find
if foo else bar then
checks
then
repeat
2drop
;

You can probably usefully move CHECKS to just before the REPEAT. Now
you do not need CONTINUE. Factoring is the key because it allows you
to see easy solutions. You can also usefully refactor the DEFERred
word so that dolocal is the DEFERred. Factor it, refactor it and
refactor it again and then you may have a solution.

Personally, I would ask why you do not handle locals by adding to the
search order. This replaces the CONTINUE problem with the problem of
having a transient dictionary area. With a bit of factoring, the
transient dictionary problem is not difficult either.

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

Alex McDonald

unread,
Aug 21, 2012, 5:37:12 AM8/21/12
to
On Aug 21, 5:05 am, "Rod Pemberton" <do_not_h...@notemailnot.cmm>
wrote:
> "Coos Haak" <chfo...@hccnet.nl> wrote in message
You're confusing what happens at compile time with what happens at run
time. At compile time, when the compiler hits the CONTINUE in BEGIN
( various words like @ DUP etc ) IF CONTINUE THEN ... the stack
contains;

<begin-addr> <if-addr>

and 1 CS-PICK pulls off <begin-addr>. There's nothing from run time
( various words like @ DUP etc ) on the stack because we're
compiling.

At run time, there's no control flow on the stack. Hence the data
stack and the control stack can be the same stack. The code works
regardless of how the control stack is implemented.

Alex McDonald

unread,
Aug 21, 2012, 5:40:07 AM8/21/12
to
Why is this a gross mistake, and what advantage does a separate
control stack bring?

Anton Ertl

unread,
Aug 21, 2012, 7:40:16 AM8/21/12
to
"Rod Pemberton" <do_no...@notemailnot.cmm> writes:
>"Coos Haak" <chf...@hccnet.nl> wrote in message
>news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
>> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
[...]
>AIUI, most Forths don't have a control-flow stack separate from the
>parameter or data stack. They use the data stack for both. Such a simple
>definition for CONTINUE will not work in such a case since BEGIN's address
>could be below other stacked data.

What other stacked data? The only data usually on the stack above
colon-sys during compilation are control-flow stack items. That's why
it's practical to use the data stack as control-flow stack. If people
put data on the stack during compilation that lived across
control-flow words, not just CONTINUE would be in trouble, but every
other control-flow word, too. But they don't.

>BEGIN
>\ BEGIN's address on data stack
> ... \ other data on stack
>\ how does CONTINUE get BEGIN's address here?
> IF CONTINUE THEN

Simple: There are only control-flow stack items there, and it's the
second control-flow stack item.

> ...
>WHILE
> ...
> IF CONTINUE THEN
> ...
>REPEAT

You could also ask how REPEAT gets BEGIN's address here. The answer
is the same.

- 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 2012: http://www.euroforth.org/ef12/

Gerry Jackson

unread,
Aug 21, 2012, 10:53:31 AM8/21/12
to
On 21/08/2012 09:34, Stephen Pelc wrote:
> On Sun, 19 Aug 2012 14:37:37 -0700 (PDT), program...@gmail.com
> wrote:
>

> Personally, I would ask why you do not handle locals by adding to the
> search order.
>

You need to be careful how you implement this idea e.g.

VFX Forth for Windows IA32
� MicroProcessor Engineering Ltd, 1998-2011

Version: 4.44 [build 3245]
Build date: 1 November 2011

Free dictionary = 7557646 bytes [7380kb]


get-order wordlist swap 1+ set-order ok
ok
: foo { x } x [ previous ] x ;
Err# -13 ERR: Undefined word.
-> : foo { x } x [ previous ] x ;
^

This is a greatly simplified version of code where the bug bit me a long
time ago. I reported it so, of course, you may have fixed this in a
later version. It's the same if LOCALS| is used.

Similarly:

wordlist constant wl ok
get-current wl set-current ok-1
1234 value x ok-1
set-current ok
: foo { x } cr x . [ get-order wl swap 1+ set-order ] x . ; ok
9876 foo
9876 1234 ok

This also violates the ANS Forth requirement that "... none of the
Search-Order words shall change the locals' privileged position in the
search order."

--
Gerry

Bernd Paysan

unread,
Aug 21, 2012, 2:49:23 PM8/21/12
to
Rod Pemberton wrote:
> AIUI, most Forths don't have a control-flow stack separate from the
> parameter or data stack. They use the data stack for both. Such a
> simple definition for CONTINUE will not work in such a case since
> BEGIN's address
> could be below other stacked data. I.e., how do you locate which
> stack location has BEGIN's address?

Search for it? In Gforth, it's a dest-like control-sys, so it is
identified by the constant "dest" for the top-most element.

: continue ( dest-sys j*sys -- dest-sys j*sys )
depth 0 ?DO I pick dest = IF
I cs-item-size / cs-pick postpone AGAIN
UNLOOP EXIT THEN
cs-item-size +LOOP
true abort" no BEGIN found" ;
immediate compile-only

should do it. I'm not using CS-PICK for the search, since Gforth
implements a check for the standard's "CS-PICK can only pick dests"
condition - and well, it's faster that way, too.

This will jump to the next-outer BEGIN. You can theoretically stack and
clean up other data in between, but normally, you don't (and it's not
adviced to do so), and if you actually do, and CONTINUE breaks, you get
what you deserve.

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

Rod Pemberton

unread,
Aug 22, 2012, 12:53:16 AM8/22/12
to
"Alex McDonald" <bl...@rivadpm.com> wrote in message
news:a2f22ce8-ab03-4006...@k3g2000vby.googlegroups.com...
> On Aug 21, 5:05 am, "Rod Pemberton" <do_not_h...@notemailnot.cmm>
> wrote:
> > "Coos Haak" <chfo...@hccnet.nl> wrote in message
> > news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
> > > Op Sun, 19 Aug 2012 21:07:12 +1000 schreef Ed:
...
> You're confusing what happens at compile time with what happens at run
> time.

I think the issue affects use of control words placing data on the stack
too.

> At compile time, when the compiler hits the CONTINUE in BEGIN
> ( various words like @ DUP etc ) IF CONTINUE THEN ... the stack
> contains;
>
> <begin-addr> <if-addr>
>
> and 1 CS-PICK pulls off <begin-addr>. There's nothing from run time
> ( various words like @ DUP etc ) on the stack because we're
> compiling.

That requires that CONTINUE be used within a single IF-THEN. I.e., what if
there are two <if-addr>'s on the stack?

> At run time, there's no control flow on the stack. Hence the data
> stack and the control stack can be the same stack.

True.

> The code works
> regardless of how the control stack is implemented.

Yeah, I don't think so...


Rod Pemberton


Rod Pemberton

unread,
Aug 22, 2012, 12:53:56 AM8/22/12
to
"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
news:2012Aug2...@mips.complang.tuwien.ac.at...
> "Rod Pemberton" <do_no...@notemailnot.cmm> writes:
> >"Coos Haak" <chf...@hccnet.nl> wrote in message
> >news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
...

> >> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
> [...]
> >AIUI, most Forths don't have a control-flow stack separate from the
> >parameter or data stack. They use the data stack for both. Such a
> >simple definition for CONTINUE will not work in such a case since
> >BEGIN's address could be below other stacked data.
>
> What other stacked data? The only data usually on the stack above
> colon-sys during compilation are control-flow stack items. That's why
> it's practical to use the data stack as control-flow stack. If people
> put data on the stack during compilation that lived across
> control-flow words, not just CONTINUE would be in trouble, but every
> other control-flow word, too. But they don't.
>

Aren't you ignoring the fact that there could be other control words placing
data on the stack? E.g., what if COTINUE is used within nested IF-THENs.
CONTINUE as Coos coded it requires that the address it uses be in a specific
stack position. However, the programmer determines which control words and
how many come prior to it's use. Are you going to modify all control words,
similar to WHILE, to preserve that location just to use CONTINUE?


Rod Pemberton




Ed

unread,
Aug 22, 2012, 1:33:40 AM8/22/12
to
The creator of the control-flow-stack (or documentor as he prefers to say)
believed Forth had all control structures it needed. His purpose in introducing
a cfs and associated words was very specific. Below he explains what it was
intended for and the political compromises he needed to make:

quote

Newsgroups: comp.lang.forth
From: wilba...@netcom.com (Wil Baden)
Date: 1998/10/27
Subject: Re: Does LEAVE need its own dedicated stack?

As the one who created and proposed `CS-ROLL`, `CS-PICK`, `AHEAD`, and
`UNLOOP` (my names were changed), and proposed the behavior of `WHILE`,
this thread brings back old memories.

`CS-ROLL` and `CS-PICK` are not intended for writing programs. They are
guarantees. They guarantee that any control-flow logic with `GOTO`s, no
matter how messy, can be written in Forth. `CS-PICK` isn't necessary. The
conversion is mechanical. With a depth first search, most programs written
with `GOTO`s can be converted to strictly structured. In fact most uses of
unstructured logic can be rewritten with just one form of `CS-ROLL`.

[...]

There were two main parties at that time.

1. We don't need control flow syntax checking and so want only
one cell for a control-flow stack element.

2. We should have control flow syntax checking and so we must
have two cells for a control-flow stack element.

The concept of control-stack was introduced to solve the problem of
control-flow stack size. I didn't invent the control-flow stack: I
named it and documented it.

The control-flow stack was also to pacify those who thought the data
stack shouldn't be used for control-flow words.

To me that is silly. The data stack has no good use during compilation and
to have a special stack only used during compilation is foolish, especially
in multi-user systems.

end-quote

I don't use a separate CFS stack. In fact I rarely use the extension words
I implemented. But they're fun to have and (if using the data stack) cheap
to implement.



hughag...@yahoo.com

unread,
Aug 22, 2012, 1:59:09 AM8/22/12
to
On Tuesday, August 21, 2012 4:40:16 AM UTC-7, Anton Ertl wrote:
> "Rod Pemberton" <do_no...@notemailnot.cmm> writes:
> >AIUI, most Forths don't have a control-flow stack separate from the
> >parameter or data stack. They use the data stack for both. Such a simple
> >definition for CONTINUE will not work in such a case since BEGIN's address
> >could be below other stacked data.
>
> What other stacked data? The only data usually on the stack above
> colon-sys during compilation are control-flow stack items. That's why
> it's practical to use the data stack as control-flow stack. If people
> put data on the stack during compilation that lived across
> control-flow words, not just CONTINUE would be in trouble, but every
> other control-flow word, too. But they don't.

Are you for real? You don't understand what :NAME does at all, do you? You apparently never write colon words that generate other colon words, but you just hand-write all of your code --- why don't you give up on Forth and just stick with C programming, as that seems to much more your style?

If you look at my novice package, you can see that I routinely pass data into colon definitions at their compile-time and give it to LITERAL. Look at <1ARRAY> etc. for example. I can't pass this data on the stack however, because the control-flow words are also using the stack. I typically use local variables, although sometimes I use the return stack --- this is an awkward way to pass data though, as the more Forth-like way to pass data is on the data stack.

Elizabeth D. Rather

unread,
Aug 22, 2012, 3:18:22 AM8/22/12
to
If your control-flow is that complicated, you need to factor differently.

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

hughag...@yahoo.com

unread,
Aug 22, 2012, 3:52:55 AM8/22/12
to era...@forth.com
On Wednesday, August 22, 2012 12:18:22 AM UTC-7, Elizabeth D. Rather wrote:
> On 8/21/12 6:53 PM, Rod Pemberton wrote:
> > Aren't you ignoring the fact that there could be other control words placing
> > data on the stack? E.g., what if COTINUE is used within nested IF-THENs.
> > CONTINUE as Coos coded it requires that the address it uses be in a specific
> > stack position. However, the programmer determines which control words and
> > how many come prior to it's use. Are you going to modify all control words,
> > similar to WHILE, to preserve that location just to use CONTINUE?
>
> If your control-flow is that complicated, you need to factor differently.

Rod Pemberton, our brave C enthusiast, actually knows more about Forth than Elizabeth Rather --- of course CONTINUE is going to be inside of an IF structure, otherwise you would just use REPEAT --- duh!

Normally every control-flow datum includes a code number to indicate what kind of control-flow datum it is. CONTINUE can search back into the control-flow stack with CS-PICK to find its BEGIN datum. There may be several items on top of it.

C.L.F. is just depressing --- people spout nonsense all the time. First Anton Ertl says that people don't put data on the stack during compilation, now we find Elizabeth Rather struggling with the concept of nested control structures. Our so-called leadership seems to be suffering from senility. You know, this might have something to do with why nobody in the world takes Forth seriously --- do you think?

Anton Ertl

unread,
Aug 22, 2012, 5:37:01 AM8/22/12
to
"Rod Pemberton" <do_no...@notemailnot.cmm> writes:
>"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>news:2012Aug2...@mips.complang.tuwien.ac.at...
>> "Rod Pemberton" <do_no...@notemailnot.cmm> writes:
>> >"Coos Haak" <chf...@hccnet.nl> wrote in message
>> >news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
>...
>
>> >> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
>> [...]
>> >AIUI, most Forths don't have a control-flow stack separate from the
>> >parameter or data stack. They use the data stack for both. Such a
>> >simple definition for CONTINUE will not work in such a case since
>> >BEGIN's address could be below other stacked data.
>>
>> What other stacked data? The only data usually on the stack above
>> colon-sys during compilation are control-flow stack items. That's why
>> it's practical to use the data stack as control-flow stack. If people
>> put data on the stack during compilation that lived across
>> control-flow words, not just CONTINUE would be in trouble, but every
>> other control-flow word, too. But they don't.
>>
>
>Aren't you ignoring the fact that there could be other control words placing
>data on the stack?

They will place it on the control flow stack, so having a separate
control flow stack won't make a difference for that issue. Did you
mention the unified data/control flow stack as a red herring, or are
you moving the goal posts now?

Anyway, my approach (and much in the Forth spirit) is to require that
the program uses CONTINUE only in non-nested IFs in BEGIN loops. If
you want a CONTINUE for a double-nested IF, it's easy to define
CONTINUE2, and likewise for CONTINUE3 etc. I don't expect that
anybody will define them, though.

Ed

unread,
Aug 22, 2012, 6:46:30 AM8/22/12
to
Anton Ertl wrote:
> ...
> Anyway, my approach (and much in the Forth spirit) is to require that
> the program uses CONTINUE only in non-nested IFs in BEGIN loops. If
> you want a CONTINUE for a double-nested IF, it's easy to define
> CONTINUE2, and likewise for CONTINUE3 etc. I don't expect that
> anybody will define them, though.

Forth has managed without CONTINUE for 40 years.


Both statements appeal to authority. Which was the more effective?



Alex McDonald

unread,
Aug 22, 2012, 7:10:31 AM8/22/12
to
On Aug 22, 5:53 am, "Rod Pemberton" <do_not_h...@notemailnot.cmm>
wrote:
> "Alex McDonald" <b...@rivadpm.com> wrote in message
Coos noted that in his submission. It's up to you as a programmer to
take heed.

Alex McDonald

unread,
Aug 22, 2012, 7:12:19 AM8/22/12
to
You don't.

Rod Pemberton

unread,
Aug 22, 2012, 7:43:03 AM8/22/12
to
<hughag...@yahoo.com> wrote in message
news:3a5a4df5-8480-4f60...@googlegroups.com...
> On Wednesday, August 22, 2012 12:18:22 AM UTC-7, Elizabeth D. Rather
wrote:
> > On 8/21/12 6:53 PM, Rod Pemberton wrote:
...

> > > Aren't you ignoring the fact that there could be other control words
> > > placing data on the stack? E.g., what if COTINUE is used within
> > > nested IF-THENs. CONTINUE as Coos coded it requires that the
> > > address it uses be in a specific stack position. However, the
> > > programmer determines which control words and how many come
> > > prior to it's use. Are you going to modify all control words,
> > > similar to WHILE, to preserve that location just to use CONTINUE?
> >
> > If your control-flow is that complicated, you need to factor
> > differently.
>
> Rod Pemberton, our brave C enthusiast, actually knows more about Forth
> than Elizabeth Rather --- of course CONTINUE is going to be inside of an
> IF structure, otherwise you would just use REPEAT --- duh!

Ms. Rather has helped me quite a bit. I clearly can't say I "actually
know more about Forth than" her. I'm still implementing Forth and not
really coding in it except to implement my Forth's system words and some
trivial tests. Personally, I forget stuff over time. E.g., I sometimes
have to spend quite some time figuring out what I coded in a program I
haven't looked at in five or so years. I'm sure if you asked someone who
implemented a Forth interpreter two or three decades ago what they did, some
of those details would be "rusty" or "wrong".

> C.L.F. is just depressing --- people spout nonsense all the time. First
> Anton Ertl says that people don't put data on the stack during
> compilation, now we find Elizabeth Rather struggling with the concept
> of nested control structures. Our so-called leadership seems to be
> suffering from senility.

Although, I do find this softer insult of yours amusing ...

> You know, this might have something to do with
> why nobody in the world takes Forth seriously ---
> do you think?

Oh, nobody here likes what I think about Forth's failure(s)...

> Normally every control-flow datum includes a code number to indicate
> what kind of control-flow datum it is. CONTINUE can search back into
> the control-flow stack with CS-PICK to find its BEGIN datum. There
> may be several items on top of it.

Normally ... ? Somehow, I doubt that that is anywhere near a "normal"
implementation. So, for which Forth is this?

That is a tracking method as I mentioned. The use of a code number also
seems overly complicated, i.e., a primitive type system for control-flow
data. The code will prevent mistaking one type of control-flow datum from
another, but how do you prevent mistaking a control-flow datum for non
control-flow datums in the first place? E.g., separate control-flow stack?


Rod Pemberton


Rod Pemberton

unread,
Aug 22, 2012, 7:44:34 AM8/22/12
to
"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
news:2012Aug2...@mips.complang.tuwien.ac.at...
> "Rod Pemberton" <do_no...@notemailnot.cmm> writes:
> >"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
> >news:2012Aug2...@mips.complang.tuwien.ac.at...
> >> "Rod Pemberton" <do_no...@notemailnot.cmm> writes:
> >> >"Coos Haak" <chf...@hccnet.nl> wrote in message
> >> >news:ynvo412dq30u$.hnqbz7gjsjis$.dlg@40tude.net...
...

> >> >> : CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
> >> [...]
> >> >AIUI, most Forths don't have a control-flow stack separate from the
> >> >parameter or data stack. They use the data stack for both. Such a
> >> >simple definition for CONTINUE will not work in such a case since
> >> >BEGIN's address could be below other stacked data.
> >>
> >> What other stacked data? The only data usually on the stack above
> >> colon-sys during compilation are control-flow stack items. That's why
> >> it's practical to use the data stack as control-flow stack. If people
> >> put data on the stack during compilation that lived across
> >> control-flow words, not just CONTINUE would be in trouble, but every
> >> other control-flow word, too. But they don't.
> >>
> >
> > Aren't you ignoring the fact that there could be other control words
> > placing data on the stack?
>
> They will place it on the control flow stack, [...]

Then, yes, there can be other stacked data.

So, when you asked "What other stacked data?" was that a red herring, or
were you moving the goal posts then? ;-)

> [...] so having a separate
> control flow stack won't make a difference for that issue.

Hopefully, I've pointed out that CONTINUE is not that effective.

Is there really any point to having a CONTINUE which is constrained to be
used within an un-nested IF-THEN? How often would that be used? How
often would people use it incorrectly? How could a Forth detect and prevent
incorrect usage?

FYI, neither 'break' nor 'continue' are constrained like that in C... They
both escape the nearest loop control that they work with: 'while', 'do',
'for' and also 'switch' for 'break'. In that regard, they are probably
closer to LEAVE.


Rod Pemberton


Rod Pemberton

unread,
Aug 22, 2012, 7:46:15 AM8/22/12
to
"Elizabeth D. Rather" <era...@forth.com> wrote in message
news:he6dnab1PPQjGqnN...@supernews.com...
I'll take it that you mean "you" and "your" in a generic sense and not me
personally.

Yes, needing to factor more might be true... Forth may have sufficient
control-flow words already. I don't know for sure. I do know it seems like
it has enough already. And, in one case, I think has some words it doesn't
need.

Even so, it seems to me that CONTINUE isn't of much value if it can't be
used within nested IF-THENs. Something similar to the opposite of LEAVE is
probably what CONTINUE needs to be, if it's of any value.


Rod Pemberton




Rod Pemberton

unread,
Aug 22, 2012, 7:46:59 AM8/22/12
to
"Bernd Paysan" <bernd....@gmx.de> wrote in message
news:5042720.V...@sunwukong.fritz.box...
> Rod Pemberton wrote:
...

> > AIUI, most Forths don't have a control-flow stack separate from the
> > parameter or data stack. They use the data stack for both. Such a
> > simple definition for CONTINUE will not work in such a case since
> > BEGIN's address
> > could be below other stacked data. I.e., how do you locate which
> > stack location has BEGIN's address?
>
> Search for it?

That seems valid, although to be avoided for it's overhead.

> In Gforth, it's a dest-like control-sys, so it is
> identified by the constant "dest" for the top-most element.
>
> : continue ( dest-sys j*sys -- dest-sys j*sys )
> depth 0 ?DO I pick dest = IF
> I cs-item-size / cs-pick postpone AGAIN
> UNLOOP EXIT THEN
> cs-item-size +LOOP
> true abort" no BEGIN found" ;
> immediate compile-only
>
> should do it. I'm not using CS-PICK for the search, since Gforth
> implements a check for the standard's "CS-PICK can only pick dests"
> condition - and well, it's faster that way, too.
>
> This will jump to the next-outer BEGIN. You can theoretically stack and
> clean up other data in between, but normally, you don't (and it's not
> adviced to do so), and if you actually do, and CONTINUE breaks, you get
> what you deserve.

My concern with searching for special values, e.g., "dest", is that it's
possible that a non-special value is recognized as a special value. I'll
have to assume it's not an issue for Gforth.


I'm not sure "adviced" is a word. You want "advised". The words "advice"
and "advise" are different. One is an action of providing information. The
other is the provided information content.


Rod Pemberton



Bernd Paysan

unread,
Aug 22, 2012, 10:24:29 AM8/22/12
to
Rod Pemberton wrote:
>> Search for it?
>
> That seems valid, although to be avoided for it's overhead.

This is a moderate compile-time overhead. How many sys-elements on the
stack do you expect?

> My concern with searching for special values, e.g., "dest", is that
> it's
> possible that a non-special value is recognized as a special value.
> I'll have to assume it's not an issue for Gforth.

No, it's just as simple as with any other control-sys: If you want your
control structure to work, *don't mess with the stack*.

> I'm not sure "adviced" is a word. You want "advised". The words
> "advice"
> and "advise" are different. One is an action of providing
> information. The other is the provided information content.

About 20 million search results on Google (compared to 277 for advised),
which means that even native speakers have their troubles. English is
not my native language, a typo here or there is not really a problem.
This is not alt.learn.english, this is comp.lang.forth.

Anton Ertl

unread,
Aug 22, 2012, 10:26:15 AM8/22/12
to
I was led by your mentioning of the common data/control-flow stack
into thinking that you were thinking about non-control-flow items, and
my answer referred to such items.

>Is there really any point to having a CONTINUE which is constrained to be
>used within an un-nested IF-THEN? How often would that be used?

Probably much more often than CONTINUE2 etc., but overall, probably
not that often. As others pointed out, people got by without it in
the last 40 years. They might use it if its there, but we would have
to see about that.

>How
>often would people use it incorrectly?

Not that often. There are few cases when people want to use CONTINUE,
there are even fewer cases when they want to use it inside a nested
IF.

> How could a Forth detect and prevent
>incorrect usage?

BEGIN produces a dest, IF produces an orig, and AGAIN and CS-PICK
consume a dest. Consider the test program:

: CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE
: nonnested begin if continue then until ;
: nested begin if if continue then then until ;

Let's feed this to a Forth system:

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
: CONTINUE 1 CS-PICK POSTPONE AGAIN ; IMMEDIATE ok
: nonnested begin if continue then until ; ok
: nested begin if if continue then then until ;
:3: expected dest, do-dest or scope
: nested begin if if >>>continue<<< then then until ;
Backtrace:
$7FFFF69F1988 throw
$7FFFF6A01848 c(abort")
$7FFFF6A01A00 non-orig?
$7FFFF6A44318 CS-PICK

So here the CS-PICK in CONTINUE detected that it did not get what it
expected.

>FYI, neither 'break' nor 'continue' are constrained like that in C...

Forth is not C. What else is new?

Bernd Paysan showed you can have a C-like CONTINUE on one particular
Forth system. There is no easy standard way to achieve this.

BTW, the next version of Gforth will have a cute feature that's
relevant in that context: It extends CASE to be a general control flow
construct that can also loop in various ways:

case
... ?of ... endof \ continues after ENDCASE/NEXTCASE
... ?of ... contof \ continues at CASE
... ?of ... endof \ continues after ENDCASE/NEXTCASE
...
nextcase \ loop back to CASE

I am not sure if this will be a much-used feature, but I have seen
several multi-WHILE loops and used one myself occasionally, and this
appears to be a cleaner alternative to me.

Elizabeth D. Rather

unread,
Aug 22, 2012, 1:20:15 PM8/22/12
to
On 8/22/12 1:46 AM, Rod Pemberton wrote:
> "Elizabeth D. Rather" <era...@forth.com> wrote in message
> news:he6dnab1PPQjGqnN...@supernews.com...
>> On 8/21/12 6:53 PM, Rod Pemberton wrote:
...
>>> Aren't you ignoring the fact that there could be other control words
>>> placing data on the stack? E.g., what if COTINUE is used within
>>> nested IF-THENs. CONTINUE as Coos coded it requires that the
>>> address it uses be in a specific stack position. However, the
>>> programmer determines which control words and how many come
>>> prior to it's use. Are you going to modify all control words,
>>> similar to WHILE, to preserve that location just to use CONTINUE?
>>
>> If your control-flow is that complicated, you need to factor differently.
>>
>
> I'll take it that you mean "you" and "your" in a generic sense and not me
> personally.

Of course.

> Yes, needing to factor more might be true... Forth may have sufficient
> control-flow words already. I don't know for sure. I do know it seems like
> it has enough already. And, in one case, I think has some words it doesn't
> need.
>
> Even so, it seems to me that CONTINUE isn't of much value if it can't be
> used within nested IF-THENs. Something similar to the opposite of LEAVE is
> probably what CONTINUE needs to be, if it's of any value.

Forth style is short, simple definitions. The architecture of Forth is
designed to minimize the cost of calls, to encourage this. This is why,
for example, that only I and J are supported for getting DO ... LOOP
indexes, not K, L, etc. (and there was some objection to including J
back in the day) Complicated control flow is contrary to the simple
style characteristic of Forth. It's a different programming style, to be
sure, just as use of an explicit stack is different, but it's amazingly
productive once you master it.

If you are struggling with complex control flow in your definition, the
solution is to simplify the definition by factoring or different design,
not to make new control structures.

hughag...@yahoo.com

unread,
Aug 22, 2012, 11:04:50 PM8/22/12
to
On Wednesday, August 22, 2012 4:43:03 AM UTC-7, Rod Pemberton wrote:
> <hughag...@yahoo.com> wrote in message
> > Normally every control-flow datum includes a code number to indicate
> > what kind of control-flow datum it is. CONTINUE can search back into
> > the control-flow stack with CS-PICK to find its BEGIN datum. There
> > may be several items on top of it.
>
> Normally ... ? Somehow, I doubt that that is anywhere near a "normal"
> implementation. So, for which Forth is this?

AFAIK, every Forth system does this. The code number is mostly used for catching bugs involving mismatched control-flow statements. For example, if you have an IF structure inside of a BEGIN loop and you forget your THEN, this will result in REPEAT aborting with an error message when it discovers an IF datum on the control-flow stack rather than the BEGIN datum that it was expecting.

Your CONTINUE and BREAK will have to search back through the data on the control-flow stack until they find a BEGIN datum that they can use --- this is the innermost BEGIN loop --- there may be one or more IF datums or whatnot on top of this BEGIN datum that have to be left in place.

> That is a tracking method as I mentioned. The use of a code number also
> seems overly complicated, i.e., a primitive type system for control-flow
> data. The code will prevent mistaking one type of control-flow datum from
> another, but how do you prevent mistaking a control-flow datum for non
> control-flow datums in the first place? E.g., separate control-flow stack?

This is not "overly complicated" --- this is simple. Every datum on the control-flow stack has a unique code number. Those data are just records and they each have a field called .KIND or some such thing. Yes, this is another advantage of having a separate control-flow stack --- when control-flow data and other kinds of data are mixed together on the data stack it is possible for them to get mixed up.

Anton's CONTINUE2 is the most ridiculous thing I've ever heard of. The programmer is supposed to count on his fingers how many IF or CASE statements are wrapped around his CONTINUE so he knows if he should use CONTINUE, CONTINUE2, CONTINUE3, etc.? I don't know what is going on with that guy --- his ideas these days are really weird, even by comp.lang.forth standards which aren't high.

Gerry Jackson

unread,
Aug 24, 2012, 12:34:34 PM8/24/12
to
On 22/08/2012 15:26, Anton Ertl wrote:

> BTW, the next version of Gforth will have a cute feature that's
> relevant in that context: It extends CASE to be a general control flow
> construct that can also loop in various ways:
>
> case
> ... ?of ... endof \ continues after ENDCASE/NEXTCASE
> ... ?of ... contof \ continues at CASE
> ... ?of ... endof \ continues after ENDCASE/NEXTCASE
> ...
> nextcase \ loop back to CASE
>
I like the idea, similar to an IT ... TI discussed in c.l.f archives but
merged into the existing CASE structure.

Will NEXTCASE have the run-time stack effect (x -- ) like ENDCASE and
VFX Forth's NEXTCASE or will it be ( -- ) like VFX Forth's NEXT-CASE

Presumably ?OF run-time will be ( f -- )

Isn't there a better name than CONTOF e.g. REPEATCASE or even CONTINUE


--
Gerry

Anton Ertl

unread,
Aug 24, 2012, 12:50:34 PM8/24/12
to
Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes:
>On 22/08/2012 15:26, Anton Ertl wrote:
>
> > BTW, the next version of Gforth will have a cute feature that's
> > relevant in that context: It extends CASE to be a general control flow
> > construct that can also loop in various ways:
> >
> > case
> > ... ?of ... endof \ continues after ENDCASE/NEXTCASE
> > ... ?of ... contof \ continues at CASE
> > ... ?of ... endof \ continues after ENDCASE/NEXTCASE
> > ...
> > nextcase \ loop back to CASE
> >
>I like the idea, similar to an IT ... TI discussed in c.l.f archives but
>merged into the existing CASE structure.
>
>Will NEXTCASE have the run-time stack effect (x -- ) like ENDCASE and
>VFX Forth's NEXTCASE

Yes, it has ( x -- ) to be compatible with VFX. Probably not that
sensible when used with ?OF (which will usually be the case when using
NEXTCASE).

> or will it be ( -- ) like VFX Forth's NEXT-CASE

Maybe we should provide NEXT-CASE *instead of* NEXTCASE.

>Presumably ?OF run-time will be ( f -- )

Yes.

>Isn't there a better name than CONTOF e.g. REPEATCASE or even CONTINUE

As usual, everyone will have their own idea for a better name; If you
reach consensus on a good name, I'll happily adopt it. The reason for
CONTOF is: The OF part indicates that this ends an OF (like ENDOF).
The CONT part indicates that we continue at the start (like C's
continue).

Mark Wills

unread,
Aug 24, 2012, 4:47:04 PM8/24/12
to
On Aug 24, 5:50 pm, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
CONTCASE

?

Ed

unread,
Aug 25, 2012, 1:50:32 AM8/25/12
to
hughag...@yahoo.com wrote:
> ...
> Anton's CONTINUE2 is the most ridiculous thing I've ever heard of. The programmer is
> supposed to count on his fingers how many IF or CASE statements are wrapped around his
> CONTINUE so he knows if he should use CONTINUE, CONTINUE2, CONTINUE3, etc.? I don't know
> what is going on with that guy --- his ideas these days are really weird, even by
> comp.lang.forth standards which aren't high.

It is incongruous to see proposals for CONTINUE, CONTINUE2,
CONTINUE3 coming from folks who campaign against LOCALS|
for no other reason than the parameter order offends them, or
who find floats on the data stack so appalling that they ensure
no-one can use it despite such practice existing since early days.

Even if one can't believe what one reads on c.l.f., it is entertaining.



m...@iae.nl

unread,
Aug 25, 2012, 1:51:43 AM8/25/12
to
On Friday, August 24, 2012 10:47:04 PM UTC+2, Mark Wills wrote:
[..]
> CONTCASE ?

In Dutch it might have connotations that are a little bit embarassing.

-marcel

Elizabeth D. Rather

unread,
Aug 25, 2012, 3:03:34 AM8/25/12
to
On 8/24/12 7:50 PM, Ed wrote:
>
> It is incongruous to see proposals for CONTINUE, CONTINUE2,
> CONTINUE3 coming from folks who campaign against LOCALS|
> for no other reason than the parameter order offends them, or
> who find floats on the data stack so appalling that they ensure
> no-one can use it despite such practice existing since early days.
>
> Even if one can't believe what one reads on c.l.f., it is entertaining.

So, significant programs have been written in Forth for, as I now count,
>40 years with no need for CONTINUE, and now we have CONTINUE3? Ok, so
some folks think it's fun to accept a challenge and invent something
whether it's needed or not, but I find it hard to get excited about it.

Coos Haak

unread,
Aug 25, 2012, 4:40:21 AM8/25/12
to
Op Sat, 25 Aug 2012 15:50:32 +1000 schreef Ed:
A silly extension might be
: ]CONTINUE ] CS-PICK POSTPONE AGAIN ; IMMEDIATE

Usage:

begin .. [ 0 ]continue ..
.. if [ 1 ]continue then ..
.. if if [ 2 ]continue then then ..
again

Finally, the computer uses the programmer to count on his fingers!

--
Coos

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

Anton Ertl

unread,
Aug 25, 2012, 4:55:23 AM8/25/12
to
Mark Wills <markrob...@yahoo.co.uk> writes:
>CONTCASE

would suggest to me that it pairs with CASE.

hughag...@yahoo.com

unread,
Aug 25, 2012, 11:47:21 PM8/25/12
to
On Friday, August 24, 2012 1:47:04 PM UTC-7, Mark Wills wrote:
>
> CONTCASE
>
> ?

Wasn't that the heroine in The Hunger Games?

Seriously, abbreviating words is a bad idea, and pasting words together without benefit of a hyphen is another bad idea --- although that is done in the German language all the time, which is the PERL of human languages.

I don't like CASE at all. You tend to get gigantic functions that do several different things depending upon a code number that is passed into them that they check at run-time --- a complete violation of the Forth principle of having each function be short and do only one thing (remember the "universal processor" in the "Thinking Forth" book?). It is very difficult to test functions like that. Whenever I see programs featuring a big CASE, they are almost always C programs that have been ported to Forth and/or they were written by recalcitrant C programmers (which is pretty much what Anton Ertl is) --- the SWITCH statement is the foundation of C programming, where it is common to see a single SWITCH statement spanning hundreds of lines of source-code.

When I worked at Testra my boss liked to use CASE. He was a hardware designer and he tended to think in terms of state-machines, which is what hardware is all about. This doesn't work very well for software though.

P.S. --- Another thing that recalcitrant C programmers do is ignore compile-time altogether and just treat Forth like C with RPN syntax. Recently Anton Ertl argued against my suggestion that the control-flow stack be separate from the data stack. He said that it is "convenient" to use the data stack for control-flow stuff because nobody ever uses it for passing parameters into colon words at compile-time that will be picked up by LITERAL. It is obvious that he has never written colon words that execute at compile-time and generate other colon words --- but that is the essence of Forth programming! If you are not going to do that, then you might as well just program in C.

Rod Pemberton

unread,
Aug 26, 2012, 6:20:41 AM8/26/12
to
<hughag...@yahoo.com> wrote in message
news:4de58c99-d87e-4851...@googlegroups.com...

> [...] Whenever I see programs featuring a big CASE, they are
> almost always C programs that have been ported to Forth
> and/or they were written by recalcitrant C programmers [...]
> --- the SWITCH statement is the foundation of C programming,
> where it is common to see a single SWITCH statement spanning
> hundreds of lines of source-code.

Well, it's definately not "the foundation" of C programming. Switches are
not as common in C code as other control-flow. However, it's definately
true some C programmers seem to embrace C's switch() much more than they
ever should. I see excessively switched programs from time to time too.
I also see programmers embrace C's for() too much. etc.

FYI, ANSI C89/90 allows 257 and ISO C99 allows 1023 items in a switch.
So, switches were designed to allow easy selection of a relatively "large"
number of items (at the time).

Personally, I think it's far more common to see a switch() with just a
handful of items, followed by maybe 20 to 50 items. From what I've seen,
the truly large switches are used with a large input set of non-contiguous
integer values. If the set of input integer values is contiguous, you don't
need a switch. You can use an array.

The largest switch I have in C has 356 items. Why so many? Well, there are
356 different valid input text strings. The switch is given an integer from
a hash function on the input string. This produces 356 different 32-bit
integers. The integer values are not adjacent to each other. There are no
hash collisions on that set of strings. That makes the switch() ideal.
Otherwise, you're using many if's.

That large switch is relatively recent. Most of mine are much smaller.
What I think is my next largest switch has 100 items. That's still many.
It too is tasked with separating strings from each other. It uses a simple
hash function which has a few collisions that must be corrected.

Another option in C is similar, switch based on the first character of the
string which reduces you to 26 or 52 switch items, but then you need to do a
bunch of string compares using if's, e.g., if you switched on 'r', you still
need to separate "return" from "register". 356/26=14. So, if the strings
were evenly distributed, which they aren't, you'd need an average of 14 if's
per case. Obviously, that means you're likely to see one case with 28 or
similar larger set of strings ... That would encourage using a hash
function in the first place.

The "worst" option in C is to loop through a string array and compare every
string until the one you're looking for is found. I.e., like searching the
dictionary in a simple interpreted Forth. The loop is to equate the string
to a sequential integer index, i.e., one value from a contiguous set of
integer values.

The need to determine one string from another and take action for a specific
string is needed for parsers and interpreters.

How would you handle code selection for 356 different input strings in
Forth?


Rod Pemberton



Ed

unread,
Aug 26, 2012, 8:13:13 AM8/26/12
to
Elizabeth D. Rather wrote:
> On 8/24/12 7:50 PM, Ed wrote:
> >
> > It is incongruous to see proposals for CONTINUE, CONTINUE2,
> > CONTINUE3 coming from folks who campaign against LOCALS|
> > for no other reason than the parameter order offends them, or
> > who find floats on the data stack so appalling that they ensure
> > no-one can use it despite such practice existing since early days.
> >
> > Even if one can't believe what one reads on c.l.f., it is entertaining.
>
> So, significant programs have been written in Forth for, as I now count,
> >40 years with no need for CONTINUE, and now we have CONTINUE3? Ok, so
> some folks think it's fun to accept a challenge and invent something
> whether it's needed or not, but I find it hard to get excited about it.

That may be but ANS let the conditionals cat out of the bag long ago.

Had ANS *not* accepted Wil Baden's proposition that Forth needed
a GOTO there might be no CS-PICK CS-ROLL or separate CFS.
But it did. And far from discouraging users, ANS suggested several
new conditionals based on the new words!

ANS wasn't at all adverse to adding conditionals to Forth. It provided
the Eaker CASE despite the known limitations. Others augmented
it with BEGINCASE NEXTCASE ?OF etc. Nor will these be the last.
A better way is to provide the tools and let users define whatever
conditionals they believe they need.



Ed

unread,
Aug 26, 2012, 8:33:29 AM8/26/12
to
hughag...@yahoo.com wrote:
> ...
> First Anton Ertl says that
> people don't put data on the stack during compilation

Classically the data stack has been used to pass conditionals
information.

Conditionals occur frequently during compilation and their number
is indeterminate. The data stack is ideal for that. For the few
occasions other data must be passed, variables have sufficed
e.g. RECURSE gets what it needs from variable LAST.



Andrew Haley

unread,
Aug 26, 2012, 12:04:22 PM8/26/12
to
Rod Pemberton <do_no...@notemailnot.cmm> wrote:
>
> How would you handle code selection for 356 different input strings in
> Forth?

If you want an exact string match followed by an action, FIND and
EXECUTE is probably a good choice.

Andrew.

Anton Ertl

unread,
Aug 26, 2012, 12:06:54 PM8/26/12
to
SEARCH-WORDLIST is a better choice than FIND: No need to worry about
additional words in other wordlists.

Andrew Haley

unread,
Aug 26, 2012, 4:32:32 PM8/26/12
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Rod Pemberton <do_no...@notemailnot.cmm> wrote:
>>>
>>> How would you handle code selection for 356 different input strings in
>>> Forth?
>>
>>If you want an exact string match followed by an action, FIND and
>>EXECUTE is probably a good choice.
>
> SEARCH-WORDLIST is a better choice than FIND: No need to worry about
> additional words in other wordlists.

True enough, but it makes no difference to the core point about Forth
design: use the tools that are already there. I've seen programs that
re-invent the dictionary, which shows this advice is not obvious!

Andrew.

Gerry Jackson

unread,
Aug 26, 2012, 5:07:55 PM8/26/12
to
To experiment with your extended CASE I have implemented it in ANS
Forth, the code with tests is below. All CASE words have to be rewritten
because the new CASE has to leave a dest on the control flow stack
(CFS). It is a modified version of the code in section A.3.2.2.2 of the
ANS Forth standard. It is quite straightforward, words have to deal with
the extra dest on the CFS. The only messy bit is how ENDCASE handles
that extra dest as ANS Forth doesn't have a CS-DROP. The only way I
could think of was to compile a jump back to the dest but hide it by
placing a forward jump in front of it to skip over it, which is
inefficient. Perhaps optimising compilers will detect this dead code.

I've kept to the name CONTOF but still don't like it, I'm not very keen
on NEXTCASE either. I've introduced ?BREAK to avoid the empty ?OF ENDOF
which simply exits the CASE structure.

The tests work on GForth, VFX Forth, SwiftForth, Win32 Forth and
BigForth but fails with a 'structure not balanced' error on iForth 4.0.380

-------------------------------------------------------
: case ( -- dest 0 ) postpone begin 0 ; immediate

: cs-swap ( orig1/dest1 orig2/dest2 -- orig2/dest2 orig1/dest1 )
1 cs-roll
;

: of ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
>r
postpone over postpone = postpone if postpone drop
cs-swap r> 1+
; immediate

: ?of ( dest #of -- orig dest #of+1 ) \ run-time ( f -- )
>r postpone if cs-swap r> 1+
; immediate

: endof ( orig dest #of -- orig2 dest #of ) \ run-time ( -- )
>r cs-swap postpone else cs-swap r>
; immediate

\ ?break is equivalent to an empty ?OF ENDOF
: ?break ( dest #of -- orig dest #of+1 ) \ run-time ( f -- )
>r postpone 0= postpone if cs-swap r> 1+
; immediate

: contof ( orig dest #of -> dest #of-1 ) \ run-time ( -- )
>r
0 cs-pick postpone again cs-swap postpone then
r> 1-
; immediate

: resolve-origs ( orig1 ... orign n -- )
0 ?do postpone then loop
;

: endcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>r postpone drop postpone ahead cs-swap postpone again
r> 1+ resolve-origs
; immediate

: nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>r postpone drop postpone again r> resolve-origs
; immediate

\ Tests require the Hayes tester or derivatives of it

testing CASE OF ENDOF ENDCASE

t{ : cs1 case 1 of 111 endof
2 of 222 endof
3 of 333 endof
>r 999 r>
endcase
; -> }t

t{ 1 cs1 -> 111 }t
t{ 2 cs1 -> 222 }t
t{ 3 cs1 -> 333 }t
t{ 4 cs1 -> 999 }t

\ Nested CASE's

t{ : cs2 >r case -1 of case r@ 1 of 100 endof
2 of 200 endof
>r -300 r>
endcase
endof
-2 of case r@ 1 of -99 endof
>r -199 r>
endcase
endof
>r 299 r>
endcase r> drop
; -> }t

t{ -1 1 cs2 -> 100 }t
t{ -1 2 cs2 -> 200 }t
t{ -1 3 cs2 -> -300 }t
t{ -2 1 cs2 -> -99 }t
t{ -2 2 cs2 -> -199 }t
t{ 0 2 cs2 -> 299 }t

testing ?of

t{ : cs3 ( n1 -- n2 )
case dup 1 = ?of 11 endof
dup 2 = ?of 22 endof
dup 3 = ?of 33 endof
44 over
endcase nip
; -> }t

t{ 1 cs3 -> 11 }t
t{ 2 cs3 -> 22 }t
t{ 3 cs3 -> 33 }t
t{ 9 cs3 -> 44 }t

testing nextcase

t{ : cs4 ( n1 -- n+ )
case 1 of 11 endof
2 of 22 endof
3 of 33 endof
44 swap 3 + dup
nextcase
; -> }t

t{ 0 cs4 -> 44 33 }t
t{ -1 cs4 -> 44 22 }t
t{ -2 cs4 -> 44 11 }t
t{ -3 cs4 -> 44 44 33 }t

testing contof

t{ : cs5 ( n1 -- n2 )
case 1 of 11 2 contof
dup 2 = ?of drop 22 4 contof
3 of 33 endof
44 3 rot
nextcase
; -> }t

t{ 1 cs5 -> 11 22 44 33 }t

testing ?break

t{ : cs6 ( n1 -- n ... n )
case 1+
dup 3 > ?break
dup 1 of 11 swap contof
2 of 22 swap contof
3 of 33 swap contof
44 -rot
nextcase drop
; -> }t

t{ 0 cs6 -> 11 22 33 }t
t{ -1 cs6 -> 44 11 22 33 }t
t{ -2 cs6 -> 44 44 11 22 33 }t

t{ : cs7 ( n1 -- n ... n )
case 1+
dup 3 > ?break
dup >r
0> ?of case r@ 1 of 11 endof
2 of 22 endof
3 of 33 endof
endcase r>
contof
44 r> dup
nextcase drop
; -> }t

t{ 0 cs7 -> 11 22 33 }t
t{ -1 cs7 -> 44 11 22 33 }t
t{ -2 cs7 -> 44 44 11 22 33 }t

--
Gerry





Marcel Hendrix

unread,
Aug 27, 2012, 12:14:42 PM8/27/12
to
Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?

> On 24/08/2012 17:50, Anton Ertl wrote:
>> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes:
>>> On 22/08/2012 15:26, Anton Ertl wrote:
[..]

> The tests work on GForth, VFX Forth, SwiftForth, Win32 Forth and
> BigForth but fails with a 'structure not balanced' error on iForth 4.0.380
[..]

With the following extra lines at the top of gerry.frt:

-----
ANEW -gerry

NEEDS -ttester
SECURE OFF VERBOSE ON
----

... we can do

FORTH> in c:/idfwforth/examples/internet/idata/gerry
Creating --- John Hopkins TESTER Version 2.00 ---
Redefining case
Redefining of
Redefining endof
Redefining endcase
testing CASE OF ENDOF ENDCASE
testing ?of
testing nextcase
testing contof
testing ?break

I don't recommend turning of SECURE .

-marcel

Gerry Jackson

unread,
Aug 27, 2012, 1:22:18 PM8/27/12
to
On 27/08/2012 17:14, Marcel Hendrix wrote:
> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?
>
>> On 24/08/2012 17:50, Anton Ertl wrote:
>>> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes:
>>>> On 22/08/2012 15:26, Anton Ertl wrote:
> [..]
>
>> The tests work on GForth, VFX Forth, SwiftForth, Win32 Forth and
>> BigForth but fails with a 'structure not balanced' error on iForth 4.0.380
> [..]
>
> With the following extra lines at the top of gerry.frt:
>
> -----
> ANEW -gerry
>
> NEEDS -ttester
> SECURE OFF VERBOSE ON
> ----
>
> .... we can do
>
> FORTH> in c:/idfwforth/examples/internet/idata/gerry
> Creating --- John Hopkins TESTER Version 2.00 ---
> Redefining case
> Redefining of
> Redefining endof
> Redefining endcase
> testing CASE OF ENDOF ENDCASE
> testing ?of
> testing nextcase
> testing contof
> testing ?break
>
> I don't recommend turning of SECURE .
>

That's interesting, I now see that is mentioned in the manual. Why is
this necessary for iForth but not for other ANS Forth systems? Only
origs and a dest are on the CFS when CS-PICK and CS-ROLL are used so
ISTM that SECURE on makes iForth non-compliant with ANS Forth when
manipulating the control flow stack.

--
Gerry

Marcel Hendrix

unread,
Aug 27, 2012, 2:45:47 PM8/27/12
to
Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?

> On 27/08/2012 17:14, Marcel Hendrix wrote:
>> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?
[..]
> I don't recommend turning off SECURE .
[..]
> That's interesting, I now see that is mentioned in the manual. Why is
> this necessary for iForth but not for other ANS Forth systems? Only
> origs and a dest are on the CFS when CS-PICK and CS-ROLL are used so
> ISTM that SECURE on makes iForth non-compliant with ANS Forth when
> manipulating the control flow stack.

[..]

Well, it is (obviously) not necessary for iForth to have SECURE on. The
reason SECURE is on is painful memories of trying to compile large NOVIX
block files.

The SECURE feature can be permanently turned off by editing the
iforth.prf file.

Why don't other Forths have SECURE? They may have a fail-safe mechanism
to catch silly errors that does not interfere with their CS-PICK etc.

But ...

-- -------------------------------
VFX Forth for Windows IA32
� MicroProcessor Engineering Ltd, 1998-2012

Version: 4.50 [build 3327]
Build date: 17 April 2012

Free dictionary = 7561806 bytes [7384kb]


: test begin 1 2 + else 3 then ; ok
-- --------------------------------------

-- ----------------------------------------------------
SwiftForth i386-Win32 3.2.2 08-Jul-2010
base @ hex : testing again 10 20 + begin ; decimal ok
-- ----------------------------------------------------

... apparently passes unnoticed.


(gForth can't be caught that easily.)

Another reason for iForth's SECURE is that the compiler uses
extra items on the CS stack to remember when registers should
be spilled/loaded to/from the stacks for control flow nodes.

Yet another reason is the somewhat complicated parallel
programming structures.

These extra CS items can be used to give better messages, but as
that is not ANS compatible, there must be a way to turn them off.

I am not claiming that having extra items on the CS stack is the only
way to get the mentioned features.

-marcel

Gerry Jackson

unread,
Aug 27, 2012, 4:43:42 PM8/27/12
to
On 27/08/2012 19:45, Marcel Hendrix wrote:
> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?
>
>> On 27/08/2012 17:14, Marcel Hendrix wrote:
>>> Gerry Jackson <ge...@jackson9000.fsnet.co.uk> writes Re: continue equivalent in Forth?
> [..]
>> I don't recommend turning off SECURE .
> [..]
>> That's interesting, I now see that is mentioned in the manual. Why is
>> this necessary for iForth but not for other ANS Forth systems? Only
>> origs and a dest are on the CFS when CS-PICK and CS-ROLL are used so
>> ISTM that SECURE on makes iForth non-compliant with ANS Forth when
>> manipulating the control flow stack.
>
> [..]
>
> Why don't other Forths have SECURE? They may have a fail-safe mechanism
> to catch silly errors that does not interfere with their CS-PICK etc.
>
> But ...
>
> -- -------------------------------
> VFX Forth for Windows IA32
> © MicroProcessor Engineering Ltd, 1998-2012
>
> Version: 4.50 [build 3327]
> Build date: 17 April 2012
>
> Free dictionary = 7561806 bytes [7384kb]
>
>
> : test begin 1 2 + else 3 then ; ok
> -- --------------------------------------
>
> -- ----------------------------------------------------
> SwiftForth i386-Win32 3.2.2 08-Jul-2010
> base @ hex : testing again 10 20 + begin ; decimal ok
> -- ----------------------------------------------------
>
> .... apparently passes unnoticed.
>
>
> (gForth can't be caught that easily.)

Heh, even my system rejects rubbish like that, still I don't suppose
those systems often encounter code like that.
>
> Another reason for iForth's SECURE is that the compiler uses
> extra items on the CS stack to remember when registers should
> be spilled/loaded to/from the stacks for control flow nodes.
>
> Yet another reason is the somewhat complicated parallel
> programming structures.
>
> These extra CS items can be used to give better messages, but as
> that is not ANS compatible, there must be a way to turn them off.
>

Thanks for that, I assumed there must be good reasons and I was
interested to know what they were.

--
Gerry

Elizabeth D. Rather

unread,
Aug 27, 2012, 6:15:43 PM8/27/12
to
On 8/27/12 8:45 AM, Marcel Hendrix wrote:
...
>
> Why don't other Forths have SECURE? They may have a fail-safe mechanism
> to catch silly errors that does not interfere with their CS-PICK etc.
>
> But ...
>
> -- -------------------------------
> VFX Forth for Windows IA32
> © MicroProcessor Engineering Ltd, 1998-2012
>
> Version: 4.50 [build 3327]
> Build date: 17 April 2012
>
> Free dictionary = 7561806 bytes [7384kb]
>
>
> : test begin 1 2 + else 3 then ; ok
> -- --------------------------------------
>
> -- ----------------------------------------------------
> SwiftForth i386-Win32 3.2.2 08-Jul-2010
> base @ hex : testing again 10 20 + begin ; decimal ok
> -- ----------------------------------------------------
>
> ... apparently passes unnoticed.

Hmmm:

SwiftForth i386-Mac OS X 3.4.2 11-Feb-2012
: test begin 1 2 + else 3 then ; Control structure mismatch

Hugh Aguilar

unread,
Aug 28, 2012, 1:58:06 AM8/28/12
to
On Aug 26, 1:32 pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> > Andrew Haley <andre...@littlepinkcloud.invalid> writes:
> >>Rod Pemberton <do_not_h...@notemailnot.cmm> wrote:
>
> >>> How would you handle code selection for 356 different input strings in
> >>> Forth?
>
> >>If you want an exact string match followed by an action, FIND and
> >>EXECUTE is probably a good choice.
>
> > SEARCH-WORDLIST is a better choice than FIND: No need to worry about
> > additional words in other wordlists.
>
> True enough, but it makes no difference to the core point about Forth
> design: use the tools that are already there.  I've seen programs that
> re-invent the dictionary, which shows this advice is not obvious!
>
> Andrew.

My ASSOCIATION in the novice package does pretty much the same thing
that the dictionary does. The advantage is that allows you to do an in-
order traversal of the nodes within a particular region. If the
ordering of your data isn't important though, then you don't need this
feature so you might as well use the dictionary. Another advantage of
ASSOCIATION is that it can use key data other than strings, such as
floats for example --- once again, if you are just using strings, then
the dictionary should work. Another advantage of ASSOCIATION is that
it can be used in cross-compiled code in which the dictionary is not
available at run-time.

I've used the dictionary as an associative array myself in the past
--- in my 65c02 source-level debugger for example.

Anton Ertl

unread,
Aug 28, 2012, 11:56:04 AM8/28/12
to
m...@iae.nl (Marcel Hendrix) writes:
>Why don't other Forths have SECURE?

What does SECURE do? Why should we have it?

>: test begin 1 2 + else 3 then ; ok
...
>(gForth can't be caught that easily.)

: test begin 1 2 + else 3 then ;
:1: expected orig
: test begin 1 2 + >>>else<<< 3 then ;

So Gforth usually notices when it does not get an orig, but something
else, and likewise it will complain if you pass it an orig while it
expects a dest. And every Forth-94 system is allowed to do this kind
of checking, as well as checking for unbalanced control flow stack,
e.g.:

: foo if ;
:2: unstructured
: foo if >>>;<<<

What does SECURE add? Is it worth the price of not being able to run
standard programs like Josh Grams implementation of CASE etc.?

>Another reason for iForth's SECURE is that the compiler uses
>extra items on the CS stack to remember when registers should
>be spilled/loaded to/from the stacks for control flow nodes.

Gforth uses larger CS items to remember which locals are alive at a
branch (orig) or branch target (dest); can be done nicely in a
Forth-94 compatible way, and I guess that's also true for your
register information. What do you do if SECURE is OFF?

>These extra CS items can be used to give better messages, but as
>that is not ANS compatible, there must be a way to turn them off.

Yes the error messages of Gforth could be better, e.g., the first one
could be "control structure mismatch, expected orig".

Marcel Hendrix

unread,
Aug 28, 2012, 2:35:48 PM8/28/12
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?

> m...@iae.nl (Marcel Hendrix) writes:
>>Why don't other Forths have SECURE?

> What does SECURE do? Why should we have it?
[..]
> : foo if ;
> :2: unstructured
> : foo if >>>;<<<
[..]

Why is gForth complaining?

IF C CORE
Compilation: ( -- orig )
Put the location of a new unresolved forward reference orig onto the
control flow stack. Append the execution semantics given below to the
current definition. The semantics are incomplete until orig is resolved
(e.g., by THEN ).
Execution: ( x -- )
If all bits of x are zero, continue execution at the location specified
by the resolution of orig.
See also: ELSE THEN


I see nothing here that allows an error message.

iForth:

FORTH> secure off ok
FORTH> : test if ; ok
[3]FORTH>

How to do this in gForth?

-marcel

Marcel Hendrix

unread,
Aug 28, 2012, 2:43:47 PM8/28/12
to
"Elizabeth D. Rather" <era...@forth.com> writes Re: continue equivalent in Forth?

> On 8/27/12 8:45 AM, Marcel Hendrix wrote:
[..]
>> -- ----------------------------------------------------
>> SwiftForth i386-Win32 3.2.2 08-Jul-2010
>> base @ hex : testing again 10 20 + begin ; decimal ok
>> -- ----------------------------------------------------

>> ... apparently passes unnoticed.

> Hmmm:

> SwiftForth i386-Mac OS X 3.4.2 11-Feb-2012
> : test begin 1 2 + else 3 then ; Control structure mismatch

Hmmm? That is the VFX bug. What about the SwiftForth example
above:

SwiftForth i386-Win32 3.4.2 11-Feb-2012
base @ hex : testing again 10 20 + begin ; decimal ok

Or do you imply that the OSX version of SwiftForth doesn't have
the bug?

-marcel



Ed

unread,
Aug 29, 2012, 3:10:32 AM8/29/12
to
Marcel Hendrix wrote:
> ..
> Hmmm? That is the VFX bug. What about the SwiftForth example
> above:
>
> SwiftForth i386-Win32 3.4.2 11-Feb-2012
> base @ hex : testing again 10 20 + begin ; decimal ok
>
> Or do you imply that the OSX version of SwiftForth doesn't have
> the bug?

Nice. Even DX-Forth swallows it :)

Idiot-proofing has not been necessary in Forth. Are you saying
it's time to reconsider?





Ed

unread,
Aug 29, 2012, 4:29:09 AM8/29/12
to
Coos Haak wrote:
> ...
> A silly extension might be
> : ]CONTINUE ] CS-PICK POSTPONE AGAIN ; IMMEDIATE
>
> Usage:
>
> begin .. [ 0 ]continue ..
> .. if [ 1 ]continue then ..
> .. if if [ 2 ]continue then then ..
> again
>
> Finally, the computer uses the programmer to count on his fingers!

But would you use it.

CASE was invented because it did away with users having to count
THENs.



Coos Haak

unread,
Aug 29, 2012, 3:26:19 PM8/29/12
to
Op Wed, 29 Aug 2012 18:29:09 +1000 schreef Ed:

> Coos Haak wrote:
>> ...
>> A silly extension might be
>>: ]CONTINUE ] CS-PICK POSTPONE AGAIN ; IMMEDIATE
>>
>> Usage:
>>
>> begin .. [ 0 ]continue ..
>> .. if [ 1 ]continue then ..
>> .. if if [ 2 ]continue then then ..
>> again
>>
>> Finally, the computer uses the programmer to count on his fingers!
>
> But would you use it.
>
The word 'silly' is not without signification...
BTW, as ] starts compiling, IMMEDIATE can be omitted.

> CASE was invented because it did away with users having to count
> THENs.
Yes.

Anton Ertl

unread,
Aug 30, 2012, 8:32:52 AM8/30/12
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?
>
>> m...@iae.nl (Marcel Hendrix) writes:
>>>Why don't other Forths have SECURE?
>
>> What does SECURE do? Why should we have it?
>[..]
>> : foo if ;
>> :2: unstructured
>> : foo if >>>;<<<
>[..]
>
>Why is gForth complaining?
>
>IF C CORE
...
>I see nothing here that allows an error message.

You are looking in the wrong place. If you look closely, you will
notice that it's the ";" that complained, not the IF. So let's look
at ";":

|6.1.0460 ;
|[...]
| Compilation: ( C: colon-sys -- )

So it is complaining, because there is something other than a
colon-sys on top of the control-flow stack.

>iForth:
>
>FORTH> secure off ok
>FORTH> : test if ; ok
>[3]FORTH>
>
>How to do this in gForth?

Do what? What is this supposed to mean? I can make something like
this piece of code compile without the compiler complaining with:

: test if [ 2drop drop ] ;

but somehow

: test drop ;

will work for the same cases (and one more) and seems more
straightforward.

Marcel Hendrix

unread,
Aug 30, 2012, 4:39:42 PM8/30/12
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?

> m...@iae.nl (Marcel Hendrix) writes:
>>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?
[..]
> You are looking in the wrong place. If you look closely, you will
> notice that it's the ";" that complained, not the IF. So let's look
> at ";":

> |6.1.0460 ;
> |[...]
> | Compilation: ( C: colon-sys -- )

> So it is complaining, because there is something other than a
> colon-sys on top of the control-flow stack.

>>iForth:

>>FORTH> secure off ok
>>FORTH> : test if ; ok
>>[3]FORTH>

>>How to do this in gForth?

> Do what? What is this supposed to mean? I can make something like
> this piece of code compile without the compiler complaining with:

> : test if [ 2drop drop ] ;

> but somehow

> : test drop ;

> will work for the same cases (and one more) and seems more
> straightforward.

OK, here is the complete example:
a label in a high-level definition (no sugar).

: blah ." blah " ;
: foo ." foo " ;

: aword blah blah blah 0 if ;
: label_001 then foo foo foo ;

FORTH> label_001 foo foo foo ok
FORTH> aword blah blah blah foo foo foo ok

-marcel


Alex McDonald

unread,
Aug 30, 2012, 10:57:32 PM8/30/12
to
: label_001 foo foo foo ;
: aword blah blah blah label_001 ;

Ed

unread,
Aug 31, 2012, 4:27:44 AM8/31/12
to
Marcel Hendrix wrote:
> ...
>
> IF C CORE
> Compilation: ( -- orig )
> Put the location of a new unresolved forward reference orig onto the
> control flow stack. Append the execution semantics given below to the
> current definition. The semantics are incomplete until orig is resolved
> (e.g., by THEN ).
> Execution: ( x -- )
> If all bits of x are zero, continue execution at the location specified
> by the resolution of orig.
> See also: ELSE THEN
>
>
> I see nothing here that allows an error message.

"The [compilation] semantics are incomplete until orig is resolved (e.g., by THEN )."




Anton Ertl

unread,
Aug 31, 2012, 5:14:20 AM8/31/12
to
m...@iae.nl (Marcel Hendrix) writes:
>OK, here is the complete example:
>a label in a high-level definition (no sugar).
>
>: blah ." blah " ;
>: foo ." foo " ;
>
>: aword blah blah blah 0 if ;
>: label_001 then foo foo foo ;
>
>FORTH> label_001 foo foo foo ok
>FORTH> aword blah blah blah foo foo foo ok

The answer specific to this example was posted by Alex MacDonald:

: label_001 foo foo foo ;
: aword blah blah blah label_001 ;

In general, one can organize the words to avoid control structures
crossing words.

But if you really want to do such a thing, here's one way to do it in
Gforth:

: blah ." blah " ;
: foo ." foo " ;
: aword blah blah blah
0 if [ >r >r >r ] ; : label_001 [ r> r> r> ] then
foo foo foo ;

My question about SECURE was actually meant as follows: If SECURE is
on, iForth apparently does not accept some Forth-94-compliant control
structures. What does it offer that is worth that cost?

BTW, your posting would have been easier to read if your newsreader
also put quote characters in front of cited empty lines.

Marcel Hendrix

unread,
Aug 31, 2012, 2:31:18 PM8/31/12
to
Alex McDonald <bl...@rivadpm.com> writes Re: continue equivalent in Forth?

> On Aug 30, 9:39 pm, m...@iae.nl (Marcel Hendrix) wrote:
>> an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?
[..]
>> : blah ." blah " ;
>> : foo ." foo " ;
>
>> : aword blah blah blah 0 if ;
>> : label_001 then foo foo foo ;
>
>> FORTH> label_001 foo foo foo ok
>> FORTH> aword blah blah blah foo foo foo ok
>
> : label_001 foo foo foo ;
> : aword blah blah blah label_001 ;

Sigh.

SECURE OFF

: blah ." blah " ;
: foo ." foo " ;

: aword ( bool -- ) blah blah blah if ;
: label_001 ( -- ) then foo 1 aword foo ;

FORTH> cr 0 aword
blah blah blah foo blah blah blah foo ok
FORTH> cr 1 aword
blah blah blah ok
FORTH> cr label_001
foo blah blah blah foo ok

-marcel

Marcel Hendrix

unread,
Aug 31, 2012, 2:39:23 PM8/31/12
to
"Ed" <inv...@nospam.com> writes Re: continue equivalent in Forth?

> Marcel Hendrix wrote:
>> ...
>>
>> IF C CORE
>> Compilation: ( -- orig )
[..]
>> I see nothing here that allows an error message.

> "The [compilation] semantics are incomplete until orig is resolved (e.g., by THEN )."

So? The following definition is also incomplete.

: foo blah

\ until we type

blah blah ;

-marcel

Marcel Hendrix

unread,
Aug 31, 2012, 3:32:19 PM8/31/12
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?

> m...@iae.nl (Marcel Hendrix) writes:
[..]
> My question about SECURE was actually meant as follows: If SECURE is
> on, iForth apparently does not accept some Forth-94-compliant control
> structures. What does it offer that is worth that cost?

For that cost, you can compile code that other Forths won't.

Of course, it would be better to have gForth-like diagnostics with a
SECURE flag to disable them for exceptional cases. Maybe for the next
redesign -- after my retirement, or when iForth goes open-source :-)

> BTW, your posting would have been easier to read if your newsreader
> also put quote characters in front of cited empty lines.

You actually notice uncited empted lines between all the
quoted-printable crap that has become the standard lately?

-marcel

Alex McDonald

unread,
Aug 31, 2012, 4:49:47 PM8/31/12
to
On Aug 31, 7:30 pm, m...@iae.nl (Marcel Hendrix) wrote:
> Alex McDonald <b...@rivadpm.com> writes Re: continue equivalent in Forth?
Double sigh. That's completely unintelligible. Can you show an example
that might have some (even minor) utility, and some form of
justification for allowing IF and THEN to behave in this non-standard
fashion? Non-standard in then sense of -- wow, how did you manage to
read that into the spec?

Ed

unread,
Sep 1, 2012, 12:28:42 AM9/1/12
to
It looks complete to me!

Resolving orig is part of "standard" IF's compile-time semantics.
It's specified because almost every forth produced since Fig has
compiler security and would complain otherwise.


If anyone is to blame it is the Dutch :) According to Bill Ragsdale
(FD 5V6) he gave variable 31 character names to Utrecht University
and they gave him compiler security ...

"We took the compiler security from their code; until that time,
none of the USA versions had that".



Ed

unread,
Sep 2, 2012, 6:30:18 AM9/2/12
to
Marcel Hendrix wrote:
> an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?
>
> > m...@iae.nl (Marcel Hendrix) writes:
> [..]
> > My question about SECURE was actually meant as follows: If SECURE is
> > on, iForth apparently does not accept some Forth-94-compliant control
> > structures. What does it offer that is worth that cost?
>
> For that cost, you can compile code that other Forths won't.
>
> Of course, it would be better to have gForth-like diagnostics with a
> SECURE flag to disable them for exceptional cases. Maybe for the next
> redesign -- after my retirement, or when iForth goes open-source :-)

Another ANS refusenik.



Anton Ertl

unread,
Sep 2, 2012, 9:15:48 AM9/2/12
to
m...@iae.nl (Marcel Hendrix) writes:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: continue equivalent in Forth?
>
>> m...@iae.nl (Marcel Hendrix) writes:
>[..]
>> My question about SECURE was actually meant as follows: If SECURE is
>> on, iForth apparently does not accept some Forth-94-compliant control
>> structures. What does it offer that is worth that cost?
>
>For that cost, you can compile code that other Forths won't.

Like what? It seems to me that iForth with the default SECURE ON
cannot compile some standard code that other Forths can compile.

>Of course, it would be better to have gForth-like diagnostics with a
>SECURE flag to disable them for exceptional cases.

So what you mean is maybe this: SECURE OFF offers additional features
(without needing funny stuff like you would have to do in Gforth);
SECURE ON offers diagnostics, but is a little overzealous and might be
fixed in the far future. Correct?

>> BTW, your posting would have been easier to read if your newsreader
>> also put quote characters in front of cited empty lines.
>
>You actually notice uncited empted lines between all the
>quoted-printable crap that has become the standard lately?

Yes. And given that you have the option of fixing your newsreader
rather than just switching to a different one, I chose to make you
aware of that. Concerning the crap, if something is too hard to read,
I don't.
0 new messages