Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #10205 > unrolled thread

DO... LOOP question

Started byArnold Doray <invalid@invalid.com>
First post2012-03-18 15:52 +0000
Last post2012-03-27 16:46 +0000
Articles 20 on this page of 45 — 9 participants

Back to article view | Back to comp.lang.forth


Contents

  DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-18 15:52 +0000
    Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-18 17:08 +0100
    Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 09:41 -0700
      Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-18 20:51 +0100
        Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 14:37 -0700
      Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 15:56 -0700
        Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-19 01:04 +0100
          Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 17:25 -0700
          Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 17:43 -0700
            Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 18:48 -0700
          Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-18 21:49 -0700
            Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-19 11:39 -0700
            Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-20 12:16 -0700
      Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-20 16:54 +0000
        Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-20 11:41 -0700
          Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-24 17:29 +0000
            Re: DO... LOOP question Andrew Haley <andrew29@littlepinkcloud.invalid> - 2012-03-24 13:22 -0500
              Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-25 04:09 +0000
                Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-25 13:49 +0200
                  Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-27 17:47 +0000
                Re: DO... LOOP question Albert van der Horst <albert@spenarnc.xs4all.nl> - 2012-03-25 19:45 +0000
                Re: DO... LOOP question Andrew Haley <andrew29@littlepinkcloud.invalid> - 2012-03-26 04:26 -0500
                  Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-26 07:28 -0700
                    Re: DO... LOOP question Andrew Haley <andrew29@littlepinkcloud.invalid> - 2012-03-26 10:03 -0500
                      Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-26 18:47 +0200
                      Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-26 09:53 -0700
                        Re: DO... LOOP question Albert van der Horst <albert@spenarnc.xs4all.nl> - 2012-03-27 11:21 +0000
                          Re: DO... LOOP question Helmar Wodtke <helmwo@gmail.com> - 2012-03-27 04:34 -0700
                            Re: DO... LOOP question Coos Haak <chforth@hccnet.nl> - 2012-03-27 17:33 +0200
                              Re: DO... LOOP question Helmar Wodtke <helmwo@gmail.com> - 2012-03-27 09:19 -0700
                                Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-27 12:20 -0700
                                  Re: DO... LOOP question "Elizabeth D. Rather" <erather@forth.com> - 2012-03-27 09:34 -1000
                                    Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-27 13:00 -0700
                Re: DO... LOOP question Hugh Aguilar <hughaguilar96@yahoo.com> - 2012-03-26 20:16 -0700
            Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-24 11:37 -0700
              Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-25 06:39 +0000
                Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-25 06:19 -0700
        Re: DO... LOOP question "Rod Pemberton" <do_not_have@noavailemail.cmm> - 2012-03-21 05:48 -0400
          Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-21 08:36 -0700
        Re: DO... LOOP question BruceMcF <agila61@netscape.net> - 2012-03-21 11:24 -0700
    Re: DO... LOOP question Hugh Aguilar <hughaguilar96@yahoo.com> - 2012-03-21 03:01 -0700
      Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-24 17:44 +0000
        Re: DO... LOOP question Albert van der Horst <albert@spenarnc.xs4all.nl> - 2012-03-25 11:57 +0000
        Re: DO... LOOP question Hugh Aguilar <hughaguilar96@yahoo.com> - 2012-03-26 20:14 -0700
          Re: DO... LOOP question Arnold Doray <invalid@invalid.com> - 2012-03-27 16:46 +0000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#10454

FromAlbert van der Horst <albert@spenarnc.xs4all.nl>
Date2012-03-25 19:45 +0000
Message-ID<m1ghk0.bw7@spenarnc.xs4all.nl>
In reply to#10431
In article <jkm5pb$7n2$1@dont-email.me>,
Arnold Doray  <invalid@invalid.com> wrote:
>On Sat, 24 Mar 2012 13:22:39 -0500, Andrew Haley wrote:
>
>> Arnold Doray <invalid@invalid.com> wrote:
>>>
>>> Besides its relative simplicity, the advantage of this solution is that
>>> it would probably also work for LEAVE'ing other looping constructs,
>>
>> We've got WHILE for that.
>>
>> Andrew.
>
>I was thinking of something along the lines of Java's "break" and
>"continue" keywords. In Java, "break" can break out of "for", "while",
>and other looping constructs. Whether this is a "good thing" is another
>question... even in Java where they are available, these are used
>sparingly.
>
>As I understand it, LEAVE only works in DO...LOOP constructs in Forth.
>There is no way to prematurely break out of a WHILE...REPEAT loop (or
>other looping constructs) in Forth. The solution outlined in my earlier
>post could do this for Forth, using LEAVE, without too much hassle.

BEGIN .. WHILE.. REPEAT is a mid conditioned loop, so at the WHILE
there is a "premature" break.  You can even have multiple WHILE's ,
but for some Forth's you have to disable security.
(In ciforth `` WANT NO-SECURITY   NO-SECURITY '' )

>
>Cheers,
>Arnold
>
>

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

[toc] | [prev] | [next] | [standalone]


#10495

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2012-03-26 04:26 -0500
Message-ID<wb-dnXOH5Oqlq-3SnZ2dnUVZ_rSdnZ2d@supernews.com>
In reply to#10431
Arnold Doray <invalid@invalid.com> wrote:
> On Sat, 24 Mar 2012 13:22:39 -0500, Andrew Haley wrote:
> 
>> Arnold Doray <invalid@invalid.com> wrote:
>>> 
>>> Besides its relative simplicity, the advantage of this solution is that
>>> it would probably also work for LEAVE'ing other looping constructs,
>> 
>> We've got WHILE for that.
> 

> I was thinking of something along the lines of Java's "break" and
> "continue" keywords. In Java, "break" can break out of "for",
> "while", and other looping constructs. Whether this is a "good
> thing" is another question... even in Java where they are available,
> these are used sparingly.
> 
> As I understand it, LEAVE only works in DO...LOOP constructs in
> Forth.  There is no way to prematurely break out of a WHILE...REPEAT
> loop (or other looping constructs) in Forth.

Sure there is.  WHILE can break out of any loop:

]$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.

: yy 0 begin dup 10 < while dup . 1+ dup 100 > until then drop ; ok
yy 0 1 2 3 4 5 6 7 8 9  ok

AIUI, WHILE can be used to early-terminate any loop, but its use in DO
... LOOPs is nonstandard.  I don't know why this is; it works on eery
system I've used.  Like this:

: zz 100 0 do  i 10 < while  i .  loop  else unloop then ;  ok
zz 0 1 2 3 4 5 6 7 8 9  ok

Andrew.

[toc] | [prev] | [next] | [standalone]


#10517

FromBruceMcF <agila61@netscape.net>
Date2012-03-26 07:28 -0700
Message-ID<10ac1de5-8bd4-4a05-9331-0bdc0c75cd94@x10g2000pbi.googlegroups.com>
In reply to#10495
On Mar 26, 5:26 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Arnold Doray <inva...@invalid.com> wrote:
> > On Sat, 24 Mar 2012 13:22:39 -0500, Andrew Haley wrote:
>
> >> Arnold Doray <inva...@invalid.com> wrote:
>
> >>> Besides its relative simplicity, the advantage of this solution is that
> >>> it would probably also work for LEAVE'ing other looping constructs,
>
> >> We've got WHILE for that.
>
> > I was thinking of something along the lines of Java's "break" and
> > "continue" keywords. In Java, "break" can break out of "for",
> > "while", and other looping constructs. Whether this is a "good
> > thing" is another question... even in Java where they are available,
> > these are used sparingly.
>
> > As I understand it, LEAVE only works in DO...LOOP constructs in
> > Forth.  There is no way to prematurely break out of a WHILE...REPEAT
> > loop (or other looping constructs) in Forth.
>
> Sure there is.  WHILE can break out of any loop:
>
> ]$ gforth
> Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
>
> : yy 0 begin dup 10 < while dup . 1+ dup 100 > until then drop ; ok
> yy 0 1 2 3 4 5 6 7 8 9  ok
>
> AIUI, WHILE can be used to early-terminate any loop, but its use in DO
> ... LOOPs is nonstandard.  I don't know why this is; it works on eery
> system I've used.  Like this:
>
> : zz 100 0 do  i 10 < while  i .  loop  else unloop then ;  ok
> zz 0 1 2 3 4 5 6 7 8 9  ok

Yes ~ LEAVE offers indefinitely many exits and LOOP takes care of its
termination, but if it does not exist, indefinitely many exits can be
done by factoring out the loop and "UNLOOP EXIT".

How does that WHILE exit work with a ?DO loop?

[toc] | [prev] | [next] | [standalone]


#10518

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2012-03-26 10:03 -0500
Message-ID<5Z-dnYWjobaqGO3SnZ2dnUVZ_sidnZ2d@supernews.com>
In reply to#10517
BruceMcF <agila61@netscape.net> wrote:
> On Mar 26, 5:26?am, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>> Arnold Doray <inva...@invalid.com> wrote:
>> > On Sat, 24 Mar 2012 13:22:39 -0500, Andrew Haley wrote:
>>
>> >> Arnold Doray <inva...@invalid.com> wrote:
>>
>> >>> Besides its relative simplicity, the advantage of this solution is that
>> >>> it would probably also work for LEAVE'ing other looping constructs,
>>
>> >> We've got WHILE for that.
>>
>> > I was thinking of something along the lines of Java's "break" and
>> > "continue" keywords. In Java, "break" can break out of "for",
>> > "while", and other looping constructs. Whether this is a "good
>> > thing" is another question... even in Java where they are available,
>> > these are used sparingly.
>>
>> > As I understand it, LEAVE only works in DO...LOOP constructs in
>> > Forth. There is no way to prematurely break out of a WHILE...REPEAT
>> > loop (or other looping constructs) in Forth.
>>
>> Sure there is. WHILE can break out of any loop:
>>
>> ]$ gforth
>> Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
>>
>> : yy 0 begin dup 10 < while dup . 1+ dup 100 > until then drop ; ok
>> yy 0 1 2 3 4 5 6 7 8 9 ok
>>
>> AIUI, WHILE can be used to early-terminate any loop, but its use in DO
>> ... LOOPs is nonstandard. I don't know why this is; it works on every
>> system I've used.

Err, sorry that was an inadvertent untruth.  I now know of at least
one system on which it doesn't work.

> Like this:
>>
>> : zz 100 0 do i 10 < while i . loop else unloop then ; ok
>> zz 0 1 2 3 4 5 6 7 8 9 ok
> 
> Yes ~ LEAVE offers indefinitely many exits and LOOP takes care of
> its termination, but if it does not exist, indefinitely many exits
> can be done by factoring out the loop and "UNLOOP EXIT".

True enough.

> How does that WHILE exit work with a DO loop?

I don't know.  It still works, though!

Andrew.

[toc] | [prev] | [next] | [standalone]


#10521

FromCoos Haak <chforth@hccnet.nl>
Date2012-03-26 18:47 +0200
Message-ID<14bmmapst7pf.1wn935k1q8lnw.dlg@40tude.net>
In reply to#10518
Op Mon, 26 Mar 2012 10:03:19 -0500 schreef Andrew Haley:

> BruceMcF <agila61@netscape.net> wrote:
>> On Mar 26, 5:26?am, Andrew Haley <andre...@littlepinkcloud.invalid>
>> wrote:
>>> Arnold Doray <inva...@invalid.com> wrote:
>>> > On Sat, 24 Mar 2012 13:22:39 -0500, Andrew Haley wrote:
>>>
>>> >> Arnold Doray <inva...@invalid.com> wrote:
>>>
>>> >>> Besides its relative simplicity, the advantage of this solution is that
>>> >>> it would probably also work for LEAVE'ing other looping constructs,
>>>
>>> >> We've got WHILE for that.
>>>
>>> > I was thinking of something along the lines of Java's "break" and
>>> > "continue" keywords. In Java, "break" can break out of "for",
>>> > "while", and other looping constructs. Whether this is a "good
>>> > thing" is another question... even in Java where they are available,
>>> > these are used sparingly.
>>>
>>> > As I understand it, LEAVE only works in DO...LOOP constructs in
>>> > Forth. There is no way to prematurely break out of a WHILE...REPEAT
>>> > loop (or other looping constructs) in Forth.
>>>
>>> Sure there is. WHILE can break out of any loop:
>>>
>>> ]$ gforth
>>> Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
>>>
>>> : yy 0 begin dup 10 < while dup . 1+ dup 100 > until then drop ; ok
>>> yy 0 1 2 3 4 5 6 7 8 9 ok
>>>
>>> AIUI, WHILE can be used to early-terminate any loop, but its use in DO
>>> ... LOOPs is nonstandard. I don't know why this is; it works on every
>>> system I've used.
> 
> Err, sorry that was an inadvertent untruth.  I now know of at least
> one system on which it doesn't work.
> 
>> Like this:
>>>
>>> : zz 100 0 do i 10 < while i . loop else unloop then ; ok
>>> zz 0 1 2 3 4 5 6 7 8 9 ok
>> 
>> Yes ~ LEAVE offers indefinitely many exits and LOOP takes care of
>> its termination, but if it does not exist, indefinitely many exits
>> can be done by factoring out the loop and "UNLOOP EXIT".
> 
> True enough.
> 
>> How does that WHILE exit work with a DO loop?
> 
> I don't know.  It still works, though!
> 
> Andrew.

DO and ?DO leave do-sys on the control flow stack while compiling
LOOP and +LOOP consume that.

WHILE leaves orig under dest. ( dest -- orig dest )
THEN consumes orig.

So, assuming the number of elements on the stack of do-sys are the same as
dest and orig this would be on the control flow stack:
DO ( do-sys ) WHILE ( orig do-sys ) LOOP ( orig ) THEN ( )

?DO would be no different from DO (apart from information for LEAVE)
+LOOP idem, no different from LOOP

Even multiple WHILEs are possible, if you provide the necessary THENs.

-- 
Coos

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

[toc] | [prev] | [next] | [standalone]


#10524

FromBruceMcF <agila61@netscape.net>
Date2012-03-26 09:53 -0700
Message-ID<b064493f-2ca9-4845-a1e2-95c75834fc91@pd5g2000pbc.googlegroups.com>
In reply to#10518
On Mar 26, 11:03 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> BruceMcF <agil...@netscape.net> wrote:
>> How does that WHILE exit work with a DO loop?

> I don't know.  It still works, though!

That was what I was asking ~ not "how does that car run?" as in, "what
is the process of converting gasoline into motion?", but as in, "are
there going to be any problems when I push down on the gas pedal?".

I can see the opportunity for an implementation of ?DO ... LOOP to get
confused by the "orig" dropped by the while, but it'd be down to
implementation details. For instance, if it hooked into the LEAVE
mechanism, there'd be no contention for the compile time stack.

[toc] | [prev] | [next] | [standalone]


#10563

FromAlbert van der Horst <albert@spenarnc.xs4all.nl>
Date2012-03-27 11:21 +0000
Message-ID<m1jjk7.mrn@spenarnc.xs4all.nl>
In reply to#10524
In article <b064493f-2ca9-4845-a1e2-95c75834fc91@pd5g2000pbc.googlegroups.com>,
BruceMcF  <agila61@netscape.net> wrote:
>On Mar 26, 11:03=A0am, Andrew Haley <andre...@littlepinkcloud.invalid>
>wrote:
>
>> BruceMcF <agil...@netscape.net> wrote:
>>> How does that WHILE exit work with a DO loop?
>
>> I don't know. =A0It still works, though!
>
>That was what I was asking ~ not "how does that car run?" as in, "what
>is the process of converting gasoline into motion?", but as in, "are
>there going to be any problems when I push down on the gas pedal?".
>
>I can see the opportunity for an implementation of ?DO ... LOOP to get
>confused by the "orig" dropped by the while, but it'd be down to
>implementation details. For instance, if it hooked into the LEAVE
>mechanism, there'd be no contention for the compile time stack.

If WHILE was required to work with a DO .. LOOP, we could drop LEAVE
from the languages:

    : test 100 0 DO I 10 > IF LEAVE THEN I . LOOP ;
could be replaced by
    : test 100 0 DO I 10 > NOT WHILE I . LOOP ;

A Forther must be aware when loop parameters are present.
I remember how upset I was that
    : test 100 0 DO I 10 > IF EXIT THEN I . LOOP ;
doesn't work.
Shifting that burden to the implementor would be a major change.
I would say that it only could be done in total overhaul of all
the looping in Forth.

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

[toc] | [prev] | [next] | [standalone]


#10568

FromHelmar Wodtke <helmwo@gmail.com>
Date2012-03-27 04:34 -0700
Message-ID<13266921.297.1332848048066.JavaMail.geo-discussion-forums@ynel5>
In reply to#10563
Am Dienstag, 27. März 2012 13:21:43 UTC+2 schrieb Albert van der Horst:

> ... something about WHILE ...

In this case the Forth has to support multiple WHILEs for one loop.
Difference at the moment between using WHILE and LEAVE is that WHILE can be there one time and LEAVE can be there multiple times.

Regards,
-Helmar

[toc] | [prev] | [next] | [standalone]


#10586

FromCoos Haak <chforth@hccnet.nl>
Date2012-03-27 17:33 +0200
Message-ID<1alsijjhczcmc.r5s3o0lve6ot$.dlg@40tude.net>
In reply to#10568
Op Tue, 27 Mar 2012 04:34:07 -0700 (PDT) schreef Helmar Wodtke:

> Am Dienstag, 27. März 2012 13:21:43 UTC+2 schrieb Albert van der Horst:
> 
>> ... something about WHILE ...
> 
> In this case the Forth has to support multiple WHILEs for one loop.
> Difference at the moment between using WHILE and LEAVE is that WHILE can be there one time and LEAVE can be there multiple times.
> 
Nope, you can use WHILE multiple times. But you have to add UNLOOP in every
ELSE part:

.. DO .. WHILE .. WHILE .. LOOP .. ELSE UNLOOP THEN ELSE UNLOOP THEN ..

But this is much simpler, and according to the standard.
.. DO .. IF LEAVE THEN .. IF LEAVE THEN .. LOOP

Or with an other word, ?LEAVE
: ?LEAVE POSTPONE IF POSTPONE LEAVE POSTPONE THEN ; IMMEDIATE
.. DO .. ?LEAVE .. ?LEAVE .. LOOP

-- 
Coos

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

[toc] | [prev] | [next] | [standalone]


#10590

FromHelmar Wodtke <helmwo@gmail.com>
Date2012-03-27 09:19 -0700
Message-ID<7536008.1597.1332865161513.JavaMail.geo-discussion-forums@vbvd13>
In reply to#10586
Am Dienstag, 27. März 2012 17:33:43 UTC+2 schrieb Coos Haak:
> Op Tue, 27 Mar 2012 04:34:07 -0700 (PDT) schreef Helmar Wodtke:
> 
> > Am Dienstag, 27. März 2012 13:21:43 UTC+2 schrieb Albert van der Horst:
> > 
> >> ... something about WHILE ...
> > 
> > In this case the Forth has to support multiple WHILEs for one loop.
> > Difference at the moment between using WHILE and LEAVE is that WHILE can be there one time and LEAVE can be there multiple times.
> > 
> Nope, you can use WHILE multiple times. But you have to add UNLOOP in every
> ELSE part:
> 
> .. DO .. WHILE .. WHILE .. LOOP .. ELSE UNLOOP THEN ELSE UNLOOP THEN ..
> 
> But this is much simpler, and according to the standard.
> .. DO .. IF LEAVE THEN .. IF LEAVE THEN .. LOOP
> 
> Or with an other word, ?LEAVE
> : ?LEAVE POSTPONE IF POSTPONE LEAVE POSTPONE THEN ; IMMEDIATE
> .. DO .. ?LEAVE .. ?LEAVE .. LOOP
> 
> -- 
> Coos
> 
> CHForth, 16 bit DOS applications
> http://home.hccnet.nl/j.j.haak/forth.html

Oh, what a messy thing.
My non-ANS-part works in a way where WHILE is possible multiple times.

It all looks simply like this:

  purpose: implement loop constructs
   status: mature

: do`      (loop-push)` begin` ;
: (?do)    2dup` (loop-push)` <>` ;
: ?do`     (?do) if` begin` (while) ;
: loop`    (loop)` repeat` unloop` ;
: +loop`   (+loop)` repeat` unloop` ;
: leave`   ahead` (while) ;
: until`   0=` while` repeat` ;
: while:`  begin` ?dup` while` ;
: for`     while:` 1-` >r` ;
: next`    r>` repeat` ;
: recurse` body compile ;

You see some (xxx)-words, that implement some "primitves" - "while" is basically a primitive too.
The ANS layer implements it inside this block:

 {~ Fix
    256 buffer pad
    : begin`   seal there ;
    : while`   if` swap ;
    : while:`  begin` ?dup` while` ;
    : until`   0=` while`
      : repeat` back then` ;
    : ans-:    smudge ::` current-xt ! is-immediate off
               parse-name current-name place ;
    : ans-;`   seal ;` smudge ;
    : ans-immediate current-xt @ if is-immediate on ;then immediate ;
    : exit`    seal ;;` ;
    : ans-recurse` current-xt @ ?dup if compile ;then recurse` ;
    : key      (key) if c@ ;then EOF ;
    : execute  321 <private-state exec private-state> ;
    /pad buffer pad
  ~}

Main problem with ANS was, that it does not allow the WHILE to be multiple times - it's not very good, what it takes as implementation predictions there... Otherwise WHILE could be doubled without problem.
You see that WHILE is implemented in ANS layer basically as:

: WHILE POSTPONE IF SWAP ; IMMEDIATE

(well, "POSTPONE" is not the right word in all cases...)
About that "SWAP" you can think of a long time, but it's on "compilation stack"... All that CS-things.

Regards,
-Helmar

[toc] | [prev] | [next] | [standalone]


#10605

FromBruceMcF <agila61@netscape.net>
Date2012-03-27 12:20 -0700
Message-ID<77a5bb88-f99d-4406-8c3a-d4fda1254cc9@mq9g2000pbb.googlegroups.com>
In reply to#10590
On Mar 27, 12:19 pm, Helmar Wodtke <hel...@gmail.com> wrote:

> Main problem with ANS was, that it does not allow the WHILE to be
> multiple times - it's not very good, what it takes as implementation
> predictions there... Otherwise WHILE could be doubled without problem.

Which is to say, the "main problem" with the WHILE in some of the
implementations that the WHILE specification respected.

The only time I've ever needed or used multiple WHILEs is for one
terminal action for exit success and a different terminal success for
exit failure, which is the:

BEGIN
   (more?) WHILE
      (not-succeeded?) WHILE
         (iterate)
   REPEAT (success)
ELSE (failure)
THEN

... pattern ... but I certainly wouldn't want to lose it because the
implementation decided that both WHILEs ought to terminate at the
REPEAT, so if you have a word that acts that way, its best not to call
it WHILE.

Given that if its complex enough to support three or four early exits
from a loop, its complex enough to factor out into its own word and to
use EXIT as an early loop exit, the "WHENCE" can easily strike someone
as being much like a solution in search of a problem.

[toc] | [prev] | [next] | [standalone]


#10607

From"Elizabeth D. Rather" <erather@forth.com>
Date2012-03-27 09:34 -1000
Message-ID<es2dnViHQKGxi-_SnZ2dnUVZ_uOdnZ2d@supernews.com>
In reply to#10605
On 3/27/12 9:20 AM, BruceMcF wrote:
...
> Given that if its complex enough to support three or four early exits
> from a loop, its complex enough to factor out into its own word and to
> use EXIT as an early loop exit, the "WHENCE" can easily strike someone
> as being much like a solution in search of a problem.

I think this is the essential point here. Complex control flow is asking 
for trouble, in any language, which is why "structured programming" 
remains good discipline. Good Forth style means short, simple 
definitions, factored such that you don't need tortured control flow. 
When you feel the need for some nasty control structure, it's a clue to 
stop and re-think your approach.

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

[toc] | [prev] | [next] | [standalone]


#10608

FromBruceMcF <agila61@netscape.net>
Date2012-03-27 13:00 -0700
Message-ID<b1448d4a-43f9-4d25-91ed-f761a9f216e5@wb9g2000pbc.googlegroups.com>
In reply to#10607
On Mar 27, 3:34 pm, "Elizabeth D. Rather" <erat...@forth.com> wrote:
> I think this is the essential point here. Complex control flow is
> asking for trouble, in any language, which is why "structured
> programming" remains good discipline.

> Good Forth style means short, simple definitions, factored such that
> you don't need tortured control flow. When you feel the need for some
> nasty control structure, it's a clue to stop and re-think your
> approach.

Indeed, note that there is a straightforward alternate approach to the
exit-success and exit-on-boundary pattern, when the loop is factored
into its own work:

...
   BEGIN
      (more?) WHILE
         (not-succeeded?) WHILE
            (iterate)
      REPEAT (success)
   ELSE (failure)
   THEN ...

... which is:

: process ( -- )
   BEGIN
      (no-more?) IF (failure) EXIT THEN
      (not-succeeeded?) WHILE
         (iterate)
   REPEAT (success) ;

[toc] | [prev] | [next] | [standalone]


#10549

FromHugh Aguilar <hughaguilar96@yahoo.com>
Date2012-03-26 20:16 -0700
Message-ID<abed4774-a15e-4d59-8757-e819778e1f13@n5g2000vbf.googlegroups.com>
In reply to#10431
On Mar 24, 10:09 pm, Arnold Doray <inva...@invalid.com> wrote:
> There is no way to prematurely break out of a WHILE...REPEAT loop (or
> other looping constructs) in Forth.

Just put the WHILE loop in a sub-function, and use EXIT to get out.

[toc] | [prev] | [next] | [standalone]


#10417

FromBruceMcF <agila61@netscape.net>
Date2012-03-24 11:37 -0700
Message-ID<1ed7fc4f-0e43-4583-98f7-5d4f5cacc8b5@jx17g2000pbb.googlegroups.com>
In reply to#10413
On Mar 24, 1:29 pm, Arnold Doray <inva...@invalid.com> wrote:

> Some wishful thinking -- perhaps what's needed are
> 2 additional words to move items between the
> compilation stack and the return stack.

> Call them CS>R and R>CS.

> In Forths that use the data stack as the compilation
> stack, this would probably be easy to do.

I'm not entirely sure how that works in compiling words, at least in
compiling words that cannot assume that:
 ... R> >TEMP CS>R TEMP> >R ...

... will necessarily their own ret-sys out of the way. And the CS>R
and R>CS needs to happen at compile time, not execute time in the word
being built, so the various:
   ... POSTPONE 2R> ...

... type design patterns don't work the same way as when pushing the
current loop-system from its 2variable to sit on the return stack.

So I'm thinking of:

: patch-ahead ( u1 addr -- )
   \ G* u1 is how for forward to adjust the branch target
   \ * addr is the address FOLLOWING the branch compiled by AHEAD
   1 CELLS - +! ;

\ ... and a test of whether it works based on:

FALSE VALUE patchable-ahead?

MARKER *patchable-ahead-test*
   : test-patchable-ahead ( -- )
      AHEAD THEN [ HERE ] EXIT
      [ HERE OVER - SWAP patch-ahead ]
      TRUE TO patchable-ahead? ;

CR CR .( This implementation of LEAVE depends on the AHEAD branch
being easily patched.
   CR .( If this test crashes your system, then a different
implementation is required. )

   test-patchable-ahead
*portable-ahead-test*

patchable-ahead? [IF]
   CR .( The implementation-dependency for LEAVE might be satisfied. )
[ELSE]
   CR .( The implementation-dependency for LEAVE is not satisfied,
   CR .( so LEAVE will not be implemented.)
[THEN]

With the 6502 version for the "$10 computer", the targets are absolute
addresses and the leave chain can be swapped in place for the patched
branch targets. For the more easily portable version, the original
branch is a no-op branch to the following address, and the leave-chain
is compiled in place in the *following* cell. That means that *if* the
branch can be patched at the final cell of the data compiled by AHEAD
then the patch works by adding an offset so should work for either
relative or absolute branch targets, and equally well for relative
branch targets whether they are relative to the beginning of the AHEAD
instruction, the location of the target address, or the beginning of
the following instruction.

VARIABLE leave-chain

: LEAVE ( -- )
   POSTPONE AHEAD POSTPONE THEN HERE leave-chain DUP @ , ! ; IMMEDIATE

: rake-leaves ( prior-leave-chain -- )
   leave-chain BEGIN @ ?DUP WHILE
      HERE OVER - OVER patch-ahead
   REPEAT leave-chain ! ;

I'll test that out tomorrow and see how it works for some Forth
implementations I have on hand.

[toc] | [prev] | [next] | [standalone]


#10434

FromArnold Doray <invalid@invalid.com>
Date2012-03-25 06:39 +0000
Message-ID<jkmejb$7md$1@dont-email.me>
In reply to#10417
On Sat, 24 Mar 2012 11:37:41 -0700, BruceMcF wrote:

> I'm not entirely sure how that works in compiling words, at least in
> compiling words that cannot assume that:
>  ... R> >TEMP CS>R TEMP> >R ...
> 

See my solution below for GForth (not tested yet!)

> ... will necessarily their own ret-sys out of the way. And the CS>R and
> R>CS needs to happen at compile time, not execute time in the word being
> built, 

Yes, that's right...

> so the various:
>    ... POSTPONE 2R> ...
> 
> ... type design patterns don't work the same way as when pushing the
> current loop-system from its 2variable to sit on the return stack.

... but I don't follow the second half of your reasoning. In the solution 
I outlined, the saving/restoring of the loop parameters only happens at 
the execution time of the word being built, not its compilation time. So 
there should be no interference between these two mechanisms. 

For example, I believe Gforth uses the data stack as the compilation 
stack. GForth's AHEAD puts 3 ints on the data stack during compilation. 
Also, it uses one int on the return stack as ret-sys. 

So perhaps this might work for GForth?

\ NOT TESTED!
\ ONLY FOR GFORTH, only to move AHEADs
: CS>R
       R> \ save ret-sys
       SWAP >R 
       SWAP >R 
       SWAP >R 
       >R ; \ restore ret-sys

\ ONLY FOR GFORTH, only to move AHEADs.
: R>CS 
       R> \ save ret-sys
       R> SWAP 
       R> SWAP 
       R> SWAP  
       >R ; \ restore ret-sys

VARIABLE  loop-leaves
VARIABLE  loop-limit
VARIABLE  loop-count

: ` POSTPONE POSTPONE ; IMMEDIATE

: (LOOP-INIT) ( limit start -- )
	OVER - loop-count ! loop-limit ! 0 loop-leaves ! ;

: (LOOP-SAVE) 
    loop-limit  @ loop-count  @ loop-leaves @ ; 
	
: (LOOP-RESTORE)
	loop-leaves ! loop-count ! loop-limit ! ; 
	
: I
	loop-count @ loop-limit @ + ; 

: J
	` 2R@ ` + ; IMMEDIATE	
	
: UNLOOP
	` R> ` R> ` R> ` (LOOP-RESTORE) ; IMMEDIATE
	
: DO
	` (LOOP-SAVE) ` >R ` >R ` >R ` (LOOP-INIT) ` BEGIN ; IMMEDIATE
	
: LEAVE 
	` AHEAD ` CS>R ; IMMEDIATE

: (LEAVE-RESOLVE) 
	loop-leaves @ BEGIN dup 0 > WHILE ` R>CS ` THEN 1- REPEAT ;
	
: (LOOP-INC) ( -- f )
	loop-count @ 1+ DUP loop-count ! 0= ; 
	
: LOOP
	(LEAVE-RESOLVE)
	` (LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE

: (+LOOP-INC) ( n -- f )
	loop-count @ + DUP loop-count ! 0< NEGATE ;

: +LOOP
	(LEAVE-RESOLVE)
	` (+LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE
	

Cheers,
Arnold

[toc] | [prev] | [next] | [standalone]


#10449

FromBruceMcF <agila61@netscape.net>
Date2012-03-25 06:19 -0700
Message-ID<240b2698-c701-4f02-87a5-eef6738ca440@t2g2000pbg.googlegroups.com>
In reply to#10434
On Mar 25, 2:39 am, Arnold Doray <inva...@invalid.com> wrote:

> : LEAVE
>         ` AHEAD ` CS>R ; IMMEDIATE

First, need to include "1 loop-leaves +!"

With AHEAD, you've postponed a compiling word, so postponing it will
cause it to execute when LEAVE executes.

With CS>R you've postponed a word with, presumably, regular behavior,
so postponing it will cause it to be compiled into the word you are
compiling, and it will execute when that word executes.

So what you need for it to work is rather: [CS>R] and [R>CS]

So, something like (equally untested):

\ NOT TESTED!
\ ONLY FOR GFORTH, only to move AHEADs
: [CS>R]
       R> \ save ret-sys
       SWAP >R
       SWAP >R
       SWAP >R
       >R ; IMMEDIATE \ restore ret-sys

\ ONLY FOR GFORTH, only to move AHEADs.
: [R>CS]
       R> \ save ret-sys
       R> SWAP
       R> SWAP
       R> SWAP
       >R ; IMMEDIATE \ restore ret-sys

VARIABLE  loop-leaves
2VARIABLE  loop-params

: ` POSTPONE POSTPONE ; IMMEDIATE

: (LOOP-INIT) ( limit start -- )
        OVER - loop-params 2! 0 loop-leaves ! ;

: (LOOP-SAVE)
    loop-params 2@ loop-leaves @ ;

: (LOOP-RESTORE)
        loop-leaves ! loop-params 2! ;

: I
        loop-params 2@ + ;

: J
        ` 2R@ ` + ; IMMEDIATE

: UNLOOP
        ` 2R> ` R> ` (LOOP-RESTORE) ; IMMEDIATE

: DO
        ` (LOOP-SAVE) ` >R ` 2>R ` (LOOP-INIT) ` BEGIN ; IMMEDIATE

: LEAVE
        ` AHEAD ` [CS>R] 1 loop-leaves +! ; IMMEDIATE

: (LEAVE-RESOLVE)
        loop-leaves @ BEGIN dup 0 > WHILE ` [R>CS] ` THEN 1- REPEAT ;

: (LOOP-INC) ( -- f )
        loop-params @ 1+ DUP loop-params ! 0= ;

: LOOP
        (LEAVE-RESOLVE)
        ` (LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE

: (+LOOP-INC) ( n -- f )
        loop-count @ + DUP loop-count ! 0< NEGATE ;

: +LOOP
   \ NB. Not a Forth94 do-loop
        (LEAVE-RESOLVE)
        ` (+LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE

-----------
Also they need loop parameters ~ for one thing, to flag that you are
not doing a Forth94 DO ... +LOOP

[toc] | [prev] | [next] | [standalone]


#10264

From"Rod Pemberton" <do_not_have@noavailemail.cmm>
Date2012-03-21 05:48 -0400
Message-ID<jkc86f$pna$1@speranza.aioe.org>
In reply to#10245
"Arnold Doray" <invalid@invalid.com> wrote in message
news:jkacp1$muf$1@dont-email.me...
> On Sun, 18 Mar 2012 09:41:53 -0700, BruceMcF wrote:
> < good stuff snipped >
>
> Thank you for the detailed solutions!
>
> You could take your idea one step further, incorporating the number of
> leaves as a separate variable that has to be saved/restored like the
> limit and biased count. This simplifies the "rake leaves" and makes the
> solution completely portable (I think), without the need for a
> compatability harness.
>
> Cheers,
> Arnold
>
>
> VARIABLE  loop-leaves
> VARIABLE  loop-limit
> VARIABLE  loop-count
>
> : ` POSTPONE POSTPONE ; IMMEDIATE
>
> : (LOOP-INIT) ( limit start -- )
>     OVER - loop-count ! loop-limit ! 0 loop-leaves ! ;
>
> : (LOOP-SAVE)
>     loop-limit  @ loop-count  @ loop-leaves @ ;
>
> : (LOOP-RESTORE)
>     loop-leaves ! loop-count ! loop-limit ! ;
>
> : I
>     loop-count @ loop-limit @ + ;
>
> : J
>     ` 2R@ ` + ; IMMEDIATE
>
> : UNLOOP
>     ` R> ` R> ` R> ` (LOOP-RESTORE) ; IMMEDIATE
>
> : DO
>     ` (LOOP-SAVE) ` >R ` >R ` >R ` (LOOP-INIT) ` BEGIN ; IMMEDIATE
>
> : LEAVE
>     ` AHEAD ; IMMEDIATE
>
> : (LEAVE-RESOLVE)
>     loop-leaves @ BEGIN dup 0 > WHILE ` THEN 1- REPEAT ;
>
> : (LOOP-INC) ( -- f )
>     loop-count @ 1+ DUP loop-count ! 0= ;
>
> : LOOP
>     (LEAVE-RESOLVE)
>     ` (LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE
>
> : (+LOOP-INC) ( n -- f )
>     loop-count @ + DUP loop-count ! 0< NEGATE ;
>
> : +LOOP
>     (LEAVE-RESOLVE)
>     ` (+LOOP-INC) ` UNTIL ` UNLOOP ; IMMEDIATE
>

You guys have seen this post on control-flow by Wil Baden, yes?  The
rake-leaves stuff is near to the bottom.
http://groups.google.com/group/comp.lang.forth/msg/c912b6777179b74e


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#10271

FromBruceMcF <agila61@netscape.net>
Date2012-03-21 08:36 -0700
Message-ID<484461ae-e7ba-4791-969b-f7d7e399155d@9g2000pbn.googlegroups.com>
In reply to#10264
On Mar 21, 5:48 am, "Rod Pemberton"
> You guys have seen this post on control-flow by Wil Baden, yes?

I assume so.

> The rake-leaves stuff is near to the bottom.
> http://groups.google.com/group/comp.lang.forth/msg/c912b6777179b74e

The OP said:
"The '93 spec shows how to define ELSE, REPEAT and WHILE in terms of
IF, THEN, BEGIN, AGAIN, UNTIL, AHEAD, CS-ROLL and CS-PICK. I was
wondering if these primitives could be used to define DO ... LOOP and
friends?"

Building from scratch with HERE , and "compile-branch" and "compile-?
branch" is a different question than the OP asked. That's why the
version I put in your post did not have that problem, since you have a
BRANCH to use.

I think if code space is data space, and a test branch compiled by
AHEAD is inspected, it should be possible to find where the target
address is in there and work in terms of the HERE prior to AHEAD being
and then a constant offset from that.

: ahead-patch ( -- addr )
   HERE AHEAD THEN ahead-target-offset + ;

That'd have some dependencies ~ code space = data space and the branch
target as a cell-wide HERE address in a cell-aligned location, but
that'd be a pretty widespread target. And for relative targets, ahead-
target-offset could be defined in advance.

If ahead-target-offset is not defined in advance, a small preliminary
"MARKER *test*" section could fairly easily build a testbed word,
attempt to find ahead-target-offset, and test whether values can be
successfully written into that offset.

Then the existence of ahead-target-offset could be used to include
LEAVE in the system.

[toc] | [prev] | [next] | [standalone]


#10276

FromBruceMcF <agila61@netscape.net>
Date2012-03-21 11:24 -0700
Message-ID<7da120ea-ae0a-4890-8f38-62548d2938ec@9g2000pbn.googlegroups.com>
In reply to#10245
I think that for an implementation dependency on codespace =
dataspace, it'll be possible to do something along the lines of:

: LEAVE ( -- )
   POSTPONE AHEAD POSTPONE THEN HERE >leave-chain
; IMMEDIATE

">leave-chain" needs to sort out the negative offset from HERE to get
to the branch target address, and maintain a relative chain so that
the leave-chain can be resolved as an offset from the target address
created by the first LEAVE, so that the same process works whether the
branch target is absolute or relative.

But it should be possible to compile sample code with:
 ... [ HERE ] POSTPONE AHEAD POSTPONE THEN
 [ HERE target-test 2! ] ...

... and find by inspection an absolute address of the target, or a
relative offset equal to the size of the compile branch, or a relative
offset from the offset address to the target.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.forth


csiph-web