Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #44558 > unrolled thread
| Started by | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| First post | 2016-01-04 14:50 -0800 |
| Last post | 2016-01-08 03:04 -0800 |
| Articles | 20 on this page of 100 — 18 participants |
Back to article view | Back to comp.lang.forth
BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 14:50 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 11:24 +1100
Re: BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 16:47 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 12:17 +1100
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-05 10:51 +0000
Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-05 15:06 +0000
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-04 17:25 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-05 13:06 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-04 21:42 -0800
Re: BEGIN WHILE UNTIL THEN rickman <gnuarm@gmail.com> - 2016-01-05 01:48 -0500
Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-05 11:15 +0000
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-06 14:35 +1100
Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-05 02:04 +0000
Re: BEGIN WHILE UNTIL THEN Julian Fondren <julian.fondren@gmail.com> - 2016-01-04 18:37 -0800
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-04 19:17 -0800
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-05 11:10 +0000
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-06 15:02 +1100
Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:03 -0800
Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:07 -0800
Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:18 -0800
Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-05 08:21 -0800
Re: BEGIN WHILE UNTIL THEN Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-07 05:13 -0500
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-08 12:36 +1100
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-08 10:32 +0000
Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 02:55 -0800
Re: BEGIN WHILE UNTIL THEN Coos Haak <chforth@hccnet.nl> - 2016-01-08 13:57 +0100
Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 06:55 -0800
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-08 15:06 -0800
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-08 16:59 -0800
Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-08 16:15 -1000
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-08 22:23 -0800
Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-08 21:12 -1000
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-09 08:04 -0800
Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-09 09:16 -1000
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-10 15:31 +0000
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-10 08:11 -0800
Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-10 09:42 -1000
Re: BEGIN WHILE UNTIL THEN Albert van der Horst <albert@spenarnc.xs4all.nl> - 2016-01-11 13:02 +0000
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-13 16:20 +0000
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 14:10 -0800
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-11 18:38 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-14 08:47 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-13 17:24 -0800
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-13 19:25 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-14 22:09 +1100
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-14 16:21 +0000
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-16 11:34 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-16 03:43 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-19 18:01 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-19 23:07 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-21 14:29 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-21 22:25 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-24 13:28 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-25 01:31 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-25 21:45 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-25 10:24 -0800
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-25 20:41 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-28 20:39 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-28 16:05 +0100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-21 20:52 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-24 13:16 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-14 08:46 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-16 11:34 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-15 20:53 -0800
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-13 19:31 -0800
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 09:29 +1100
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-10 21:18 -0800
Re: BEGIN WHILE UNTIL THEN Paul Rubin <no.email@nospam.invalid> - 2016-01-10 21:29 -0800
Re: BEGIN WHILE UNTIL THEN "Elizabeth D. Rather" <erather@forth.com> - 2016-01-10 20:37 -1000
Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 09:05 +0000
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-12 12:26 +1100
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 14:18 -0800
Re: BEGIN WHILE UNTIL THEN Raimond Dragomir <raimond.dragomir@gmail.com> - 2016-01-08 23:31 -0800
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-09 08:09 -0800
Re: BEGIN WHILE UNTIL THEN Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-09 05:31 -0600
Re: BEGIN WHILE UNTIL THEN Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-01-09 07:52 -0600
Re: BEGIN WHILE UNTIL THEN Ron Aaron <rambamist@gmail.com> - 2016-01-09 18:22 +0200
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-09 16:29 +0000
Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-08 11:23 +0000
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-10 20:17 -0800
Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-11 11:56 +0000
Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 11:59 +0000
generalized CASE (was: BEGIN WHILE UNTIL THEN) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-11 12:30 +0000
Re: generalized CASE (was: BEGIN WHILE UNTIL THEN) hughaguilar96@gmail.com - 2016-01-11 13:52 -0800
Re: generalized CASE Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-11 22:00 +0000
Re: generalized CASE Coos Haak <chforth@hccnet.nl> - 2016-01-12 01:50 +0100
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-11 14:16 -0800
Re: BEGIN WHILE UNTIL THEN Chris Curl <ccurl609@gmail.com> - 2016-01-11 16:17 -0800
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-12 13:07 +0000
Re: BEGIN WHILE UNTIL THEN Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2016-01-12 20:48 +0000
Re: BEGIN WHILE UNTIL THEN hughaguilar96@gmail.com - 2016-01-12 14:16 -0800
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-08 16:21 +0000
Re: BEGIN WHILE UNTIL THEN stephen@mpeforth.com (Stephen Pelc) - 2016-01-08 20:12 +0000
Re: BEGIN WHILE UNTIL THEN anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-01-09 18:19 +0000
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 09:34 +1100
Re: BEGIN WHILE UNTIL THEN Bernd Paysan <bernd.paysan@gmx.de> - 2016-01-08 21:13 +0100
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-09 23:46 +1100
Re: BEGIN WHILE UNTIL THEN Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-01-08 10:11 -0500
Re: BEGIN WHILE UNTIL THEN "HAA" <someone@microsoft.com> - 2016-01-11 08:38 +1100
Re: BEGIN WHILE UNTIL THEN november.nihal@gmail.com - 2016-01-08 03:04 -0800
Page 5 of 5 — ← Prev page 1 2 3 4 [5]
| From | stephen@mpeforth.com (Stephen Pelc) |
|---|---|
| Date | 2016-01-11 11:56 +0000 |
| Message-ID | <56939737.2219350329@news.eternal-september.org> |
| In reply to | #44750 |
On Sun, 10 Jan 2016 20:17:09 -0800 (PST), hughaguilar96@gmail.com wrote: >Anyway, your CASE ... NEXTCASE isn't as robust as Raimond's BREAK because y= >ou require the test to be a comparison of two cells, whereas in Raimond's s= >ystem the test can be anything --- if you are going to require the test to = >be a comparison of two cells, then you would be better off with a jump-tabl= >e as I described earlier. The discussion includes possible options for standardisation to avoid vendor lock-in. Surely that's part of my job as a standards committee member? You make a valid point about two-cell comparison for equality only. Many Forth systems (including VFX) provide ?OF as well as OF. Perhaps that should be standardised too? Stephen -- Stephen Pelc, stephenXXX@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
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2016-01-11 11:59 +0000 |
| Message-ID | <n7059h$vai$1@dont-email.me> |
| In reply to | #44750 |
On 11/01/2016 04:17, hughaguilar96@gmail.com wrote:
> On Friday, January 8, 2016 at 8:58:37 PM UTC-7, Stephen Pelc wrote:
>> >On Fri, 8 Jan 2016 02:55:19 -0800 (PST), Raimond Dragomir
>> ><raimond.dragomir@gmail.com> wrote:
>> >
>>> > >Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops:
>>> > >
>>> > >begin
>>> > > test1 if thing1 break then
>>> > > test2 if thing2 break then
>>> > > ...
>>> > >again
>>> > >
>>> > >This way we can get rid of BEGIN...WHILE...REPEAT loops entirely.
>> >
>> >That looks almost like
>> > CASE
>> > test1 OF ... ENDOF
>> > test2 OF ... ENDOF
>> > NEXTCASE
>> >
>> >and all the infrastructure is already present in most systems.
>> >As I have said before, once you have such facilities, you will
>> >probably find find that are not used enough to justify their
>> >existence.
> I never heard of NEXTCASE before. This is because I never did
> RTFM the VFX manual, as you have repeatedly told me to do.
>
> Maybe the reason why these facilities aren't used is because people don't
> want vendor lock-in with VFX --- they are trying to write ANS-Forth code
> for portability --- ANS-Forth code isn't very portable though, so they
> might as well just give up and accept vendor lock-in.
In 2012 in a similar discussion I posted an ANS Forth implementation
NEXTCASE and other words that seem to meet your and Chris Curls
objections. Another opportunity for you to complain about 'ugly,
inefficient Forth code' :)
See
https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/nextcase/comp.lang.forth/64GKthsYVFs/1QTLZCyiHCUJ
for the discussion, code and test program. For convenience the code follows:
-----------------------------------------------------
: 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 tests a flag
: ?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 loops back to CASE
: nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
>r postpone drop postpone again r> resolve-origs
; immediate
--------------------------------------------------------
--
Gerry
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-01-11 12:30 +0000 |
| Subject | generalized CASE (was: BEGIN WHILE UNTIL THEN) |
| Message-ID | <2016Jan11.133011@mips.complang.tuwien.ac.at> |
| In reply to | #44758 |
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>: of ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 )
> >r
> postpone over postpone = postpone if postpone drop
> cs-swap r> 1+
>; immediate
The compile-time stack effect should be:
( dest #of -- orig dest #of+1), as for ?OF.
It seems to me that the whole package would be slightly simpler if the
stack effect would be ( dest #of -- dest orig #of+1 ), and that of
ENDOF ( dest orig #of -- orig2 dest #of ).
>\ NEXTCASE loops back to CASE
>: nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- )
> >r postpone drop postpone again r> resolve-origs
>; immediate
VFX also has NEXT-CASE (as well as an END-CASE) that does not expect
and drop the x. I have a hard time coming up with loops where
NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE
seems more useful than ENDCASE. However, I expect that the name
similarity to NEXTCASE/ENDCASE may confuse programmers and lead to
bugs.
In the Gforth sources we currently have DEFAULT: to deal with that: If
you don't use DEFAULT:, ENDCASE and NEXTCASE drop a value at run-time,
if you use DEFAULT:, they don't. The idea is to use this in the
simplest case as:
CASE
... ?OF ... ENDOF
... ?OF ... ENDOF
DEFAULT: defaultcode
ENDCASE
However, thinking about it again, this seems too roundabout, and we
are probably better off with
CASE
... ?OF ... ENDOF
... ?OF ... ENDOF
defaultcode
0 ENDCASE
Of course the even better variant would be to only have END-CASE and
NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have
ENDCASE and have to live with it for a long time. For the looping
variant, maybe we should go with NEXT-CASE only, though.
- 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 2015: http://www.rigwit.co.uk/EuroForth2015/
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-01-11 13:52 -0800 |
| Subject | Re: generalized CASE (was: BEGIN WHILE UNTIL THEN) |
| Message-ID | <342e3527-8524-48c8-a9e5-a25bd5ace982@googlegroups.com> |
| In reply to | #44761 |
On Monday, January 11, 2016 at 7:44:05 AM UTC-7, Anton Ertl wrote: > Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes: > >: of ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 ) > > >r > > postpone over postpone = postpone if postpone drop > > cs-swap r> 1+ > >; immediate > > The compile-time stack effect should be: > > ( dest #of -- orig dest #of+1), as for ?OF. > > It seems to me that the whole package would be slightly simpler if the > stack effect would be ( dest #of -- dest orig #of+1 ), and that of > ENDOF ( dest orig #of -- orig2 dest #of ). > > >\ NEXTCASE loops back to CASE > >: nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- ) > > >r postpone drop postpone again r> resolve-origs > >; immediate > > VFX also has NEXT-CASE (as well as an END-CASE) that does not expect > and drop the x. I have a hard time coming up with loops where > NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE > seems more useful than ENDCASE. However, I expect that the name > similarity to NEXTCASE/ENDCASE may confuse programmers and lead to > bugs. > > In the Gforth sources we currently have DEFAULT: to deal with that: If > you don't use DEFAULT:, ENDCASE and NEXTCASE drop a value at run-time, > if you use DEFAULT:, they don't. The idea is to use this in the > simplest case as: > > CASE > ... ?OF ... ENDOF > ... ?OF ... ENDOF > DEFAULT: defaultcode > ENDCASE > > However, thinking about it again, this seems too roundabout, and we > are probably better off with > > CASE > ... ?OF ... ENDOF > ... ?OF ... ENDOF > defaultcode > 0 ENDCASE > > Of course the even better variant would be to only have END-CASE and > NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have > ENDCASE and have to live with it for a long time. For the looping > variant, maybe we should go with NEXT-CASE only, though. > > - 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 2015: http://www.rigwit.co.uk/EuroForth2015/ You've got your NEXTCASE and ENDCASE mixed up throughout your post.
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2016-01-11 22:00 +0000 |
| Subject | Re: generalized CASE |
| Message-ID | <n718hl$gd4$1@dont-email.me> |
| In reply to | #44761 |
On 11/01/2016 12:30, Anton Ertl wrote: > Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes: >> : of ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 ) >> >r >> postpone over postpone = postpone if postpone drop >> cs-swap r> 1+ >> ; immediate > > The compile-time stack effect should be: > > ( dest #of -- orig dest #of+1), as for ?OF. Yes, thank you. > > It seems to me that the whole package would be slightly simpler if the > stack effect would be ( dest #of -- dest orig #of+1 ), and that of > ENDOF ( dest orig #of -- orig2 dest #of ). > >> \ NEXTCASE loops back to CASE >> : nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- ) >> >r postpone drop postpone again r> resolve-origs >> ; immediate > > VFX also has NEXT-CASE (as well as an END-CASE) that does not expect > and drop the x. I have a hard time coming up with loops where > NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE > seems more useful than ENDCASE. However, I expect that the name > similarity to NEXTCASE/ENDCASE may confuse programmers and lead to > bugs. When I did this in 2012 I can't remember being aware of NEXT-CASE and END-CASE and I agree if they co-existed with ENDCASE and NEXTCASE that would be too confusing. > > Of course the even better variant would be to only have END-CASE and > NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have > ENDCASE and have to live with it for a long time. For the looping > variant, maybe we should go with NEXT-CASE only, though. > Given that virtually every other compound word is hyphenated it is rather strange that ENDOF and ENDCASE weren't hyphenated, I don't think they were standardised previously. I think you and others have said that words like these CASE extensions have not been much used. I have to say that having written the code I posted I don't think I have ever used any of the extensions, certainly I haven't built them into my system. -- Gerry
[toc] | [prev] | [next] | [standalone]
| From | Coos Haak <chforth@hccnet.nl> |
|---|---|
| Date | 2016-01-12 01:50 +0100 |
| Subject | Re: generalized CASE |
| Message-ID | <ysa9yvy1x1yl.1d04lcd1xoveo$.dlg@40tude.net> |
| In reply to | #44764 |
Op Mon, 11 Jan 2016 22:00:56 +0000 schreef Gerry Jackson: > On 11/01/2016 12:30, Anton Ertl wrote: >> Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes: >>> : of ( dest #of -- orig #of+1 ) \ run-time ( x1 x2 -- | x1 ) >>> >r >>> postpone over postpone = postpone if postpone drop >>> cs-swap r> 1+ >>> ; immediate >> >> The compile-time stack effect should be: >> >> ( dest #of -- orig dest #of+1), as for ?OF. > > Yes, thank you. > >> >> It seems to me that the whole package would be slightly simpler if the >> stack effect would be ( dest #of -- dest orig #of+1 ), and that of >> ENDOF ( dest orig #of -- orig2 dest #of ). >> >>> \ NEXTCASE loops back to CASE >>> : nextcase ( orig1 ... orign dest #of -- ) \ run-time ( x -- ) >>> >r postpone drop postpone again r> resolve-origs >>> ; immediate >> >> VFX also has NEXT-CASE (as well as an END-CASE) that does not expect >> and drop the x. I have a hard time coming up with loops where >> NEXTCASE is more useful than NEXT-CASE, and if you use ?OF, END-CASE >> seems more useful than ENDCASE. However, I expect that the name >> similarity to NEXTCASE/ENDCASE may confuse programmers and lead to >> bugs. > > When I did this in 2012 I can't remember being aware of NEXT-CASE and > END-CASE and I agree if they co-existed with ENDCASE and NEXTCASE that > would be too confusing. > >> >> Of course the even better variant would be to only have END-CASE and >> NEXT-CASE, and use DROP END-CASE instead of ENDCASE, but we now have >> ENDCASE and have to live with it for a long time. For the looping >> variant, maybe we should go with NEXT-CASE only, though. >> > > Given that virtually every other compound word is hyphenated it is > rather strange that ENDOF and ENDCASE weren't hyphenated, I don't think > they were standardised previously. The names ENDOF and ENDCASE were in the Case Context of Forth Dimensions II, 3. That was back in 1980. The standard of the '90s did not change them. I suppose that ENDOF was derived from ENDIF that had no hyphen either. > > I think you and others have said that words like these CASE extensions > have not been much used. I have to say that having written the code I > posted I don't think I have ever used any of the extensions, certainly I > haven't built them into my system. I heard about NEXTCASE only a few months ago and saw them in Gforth. I can load it, and CONTOF, but never found it necessary. groet Coos
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-01-11 14:16 -0800 |
| Message-ID | <1300bc89-75f3-4ac1-992d-0f0c2251deb0@googlegroups.com> |
| In reply to | #44758 |
On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote: > In 2012 in a similar discussion I posted an ANS Forth implementation > NEXTCASE and other words that seem to meet your and Chris Curls > objections. Another opportunity for you to complain about 'ugly, > inefficient Forth code' :) Your code is just generating nested IF statements. This is pretty much the same as that Forth Dimensions contest winner from the 1980s. Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are. What is sad about all of this is that Bernd Paysan and Anton Ertl are obviously aware of how fast this method is, because they write their Forth interpreter in C and they depend upon SWITCH to be fast. They don't consider using this method in Forth though, because they just consider Forth to be a toy language and they have no concern about speed. Anton Ertl is a college professor --- his students are writing toy programs that will never be used in the real world, so speed is not a concern --- all he really cares about is grading people's Forth code, as if he is naturally above everybody else (he was actually appointed to his job as Forth-200x chair-person by Elizabeth Rather, the ANS-Forth chair-person who appointed herself to that job). In my experience, when I say that I'm a Forth programmer, the typical C programmer will say that he is not just a mere Forth application-programmer like me, but is a Forth compiler-writer, so he knows ever so much more about Forth than I do. In his next breath he will say that writing a Forth interpreter is a good exercise for people learning C, but the Forth interpreter itself is utterly useless for writing application programs. Rod Pemberton is typical in this with his assertion that C is the "God language" that toy interpreters (Forth, Python, Lua, etc.) are entirely dependent upon. Since you are so proud of your CASE NEXTCASE code, how about writing a byte-code interpreter? A byte-code interpreter has upwards of 256 opcodes, so with your method that is upwards of 256 conditional tests for every opcode before your program figures out which opcode it has and is able to emulate it. Your program should be about three orders of magnitude slower than a comparable C program --- a great way to disprove the C programmers' assertion that Forth is too slow to be useful in the real world.
[toc] | [prev] | [next] | [standalone]
| From | Chris Curl <ccurl609@gmail.com> |
|---|---|
| Date | 2016-01-11 16:17 -0800 |
| Message-ID | <00034aff-8f9e-4ca4-aa7f-40aaf44805af@googlegroups.com> |
| In reply to | #44765 |
On Monday, January 11, 2016 at 5:16:51 PM UTC-5, hughag...@gmail.com wrote: > ... > Since you are so proud of your CASE NEXTCASE code, how about writing a byte-code interpreter? > A byte-code interpreter has upwards of 256 opcodes, so with your method that is upwards of 256 > conditional tests for every opcode before your program figures out which opcode it has and is > able to emulate it. Your program should be about three orders of magnitude slower than a > comparable C program --- a great way to disprove the C programmers' assertion that Forth is > too slow to be useful in the real world. My byte-code interpreter (written in assembler) has a jump table for the opcodes. It currently has about 100 such opcodes.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-01-12 13:07 +0000 |
| Message-ID | <2016Jan12.140723@mips.complang.tuwien.ac.at> |
| In reply to | #44765 |
hughaguilar96@gmail.com writes:
>What is sad about all of this is that Bernd Paysan and Anton Ertl are obvio=
>usly aware of how fast this method is, because they write their Forth inter=
>preter in C and they depend upon SWITCH to be fast.
LOL. There are some usages of switch in the Gforth sources, but not
in parts where Gforth typically spends much time. For anybody
interested in facts rather than (wrong) guesses, you can find what we
did in the beginning in [ertl93]
@InProceedings{ertl93,
author = "M. Anton Ertl",
title = "A Portable {Forth} Engine",
booktitle = "EuroFORTH '93 conference proceedings",
year = "1993",
address = "Mari\'ansk\'e L\'azn\`e (Marienbad)",
url = "http://www.complang.tuwien.ac.at/papers/ertl93.ps.gz",
abstract = "The Forth engine discussed in this paper is written
in GNU C, which provides several extensions that are
important for Forth implementation. The indirect
threaded Forth engine is completely
machine-independent, direct threading requires a few
machine-specific lines for each machine. Using
a portable language like GNU C encourages producing
an engine with many primitives. In order to make the
development of primitives easier and less
error-prone, an automatic tool generates most of the
code for a Forth primitive from the stack effect
notation, even if the TOS is kept in a register. The
engine is combined with the parts of the system
written in Forth by loading a machine-independent
image file that contains the executable Forth code
in relocatable form."
}
Later we expanded on that:
@InProceedings{ertl&gregg03,
author = "M. Anton Ertl and David Gregg",
title = "Optimizing Indirect Branch Prediction Accuracy in Virtual Machine Interpreters",
crossref = "sigplan03",
OPTpages = "",
url = "http://www.complang.tuwien.ac.at/papers/ertl%26gregg03.ps.gz",
abstract = "Interpreters designed for efficiency execute a huge
number of indirect branches and can spend more than
half of the execution time in indirect branch
mispredictions. Branch target buffers are the best
widely available\mn{on all recent general-purpose
machines?} form of indirect branch prediction;
however, their prediction accuracy for existing
interpretes is only 2\%--50\%. In this paper we
investigate two methods for improving the prediction
accuracy of BTBs for interpreters: replicating
virtual machine (VM) instructions and combining
sequences of VM instructions into superinstructions.
We investigate static (interpreter build-time) and
dynamic (interpreter run-time) variants of these
techniques and compare them and several combinations
of these techniques. These techniques can eliminate
nearly all of the dispatch branch mispredictions,
and have other benefits, resulting in speedups by a
factor of up to 3.17 over efficient threaded-code
interpreters, and speedups by a factor of up to 1.3
over techniques relying on superinstructions alone."
}
@Proceedings{sigplan03,
booktitle = "SIGPLAN Conference on Programming Language
Design and Implementation (PLDI'03)",
title = "SIGPLAN Conference on Programming Language
Design and Implementation (PLDI'03)",
year = "2003",
key = "PLDI '03"
}
@InProceedings{ertl&gregg05,
author = {M. Anton Ertl and David Gregg},
title = {Stack Caching in {Forth}},
crossref = {euroforth05},
pages = {6--15},
url = {http://www.complang.tuwien.ac.at/papers/ertl%26gregg05.ps.gz},
pdfurl = {http://www.complang.tuwien.ac.at/anton/euroforth2005/papers/ertl%26gregg05.pdf},
OPTnote = {not refereed},
abstract = {Stack caching speeds Forth up by keeping stack items
in registers, reducing the number of memory accesses
for stack items. This paper describes our work on
extending Gforth's stack caching implementation to
support more than one register in the canonical
state, and presents timing results for the resulting
Forth system. For single-representation stack
caches, keeping just one stack item in registers is
usually best, and provides speedups up to a factor
of 2.84 over the straight-forward stack
representation. For stack caches with multiple stack
representations, using the one-register
representation as canonical representation is
usually optimal, resulting in an overall speedup of
up to a factor of 3.80 (and up to a factor of 1.53
over single-representation stack caching).}
}
>Since you are so proud of your CASE NEXTCASE code, how about writing a byte=
>-code interpreter? A byte-code interpreter has upwards of 256 opcodes, so w=
>ith your method that is upwards of 256 conditional tests for every opcode b=
>efore your program figures out which opcode it has and is able to emulate i=
>t. Your program should be about three orders of magnitude slower than a com=
>parable C program --- a great way to disprove the C programmers' assertion =
>that Forth is too slow to be useful in the real world.
One will obviously not use Eaker's CASE for a virtual-machine
interpreter. The standard Forth way to do large dispatches is to use
EXECUTE. There are performance problems with that, because standard
Forth does not guarantee tail-call elimination, and compilers are
limited in their register allocation by not knowing the stack effect
of the EXECUTEd xt; PAF is a Forth dialect designed to fill these
holes, but for now is just an idea:
@InProceedings{ertl13-paf,
author = {M. Anton Ertl},
title = {{PAF}: A Portable Assembly Language},
crossref = {euroforth13},
pages = {30--38},
url = {http://www.complang.tuwien.ac.at/anton/euroforth/ef13/papers/ertl-paf.pdf},
OPTnote = {not refereed},
abstract = {A portable assembly language provides access to
machine-level features like memory addresses,
machine words, code addresses, and modulo
arithmetics, like assembly language, but abstracts
away differences between architectures like the
assembly language syntax, instruction encoding,
register set size, and addressing modes. Forth
already satisfies a number of the characteristics of
a portable assembly language, and is therefore a
good basis. This paper presents PAF, a portable
assembly language based on Forth, and specifically
discusses language features that other portable
assembly languages do not have, and their benefits;
it also discusses the differences from Forth. The
main innovations of PAF are: tags indicate the
control flow for indirect branches and calls; and
PAF has two kinds of calls and definitions: the ABI
ones follow the platform's calling convention and
are useful for interfacing to the outside world,
while the PAF ones allow tail-call elimination and
are useful for implementing general control
structures.}
}
@Proceedings{euroforth13,
title = {29th EuroForth Conference},
booktitle = {29th EuroForth Conference},
year = {2013},
key = {EuroForth'13},
url = {http://www.complang.tuwien.ac.at/anton/euroforth/ef13/papers/proceedings.pdf}
}
- 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 2015: http://www.rigwit.co.uk/EuroForth2015/
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2016-01-12 20:48 +0000 |
| Message-ID | <n73omj$63c$1@dont-email.me> |
| In reply to | #44765 |
On 11/01/2016 22:16, hughaguilar96@gmail.com wrote:
> On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote:
>> In 2012 in a similar discussion I posted an ANS Forth implementation
>> NEXTCASE and other words that seem to meet your and Chris Curls
>> objections. Another opportunity for you to complain about 'ugly,
>> inefficient Forth code' :)
>
> Your code is just generating nested IF statements.
Tell me something I don't know.
>
> Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are.
>
The specification for CASE etc permits code such as:
: foo ( x -- )
>r
case
aaa true of ( action a ) endof
bbb true of ( action b ) endof
ccc r@ of ( action c ) endof
ddd wxyz of ( action d ) endof
...
endcase
...
;
where aaa etc represent one or more Forth words. The values compared by
OF may be repeated, calculated, passed in on the stack and may,
therefore, be unknown at compile time. How would a jump-table handle
those cases?
> Since you are so proud of your CASE NEXTCASE code, how about writing
> a byte-code interpreter? A byte-code interpreter has upwards of 256
> opcodes, so with your method that is upwards of 256 conditional tests
> for every opcode before your program figures out which opcode it has
> and is able to emulate it. Your program should be about three orders
> of magnitude slower than a comparable C program --- a great way to
> disprove the C programmers' assertion that Forth is too slow to be
> useful in the real world.
Surely you're not serious, are you being sarcastic? Anyway you're wrong,
with a (large) tree of nested CASE statements it could be done in 8
comparisons, e.g. testing opcode bit 7, then bit 6 etc. (this may not be
a practical solution but suffices to refute your claim - in fact I'd
hate to set it up and would use a jump table instead). Also look up the
meaning of "upwards of".
--
Gerry
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-01-12 14:16 -0800 |
| Message-ID | <0eab0f6c-42f1-4cbc-bb4d-e3f9a478e4fe@googlegroups.com> |
| In reply to | #44793 |
On Tuesday, January 12, 2016 at 1:48:56 PM UTC-7, Gerry wrote: > On 11/01/2016 22:16, hughaguilar96@gmail.com wrote: > > On Monday, January 11, 2016 at 4:59:16 AM UTC-7, Gerry wrote: > >> In 2012 in a similar discussion I posted an ANS Forth implementation > >> NEXTCASE and other words that seem to meet your and Chris Curls > >> objections. Another opportunity for you to complain about 'ugly, > >> inefficient Forth code' :) > > > > Your code is just generating nested IF statements. > > Tell me something I don't know. You can write nested IF statements yourself. Either use my method of putting the structure in a function by itself and using EXIT to get out, or just do this: IF ELSE IF ELSE IF ELSE IF THEN THEN THEN THEN If you don't want to count how many IF you have, and risk having the wrong number of THEN, then write some meta-compiling code that generates this for you (computers are good at counting). If you are going to use CASE though, and it is going to compare a parameter to constant test values, then you should generate a jump-table because it is orders of magnitude more efficient. > > Did you read what I said about the jump-table? This is how C does their SWITCH statement (also HLA and most likely every other serious language). This is two or three orders of magnitude faster than your method, depending upon how many test values there are. > > > > The specification for CASE etc permits code such as: > : foo ( x -- ) > >r > case > aaa true of ( action a ) endof > bbb true of ( action b ) endof > ccc r@ of ( action c ) endof > ddd wxyz of ( action d ) endof > ... > endcase > ... > ; > where aaa etc represent one or more Forth words. The values compared by > OF may be repeated, calculated, passed in on the stack and may, > therefore, be unknown at compile time. How would a jump-table handle > those cases? This is a very disengenious argument. It is obvious that if you need to do a series of conditional tests then you need nested IF statements. When you ask me how a jump-table would handle this, you are implying that I don't know anything about computer programming --- this is safer and more politically correct for you than to admit that Elizabeth Rather (the author of ANS-Forth) doesn't know anything about computer programming, which is why this goofy CASE statement became part of the Standard. Also obvious, is that generating a flag and then comparing the flag to TRUE is nonsense --- this is going to result in inefficient code in a compiler such as SwiftForth that doesn't do any optimization, and it is just weird and hard-to-read --- you are contorting the ANS-Forth CASE in a desperate attempt to make it appear useful. What I'm saying is that if you are going to compare a value to several constant test values (all from an ENUM most of the time), then it is best to use a jump-table. > > Since you are so proud of your CASE NEXTCASE code, how about writing > > a byte-code interpreter? A byte-code interpreter has upwards of 256 > > opcodes, so with your method that is upwards of 256 conditional tests > > for every opcode before your program figures out which opcode it has > > and is able to emulate it. Your program should be about three orders > > of magnitude slower than a comparable C program --- a great way to > > disprove the C programmers' assertion that Forth is too slow to be > > useful in the real world. > > Surely you're not serious, are you being sarcastic? Anyway you're wrong, > with a (large) tree of nested CASE statements it could be done in 8 > comparisons, e.g. testing opcode bit 7, then bit 6 etc. (this may not be > a practical solution but suffices to refute your claim - in fact I'd > hate to set it up and would use a jump table instead). Nested CASE statements for a byte-code interpreter??? Surely you are not serious! You need to just use a jump-table. I can write code in Forth to manually build a jump-table. I can do this in assembly-language too. The point of having a high-level language rather than assembly-language is that basic control structures such as this are provided --- you don't have to write low-level code like this manually --- similarly you have IF ELSE THEN rather than have to use labels like in most assembly-languages, and you don't write spaghetti code as bad assembly-language programmers are prone to doing. I use jump-tables in Stundurd Forth --- note that I have a GOTO instruction in the processor --- I added GOTO specifically for the purpose of making jump-tables efficient. I don't think that anybody on the ANS-Forth committee knew what a jump-table is. This is why they made that goofy CASE standard, when it is actually just nested IF statements. This is also why there is no GOTO in ANS-Forth. > Also look up the > meaning of "upwards of". Well, I looked it up --- you got me on that one --- I have apparently been using the term incorrectly for 40 years.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-01-08 16:21 +0000 |
| Message-ID | <2016Jan8.172115@mips.complang.tuwien.ac.at> |
| In reply to | #44685 |
Raimond Dragomir <raimond.dragomir@gmail.com> writes:
>Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops:
>
>begin
> test1 if thing1 break then
> test2 if thing2 break then
> ...
>again
>
>This way we can get rid of BEGIN...WHILE...REPEAT loops entirely.
You would also need a word to resolve all the BREAKs. Redefining
AGAIN (one of the basic control flow words) to do that does not appear
to be a good idea.
Anyway, at one point following that line of thought led both Stephen
Pelc and me to implement generalized CASE variants (because the IF
... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
make use of them. Did we follow that line of thought too far? But
other variants have not become popular, either.
- 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 2015: http://www.rigwit.co.uk/EuroForth2015/
[toc] | [prev] | [next] | [standalone]
| From | stephen@mpeforth.com (Stephen Pelc) |
|---|---|
| Date | 2016-01-08 20:12 +0000 |
| Message-ID | <56901637.1989718589@news.eternal-september.org> |
| In reply to | #44703 |
On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at
(Anton Ertl) wrote:
>Anyway, at one point following that line of thought led both Stephen
>Pelc and me to implement generalized CASE variants (because the IF
>... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
>make use of them. Did we follow that line of thought too far? But
>other variants have not become popular, either.
CASE
test1 OF ... ENDOF
test2 OF ... ENDOF
NEXTCASE
I view this as a "get out of jail card".
Forth has no easy way to produce a multiple-exit loop with
exit conditions. Despite lots of recommendations that people
factor more and perhaps (ooh! gasp!) return exit flags, people
persist in writing ugly code. IMHO, because CASE ... ENDCASE
has been in widespread use for a very long time, and is now
standard, perhaps we should consider adding NEXTCASE or some
other extension to solve the problem.
It may be that we have a chicken and egg problem here. If
we provide a solution it may get used,
Stephen
--
Stephen Pelc, stephenXXX@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
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2016-01-09 18:19 +0000 |
| Message-ID | <2016Jan9.191925@mips.complang.tuwien.ac.at> |
| In reply to | #44711 |
stephen@mpeforth.com (Stephen Pelc) writes:
>On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at
>(Anton Ertl) wrote:
>
>>Anyway, at one point following that line of thought led both Stephen
>>Pelc and me to implement generalized CASE variants (because the IF
>>... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not
>>make use of them. Did we follow that line of thought too far? But
>>other variants have not become popular, either.
>
> CASE
> test1 OF ... ENDOF
> test2 OF ... ENDOF
> NEXTCASE
IIRC NEXTCASE has an inconvenient stack effect, and you also provide
NEXT-CASE with a better one.
Gforth (development version) also provides CONTOF for ending an OF and
jumping back to the CASE. So if you do
CASE
test1 ?OF ... CONTOF
test2 ?OF ... CONTOF
...
ENDCASE
this corresponds to Dijkstra's do...od repetition: repeat until none
of the guards are true.
>It may be that we have a chicken and egg problem here. If
>we provide a solution it may get used,
My own non-existent usage of CONTOF and NEXTCASE argues against that,
but it might appeal to others.
- 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 2015: http://www.rigwit.co.uk/EuroForth2015/
[toc] | [prev] | [next] | [standalone]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2016-01-11 09:34 +1100 |
| Message-ID | <n6um98$16af$1@gioia.aioe.org> |
| In reply to | #44711 |
Stephen Pelc wrote: > On Fri, 08 Jan 2016 16:21:15 GMT, anton@mips.complang.tuwien.ac.at > (Anton Ertl) wrote: > > >Anyway, at one point following that line of thought led both Stephen > >Pelc and me to implement generalized CASE variants (because the IF > >... BREAK THEN is very similar to ?OF ... ENDOF), but we then did not > >make use of them. Did we follow that line of thought too far? But > >other variants have not become popular, either. > > CASE > test1 OF ... ENDOF > test2 OF ... ENDOF > NEXTCASE > > I view this as a "get out of jail card". > > Forth has no easy way to produce a multiple-exit loop with > exit conditions. Despite lots of recommendations that people > factor more and perhaps (ooh! gasp!) return exit flags, people > persist in writing ugly code. IMHO, because CASE ... ENDCASE > has been in widespread use for a very long time, and is now > standard, perhaps we should consider adding NEXTCASE or some > other extension to solve the problem. > > It may be that we have a chicken and egg problem here. If > we provide a solution it may get used, The solution is to extend the control-flow words. Justifying it is harder.
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2016-01-08 21:13 +0100 |
| Message-ID | <n6p54a$3nm$1@dont-email.me> |
| In reply to | #44703 |
Anton Ertl wrote: > Raimond Dragomir <raimond.dragomir@gmail.com> writes: >>Or implement a BREAK word for BEGIN...AGAIN and BEGIN...UNTIL loops: >> >>begin >> test1 if thing1 break then >> test2 if thing2 break then >> ... >>again >> >>This way we can get rid of BEGIN...WHILE...REPEAT loops entirely. > > You would also need a word to resolve all the BREAKs. Redefining > AGAIN (one of the basic control flow words) to do that does not appear > to be a good idea. In Gforth, you can use BEGIN .. LEAVE .. DONE for that, all the LEAVEs will jump to DONE. If you want a loop inside that, you need BEGIN BEGIN test1 if thing1 LEAVE then test2 if thing2 LEAVE then AGAIN DONE Of course, you could write an AGAIN-DONE that only needs one BEGIN: : AGAIN-DONE ( begin-sys -- ) ]] YET AGAIN DONE [[ ; immediate (YET is 0 cs-pick, but immediate). -- Bernd Paysan "If you want it done right, you have to do it yourself" net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ* http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2016-01-09 23:46 +1100 |
| Message-ID | <n6qvf5$tib$1@gioia.aioe.org> |
| In reply to | #44683 |
Anton Ertl wrote:
> "HAA" <someone@microsoft.com> writes:
> >This is the problem ANS WHILE was designed to solve. It lets you exit the
> >loop at different points avoiding the need to test (again) which condition
> >caused the exit e.g.
> >
> > BEGIN test1 WHILE test2 WHILE ... REPEAT exit2 ELSE exit1 THEN
> >
> > BEGIN test1 WHILE test2 UNTIL exit2 ELSE exit1 THEN
> >
> >Other variations:
> >
> > BEGIN test1 WHILE test2 WHILE ... REPEAT exit2 THEN exit1
> >
> > BEGIN test1 WHILE test2 WHILE ... REPEAT THEN exit1/exit2
> >
> >The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter 8 ...
> >
> >"The value is that you get simpler programs. And it costs nothing."
>
> There is a mind load cost in the first three examples: the exit
> fragments are not right where the corresponding conditions are, but
> you have to count the WHILEs and THENs and ELSEs, and match them up.
> That's why I prefer things like:
>
> begin
> test1 if exit1 EXIT then
> test2 if exit2 EXIT then
> ...
> again
It appears not everyone on the GForth team shares your reservations...
Examples of multiple WHILE use in GForth 0.7.0
: scan
>r BEGIN dup WHILE over c@ r@ <> WHILE 1 /string REPEAT THEN rdrop ;
: s>unumber? ( addr u -- ud flag )
over [char] ' =
IF \ a ' alone is rather unusual :-)
drop char+ c@ 0 true EXIT
THEN
base @ >r dpl on getbase
0. 2swap
BEGIN ( d addr len )
dup >r >number dup
WHILE \ there are characters left
dup r> -
WHILE \ the last >number parsed something
dup 1- dpl ! over c@ [char] . =
WHILE \ the current char is '.'
1 /string
REPEAT THEN \ there are unparseable characters left
2drop false
ELSE
rdrop 2drop true
THEN
r> base ! ;
: skip-defs ( -- )
BEGIN refill WHILE source -trailing nip 0= UNTIL THEN ;
: (done) ( do-addr -- )
\G resolve branches of leave and ?leave and ?do
\G do-addr is the address of the beginning of our
\G loop so we can take care of nested loops
tleavings @
BEGIN dup
WHILE
>r dup r@ cell+ @ \ address of branch
u> 0= \ lower than DO?
WHILE
r@ 2 cells + @ \ branch token
branchtoresolve,
r@ @ r> free throw
REPEAT r> THEN
tleavings ! drop ;
: (_debug) ( body ip -- )
0 Nesting !
BEGIN Unnest off
cr ." Scanning code..." cr C-Formated on
swap scanword dbg-ip !
cr ." Nesting debugger ready!" cr
BEGIN d.s disp-step D-Key
WHILE C-Stop @ 0=
WHILE 0 get-next set-bp
dbg-ip @ jump
[ here DebugLoop ! ]
restore-bp
REPEAT
Nesting @ 0= IF EXIT THEN
-1 Nesting +! r>
ELSE
get-next >r 1 Nesting +!
THEN
dup
AGAIN ;
: -zeros ( addr u -- addr' u' )
BEGIN dup WHILE 1- 2dup + c@ '0 <> UNTIL 1+ THEN ;
: find-prev-line ( max addr -- max span addr pos2 )
backward^ 2@ forward^ 2!
over 2 + negate s>d backward^ 2@ d+ 0. dmax 2dup hist-setpos
BEGIN
backward^ 2! 2dup get-line WHILE
hist-pos 2dup forward^ 2@ d< WHILE
rot drop
REPEAT 2drop THEN tuck ;
: extract-word ( addr len -- addr' len' ) dup >r
BEGIN 1- dup 0>= WHILE 2dup + c@ bl = UNTIL THEN 1+
tuck + r> rot - ;
: \"-parse ( "string"<"> -- c-addr u ) \ gforth-internal backslash-quote-parse
\G parses string, translating @code{\}-escapes to characters (as in
\G C). The resulting string resides at @code{here}. See @code{S\"}
\G for the supported @code{\-escapes}.
here >r
>in @ chars source chars over + >r + begin ( parse-area R: here parse-end )
dup r@ < while
dup c@ '" <> while
dup c@ dup '\ = if ( parse-area c R: here parse-end )
drop char+ dup r@ = abort" unfinished \-escape"
\-escape c,
else
c, char+
endif
repeat then
char+ source >r - r> min char/ >in !
r> drop
here r> - dup negate allot
here swap char/ ;
: (BranchAddr?) ( a-addr1 -- a-addr2 true | false )
\ searches a branch with destination a-addr1
\ a-addr1: branch destination
\ a-addr2: pointer in branch table
SearchPointer @
BEGIN dup BranchPointer @ u<
WHILE
dup @ 2 pick <>
WHILE 3 cells +
REPEAT
nip dup 3 cells + SearchPointer ! true
ELSE
2drop false
THEN ;
: MyBranch ( a-addr -- a-addr a-addr2 )
\ finds branch table entry for branch at a-addr
dup @
BranchAddr?
BEGIN
WHILE 1 cells - @
over <>
WHILE dup @
MoreBranchAddr?
REPEAT
SearchPointer @ 3 cells -
ELSE true ABORT" SEE: Table failure"
THEN ;
: RepeatCheck ( a-addr1 a-addr2 true | false -- false )
IF BEGIN 2dup
1 cells - @ swap @
u<=
WHILE drop dup cell+
MoreBranchAddr? 0=
UNTIL false
ELSE true
THEN
ELSE false
THEN ;
: see-code-next-inline { addr1 addr2 -- addr3 }
\ decompile starting at addr1 until an inlined primitive is found,
\ or addr2 is reached; addr3 is addr2 or the next inlined
\ primitive
addr1 begin { addr }
addr addr2 u< while
addr @ dup decompile-prim = while
addr cr simple-see-word
addr cell+
repeat then
addr ;
: u8len ( u8 -- n )
dup max-single-byte u< IF drop 1 EXIT THEN \ special case ASCII
$800 2 >r
BEGIN 2dup u>= WHILE 5 lshift r> 1+ >r dup 0= UNTIL THEN
2drop r> ;
: $> ( -- )
BEGIN source >in @ /string s" <$" search 0= WHILE
type cr refill 0= UNTIL EXIT THEN
nip source >in @ /string rot - dup 2 + >in +! type ;
: read-chunked ( fid -- ) base @ >r hex >r
BEGIN pad $100 r@ read-line throw WHILE
pad swap s>number drop dup WHILE r@ add-chunk drop
pad 1 r@ read-line throw nip 0= UNTIL
ELSE drop THEN THEN rdrop r> base ! ;
: skip ( addr1 n1 char -- addr2 n2 ) \ gforth
\G skip all characters equal to char
>r
BEGIN
dup
WHILE
over c@ r@ =
WHILE
1 /string
REPEAT THEN
rdrop ;
: -trailing ( c_addr u1 -- c_addr u2 ) \ string dash-trailing
\G Adjust the string specified by @i{c-addr, u1} to remove all
\G trailing spaces. @i{u2} is the length of the modified string.
BEGIN
dup
WHILE
1- 2dup + c@ bl <>
UNTIL 1+ THEN ;
: (f83find) ( c_addr u f83name1 -- f83name2 )
BEGIN dup WHILE (find-samelen) dup WHILE
>r 2dup r@ cell+ char+ capscomp 0=
IF 2drop r> EXIT THEN
r> @
REPEAT THEN nip nip ;
: (find-samelen) ( u f83name1 -- u f83name2/0 )
BEGIN 2dup cell+ c@ $1F and <> WHILE @ dup 0= UNTIL THEN ;
: (parse-white) ( c_addr1 u1 -- c_addr2 u2 )
BEGIN dup WHILE over c@ bl <= WHILE 1 /string
REPEAT THEN 2dup
BEGIN dup WHILE over c@ bl > WHILE 1 /string
REPEAT THEN nip - ;
....
[toc] | [prev] | [next] | [standalone]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Date | 2016-01-08 10:11 -0500 |
| Message-ID | <20160108101153.4d4729cc@_> |
| In reply to | #44671 |
On Fri, 8 Jan 2016 12:36:25 +1100 "HAA" <someone@microsoft.com> wrote: > Rod Pemberton wrote: > > Since the BEGIN-UNTIL now exits for two > > conditions, you must determine which condition caused > > it to exit, afterwards. > > ... > > This is the problem ANS WHILE was designed to solve. It lets you > exit the loop at different points avoiding the need to test (again) > which condition caused the exit e.g. > > ... > > The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter > 8 ... > > "The value is that you get simpler programs. And it costs nothing." It doesn't cost nothing. The branching clearly increases. My understanding is that modern processors are good with single loops with a backwards branch. That might be somewhat simplistic or out of date, but the point of branching complexity not being good remains. Rod Pemberton
[toc] | [prev] | [next] | [standalone]
| From | "HAA" <someone@microsoft.com> |
|---|---|
| Date | 2016-01-11 08:38 +1100 |
| Message-ID | <n6uivl$t5q$1@gioia.aioe.org> |
| In reply to | #44692 |
Rod Pemberton wrote: > On Fri, 8 Jan 2016 12:36:25 +1100 > "HAA" <someone@microsoft.com> wrote: > > > Rod Pemberton wrote: > > > > Since the BEGIN-UNTIL now exits for two > > > conditions, you must determine which condition caused > > > it to exit, afterwards. > > > ... > > > > This is the problem ANS WHILE was designed to solve. It lets you > > exit the loop at different points avoiding the need to test (again) > > which condition caused the exit e.g. > > > > ... > > > > The topic is discussed by Brodie/Moore in 'Thinking FORTH' Chapter > > 8 ... > > > > "The value is that you get simpler programs. And it costs nothing." > > It doesn't cost nothing. The branching clearly increases. > ... In general I expect ANS WHILE to reduce tests and branching. When you post complete working code it can be compared against the original. The complexity of the logic you propose to use makes me suspicious.
[toc] | [prev] | [next] | [standalone]
| From | november.nihal@gmail.com |
|---|---|
| Date | 2016-01-08 03:04 -0800 |
| Message-ID | <24458bec-ee0e-4fbf-ba58-f79a56a80798@googlegroups.com> |
| In reply to | #44558 |
On Monday, 4 January 2016 22:50:26 UTC, Julian Fondren wrote: > Hello clf, > > The following code is from SwoopPortable.f > > : UPDATE-LINKS ( super link -- ) >R > BEGIN > DUP @ DUP WHILE \ prev cur > R@ BEGIN \ prev cur sup > @ DUP WHILE \ prev cur sup' > 2DUP = UNTIL > 2DROP R> @ SWAP ! EXIT > THEN DROP NIP > REPEAT R> DROP 2DROP ; > > Can someone rewrite this with normal control-flow? > > > Thanks, > Julian Hi Julian, : update-links1 ( s a l -- T )(l -- ) ( s a l -- a F )(l -- l) begin @ dup while ( s a l -- s a b ?b==true ) \ b <- l @ 2dup = if ( s a b -- s a b ?a==b ) 2drop r> @ swap ! true exit ( s a b -- T) ( l -- ) then repeat drop nip false ( s a b -- a F )( l -- l ) ; : update-links ( s l -- ) >r begin ( s l -- s )( -- l ) dup @ dup while ( s -- s a ?a==true )( l -- ) \ a<- s @ r@ update-links1 if exit then repeat r> drop 2drop ; \ a become new s NN
[toc] | [prev] | [standalone]
Page 5 of 5 — ← Prev page 1 2 3 4 [5]
Back to top | Article view | comp.lang.forth
csiph-web