Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.forth

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 03-30-2012, 10:40 PM
Rod Pemberton
Guest
 
Posts: n/a
Default Does ?DO force DO to become bloated?


Does ?DO force DO 's definition to become bloated?

Because both DO and ?DO must work with LOOP and +LOOP, DO ballooned
to a 13 word definition. That's two more than ?DO ...

DO went from a simple 4 word definition to a bunch of do-nothing code. This
is because DO must mirror ?DO's functionality and ?DO must work with LOOP
and +LOOP . Does this sound correct to you?

Also, is it possible to define ?DO in terms of DO ? I assuming that's a
"no", since DO must mirror ?DO 's functionality.

Part of ?DO 's and now DO 's size was because I needed to expand the
definition of IF inline for them to work... I'll have to track down that
issue. I tried to use IF directly. I have COMPILE and [COMPILE] which work
and will give them a try to see what is closest or working. I also have
COMPILE, now and POSTPONE too but I'm avoiding their use in my base code.
COMPILE and [COMPILE] and , (comma) make sense to me for now. Also,
POSTPONE needs some thorough testing ... I thought it should've worked in
the same places as COMPILE and [COMPILE] . I based POSTPONE off of
one of two common definitions posted to c.l.f. years ago.


Rod Pemberton




Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 03-30-2012, 11:24 PM
Elizabeth D. Rather
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On 3/30/12 12:40 PM, Rod Pemberton wrote:
> Does ?DO force DO 's definition to become bloated?
>
> Because both DO and ?DO must work with LOOP and +LOOP, DO ballooned
> to a 13 word definition. That's two more than ?DO ...
>
> DO went from a simple 4 word definition to a bunch of do-nothing code. This
> is because DO must mirror ?DO's functionality and ?DO must work with LOOP
> and +LOOP . Does this sound correct to you?
>
> Also, is it possible to define ?DO in terms of DO ? I assuming that's a
> "no", since DO must mirror ?DO 's functionality.
>
> Part of ?DO 's and now DO 's size was because I needed to expand the
> definition of IF inline for them to work... I'll have to track down that
> issue. I tried to use IF directly. I have COMPILE and [COMPILE] which work
> and will give them a try to see what is closest or working. I also have
> COMPILE, now and POSTPONE too but I'm avoiding their use in my base code.
> COMPILE and [COMPILE] and , (comma) make sense to me for now. Also,
> POSTPONE needs some thorough testing ... I thought it should've worked in
> the same places as COMPILE and [COMPILE] . I based POSTPONE off of
> one of two common definitions posted to c.l.f. years ago.


The function of ?DO is simply to determine whether to proceed with DO or
not. So there's no need to incorporate DO's logic in ?DO or vice-versa.
Just compile ?DO followed by the runtime of DO, and all that will be
skipped if ?DO's test fires.

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."
==================================================
Reply With Quote
  #3 (permalink)  
Old 03-30-2012, 11:46 PM
Josh Grams
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

Rod Pemberton wrote: <jl5cp3$tev$1@speranza.aioe.org>
> Does ?DO force DO 's definition to become bloated?


It shouldn't change DO at all.

?DO should basically compile `2DUP <> IF DO`, and the IF's compile-time
info should be stored so that it will be resolved as if it were a LEAVE.

Do you have LEAVE yet? I'd implement that before ?DO.

--Josh
Reply With Quote
  #4 (permalink)  
Old 03-31-2012, 06:58 AM
Elizabeth D. Rather
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On 3/30/12 1:46 PM, Josh Grams wrote:
> Rod Pemberton wrote:<jl5cp3$tev$1@speranza.aioe.org>
>> Does ?DO force DO 's definition to become bloated?

>
> It shouldn't change DO at all.
>
> ?DO should basically compile `2DUP<> IF DO`, and the IF's compile-time
> info should be stored so that it will be resolved as if it were a LEAVE.


Alternatively, the compile-time ?DO can compile a reference to the
runtime ?DO which checks the stack arguments and, if necessary, discard
the loop parameters and branch to the address beyond the next LOOP or
+LOOP. Then compile a reference to the normal runtime for DO, which will
be part of what gets skipped if necessary.

In other words, keep these words suitably factored. Neither has to do
the other's job.

For example:

: DO ( -- flag addr)
POSTPONE (DO) 0 (BEGIN) ; IMMEDIATE

: ?DO ( -- addr1 flag addr2)
POSTPONE (?DO) (BEGIN)
POSTPONE (DO) 1 (BEGIN) ; IMMEDIATE

....where (DO) and (?DO) are the run-time actions. (?DO) contains a
forward branch which compile-time LOOP or +LOOP must resolve. (BEGIN)
leaves on the compile-time stack an address for LOOP or +LOOP to branch
back to, and a flag.

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."
==================================================
Reply With Quote
  #5 (permalink)  
Old 03-31-2012, 07:29 AM
Rod Pemberton
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

"Josh Grams" <josh@qualdan.com> wrote in message
news:4f7645ed$0$23410$882e7ee2@usenet-news.net...
> Rod Pemberton wrote: <jl5cp3$tev$1@speranza.aioe.org>
> > Does ?DO force DO 's definition to become bloated?

>
> It shouldn't change DO at all.

....

> ?DO should basically compile `2DUP <> IF DO`,


?DO first compiles (?DO) which is currently `2DUP <>` in my case. That's
followed by the definition of IF inlined into ?DO . I've yet to find out
why IF itself won't work there. I thought it was an issue with needing
COMPILE or [COMPILE] but maybe IF just needed to be in (?DO) ...
Continuing, that's followed by compiling (DO) which is what DO compiles.
Finally, there is a HERE at the end of ?DO . The HERE is definately
different from what you mentioned. Otherwise, it's probably equivalent.

So, when using ?DO there are two HERE addresses on the stack, one due to the
IF and one by the explict HERE. One address is for looping and the other is
for the conditional branch in ?DO . That means that LOOP and +LOOP are
always getting two addresses from ?DO . So, they must be coded to use both
of them. That means that DO must also supply two addresses, not just one.
Yes? If only one is provided by DO , then a stack underflow will occur.
I.e., that implies that DO 's code must mirror the implementation of ?DO in
terms of placing addresses on the stack. If LOOP and +LOOP didn't have to
backfill in the conditional forward address from ?DO , then DO would be
simpler.

(Just prior to me posting this, Ms. Rather posted a solution which doesn't
require both DO and ?DO putting two addresses onto the stack.)

> [...] and the IF's compile-time info should be stored so
> that it will be resolved as if it were a LEAVE.
>


Are you talking about the linked-list created "leave" and "rake" chaining
implementation of LEAVES?

> Do you have LEAVE yet?


No.

> I'd implement that before ?DO.


Why?


ISTM that the "leaves-rake" method is complicated. ISTM also that it
doesn't fit well with the other control-flow words. From what I can tell,
it seems that ANS LEAVE also requires a forward reference branch address
that must be resolved, like ?DO . I'm not sure yet how to work that into DO
?DO LOOP +LOOP yet. AIUI, the old fig-Forth LEAVE didn't immediately exit
the loop. It just changed the parameters so the loop exited. Having to
implement a LEAVE which immediately exits the loop is making me hesistant.


Rod Pemberton



Reply With Quote
  #6 (permalink)  
Old 03-31-2012, 07:31 AM
Rod Pemberton
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

"Elizabeth D. Rather" <erather@forth.com> wrote in message
news:sr6dnQSBkK-NNuvSnZ2dnUVZ_vednZ2d@supernews.com...
> On 3/30/12 1:46 PM, Josh Grams wrote:
> > Rod Pemberton wrote:<jl5cp3$tev$1@speranza.aioe.org>
> >> Does ?DO force DO 's definition to become bloated?

> >
> > It shouldn't change DO at all.
> >
> > ?DO should basically compile `2DUP<> IF DO`, and the IF's compile-time
> > info should be stored so that it will be resolved as if it were a LEAVE.

>
> Alternatively, the compile-time ?DO can compile a reference to the
> runtime ?DO which checks the stack arguments and, if necessary, discard
> the loop parameters and branch to the address beyond the next LOOP or
> +LOOP. Then compile a reference to the normal runtime for DO, which will
> be part of what gets skipped if necessary.
>
> In other words, keep these words suitably factored. Neither has to do
> the other's job.
>
> For example:
>
> : DO ( -- flag addr)
> POSTPONE (DO) 0 (BEGIN) ; IMMEDIATE
>
> : ?DO ( -- addr1 flag addr2)
> POSTPONE (?DO) (BEGIN)
> POSTPONE (DO) 1 (BEGIN) ; IMMEDIATE
>
> ...where (DO) and (?DO) are the run-time actions. (?DO) contains a
> forward branch which compile-time LOOP or +LOOP must resolve. (BEGIN)
> leaves on the compile-time stack an address for LOOP or +LOOP to branch
> back to, and a flag.
>


Ok, make LOOP and +LOOP "smarter" or DO/?DO-aware ... I had decided against
attempting to pair them, in case there was some unforeseen issue leading to
a mismatch. But, that works or should. It's simple enough.

My ?DO is putting two addresses onto the stack, one for the loop and one for
the forward branch that needs resolving. Because of ?DO needing two
addresses and it "passing" both to LOOP and +LOOP , I changed DO to also put
two addresses onto the stack instead of only one. That's what I meant by
the bloating.


Rod Pemberton


Reply With Quote
  #7 (permalink)  
Old 03-31-2012, 09:58 AM
Josh Grams
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

Rod Pemberton wrote: <jl6bon$mnj$1@speranza.aioe.org>
> "Josh Grams" <josh@qualdan.com> wrote in message
> news:4f7645ed$0$23410$882e7ee2@usenet-news.net...
>
> (Just prior to me posting this, Ms. Rather posted a solution which doesn't
> require both DO and ?DO putting two addresses onto the stack.)
>
>> [...] and the IF's compile-time info should be stored so
>> that it will be resolved as if it were a LEAVE.

>
> Are you talking about the linked-list created "leave" and "rake" chaining
> implementation of LEAVES?


It doesn't have to be a linked-list implementation -- you can keep the
forward branch references on the stack along with a count. It would be
like the code that Elizabeth posted, but instead of a flag and a single
address, you would have a count on top of 0 or more addresses.

E.g. assuming (DO) is 2>R and (?DO) is 2DUP <>:

: do ( C: -- 0 dest )
postpone (do) 0 postpone begin ; immediate
: ?DO ( C: -- orig 1 dest )
postpone (?do) postpone if 1
postpone (do) postpone begin ; immediate

: leave ( u*orig u dest -- u+1*orig u+1 dest )
postpone unloop
>r >r postpone ahead r> 1+ r> ; immediate


At the end of loop/+loop you want to resolve all the branches:

: thens ( u*orig u -- )
begin dup while 1- over postpone then repeat drop ;

Does that make sense?

--Josh
Reply With Quote
  #8 (permalink)  
Old 03-31-2012, 11:21 AM
segher
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On Mar 31, 11:58*am, Josh Grams <j...@qualdan.com> wrote:
> It doesn't have to be a linked-list implementation -- you can keep the
> forward branch references on the stack along with a count.


LEAVE does not have special compilation semantics, in
particular it does not have access to a do-sys, so this
can not be a conforming implementation.


Segher
Reply With Quote
  #9 (permalink)  
Old 03-31-2012, 01:29 PM
Hans Bezemer
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

Rod Pemberton wrote:

> AIUI, the old fig-Forth LEAVE didn't immediately exit
> the loop. It just changed the parameters so the loop exited. Having to
> implement a LEAVE which immediately exits the loop is making me hesistant.

I agree with you. With the danger of starting a flame war again, I kept with
the original Forth-79 implementation. First, now with ?DO we have TWO words
which make the decision to branch or not. Second, the redefinition of
Forth-83 to allow to "drop" through the loop instead of doing the sensible
thing and abort (yeah, you can now cover the entire address range, cool)
made an already somewhat flawed construction worse. So, ?DO was added to
make it still worse. Now we have a very, very flawed LOOP construct, which
is beyond repair. Yes, beyond repair, because it would break so much code
to fix this, nobody would never, ever touch this one.

Hans Bezemer
Reply With Quote
  #10 (permalink)  
Old 03-31-2012, 02:19 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On Mar 31, 5:58*am, Josh Grams <j...@qualdan.com> wrote:
> : leave ( u*orig u dest -- u+1*orig u+1 dest )
> * * * * postpone unloop
> * * * * >r *>r postpone ahead r> 1+ *r> ; immediate


That's broken, since there can be arbitrary structured words the
DO ... LOOP.

If the compile structures stack is the data stack and you have a data
stack index, which I think Rod will have, you can hold a leave count
in one variable and the height of the data stack in another. When you
do LEAVE, increment the leave count, and bubble the orig down to the
original DO-LOOP stack height. Then RAKE-LEAVES just postpones a THEN
for each orig, which should be on the top of the stack, until the
leave count is 0.

Then DO would save the old leave count and data stack height on the
return stack and LOOP and +LOOP would restore it.
Reply With Quote
  #11 (permalink)  
Old 03-31-2012, 02:43 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On Mar 31, 3:29*am, "Rod Pemberton" <do_not_h...@noavailemail.cmm>
wrote:
> "Josh Grams" <j...@qualdan.com> wrote in message
>
> news:4f7645ed$0$23410$882e7ee2@usenet-news.net...> Rod Pemberton wrote: <jl5cp3$te...@speranza.aioe.org>
> > > Does ?DO force DO 's definition to become bloated?

>
> > It shouldn't change DO at all.

>
> ...
>
> > ?DO should basically compile `2DUP <> IF DO`,

>
> ?DO first compiles (?DO) which is currently `2DUP <>` in my case. *That's
> followed by the definition of IF inlined into ?DO . *I've yet to find out
> why IF itself won't work there. *I thought it was an issue with needing
> COMPILE or [COMPILE] but maybe IF just needed to be in (?DO) ...
> Continuing, that's followed by compiling (DO) which is what DO compiles.
> Finally, there is a HERE at the end of ?DO . *The HERE is definately
> different from what you mentioned. *Otherwise, it's probably equivalent..
>
> So, when using ?DO there are two HERE addresses on the stack, one due to the
> IF and one by the explict HERE. *One address is for looping and the other is
> for the conditional branch in ?DO . *That means that LOOP and +LOOP are
> always getting two addresses from ?DO . *So, they must be coded to use both
> of them. *That means that DO must also supply two addresses, not just one.
> Yes? *If only one is provided by DO , then a stack underflow will occur..
> I.e., that implies that DO 's code must mirror the implementation of ?DO in
> terms of placing addresses on the stack. *If LOOP and +LOOP didn't haveto
> backfill in the conditional forward address from ?DO , then DO would be
> simpler.
>
> (Just prior to me posting this, Ms. Rather posted a solution which doesn't
> require both DO and ?DO putting two addresses onto the stack.)
>
> > [...] and the IF's compile-time info should be stored so
> > that it will be resolved as if it were a LEAVE.

>
> Are you talking about the linked-list created "leave" and "rake" chaining
> implementation of LEAVES?
>
> > Do you have LEAVE yet?

>
> No.
>
> > I'd implement that before ?DO.

>
> Why?


> ISTM that the "leaves-rake" method is complicated.


How complicate it is depends on how you implement it. If you implement
it for simplicity, it can be as simple as postponing a THEN as long as
loop count is greater than zero:

: RAKE-LEAVES ( C: u1 u2 count*orig -- )
leave-count @
BEGIN ?DUP WHILE SWAP POSTPONE THEN REPEAT
leave-count ! do-height ! ;

> ISTM also that it doesn't fit well with the other
> control-flow words.


Quite, its a exceptional exit from the do-loop, and does not use the
regular compile-time structure stack.

> From what I can tell, it seems that ANS LEAVE also
> requires a forward reference branch address that must be
> resolved, like ?DO


Yes, which is why if you have LEAVE already, the simplest way to do ?
DO is to hook into that system.

> I'm not sure yet how to work that into DO ?DO LOOP +LOOP yet.


In that case, have DO drop a "0" on the stack before it drops its
"dest", and have ?DO drop a "TRUE" on the stack after it postpones its
"IF".

Then at the right time in LOOP and +LOOP, you have:
... IF POSTPONE THEN THEN ...

.... and you're set until you work out how you are going to handle
LEAVE.
Reply With Quote
  #12 (permalink)  
Old 03-31-2012, 06:25 PM
Elizabeth D. Rather
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On 3/30/12 9:31 PM, Rod Pemberton wrote:
> "Elizabeth D. Rather"<erather@forth.com> wrote in message
> news:sr6dnQSBkK-NNuvSnZ2dnUVZ_vednZ2d@supernews.com...
>> On 3/30/12 1:46 PM, Josh Grams wrote:
>>> Rod Pemberton wrote:<jl5cp3$tev$1@speranza.aioe.org>
>>>> Does ?DO force DO 's definition to become bloated?
>>>
>>> It shouldn't change DO at all.
>>>
>>> ?DO should basically compile `2DUP<> IF DO`, and the IF's compile-time
>>> info should be stored so that it will be resolved as if it were a LEAVE.

>>
>> Alternatively, the compile-time ?DO can compile a reference to the
>> runtime ?DO which checks the stack arguments and, if necessary, discard
>> the loop parameters and branch to the address beyond the next LOOP or
>> +LOOP. Then compile a reference to the normal runtime for DO, which will
>> be part of what gets skipped if necessary.
>>
>> In other words, keep these words suitably factored. Neither has to do
>> the other's job.
>>
>> For example:
>>
>> : DO ( -- flag addr)
>> POSTPONE (DO) 0 (BEGIN) ; IMMEDIATE
>>
>> : ?DO ( -- addr1 flag addr2)
>> POSTPONE (?DO) (BEGIN)
>> POSTPONE (DO) 1 (BEGIN) ; IMMEDIATE
>>
>> ...where (DO) and (?DO) are the run-time actions. (?DO) contains a
>> forward branch which compile-time LOOP or +LOOP must resolve. (BEGIN)
>> leaves on the compile-time stack an address for LOOP or +LOOP to branch
>> back to, and a flag.
>>

>
> Ok, make LOOP and +LOOP "smarter" or DO/?DO-aware ... I had decided against
> attempting to pair them, in case there was some unforeseen issue leading to
> a mismatch. But, that works or should. It's simple enough.


The DO words and LOOP words are inevitably paired. That's why the
standard uses special compile-time stack nomenclature 'do-orig' and
'do-dest' to describe them. And simple solutions are always best :-)

The LOOP words don't have to be very smart, just fix the necessary
address if there is one.

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."
==================================================
Reply With Quote
  #13 (permalink)  
Old 03-31-2012, 06:56 PM
Hans Bezemer
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

Elizabeth D. Rather wrote:
> The function of ?DO is simply to determine whether to proceed with DO or
> not. So there's no need to incorporate DO's logic in ?DO or vice-versa.
> Just compile ?DO followed by the runtime of DO, and all that will be
> skipped if ?DO's test fires.

"Simply.."

2DUP <> IF DO .. LOOP ELSE 2DROP THEN

Too horrible for words.. Elegant is different.

Hans Bezemer
Reply With Quote
  #14 (permalink)  
Old 03-31-2012, 07:02 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On Mar 31, 3:31*am, "Rod Pemberton" <do_not_h...@noavailemail.cmm>
wrote:
> Ok, make LOOP and +LOOP "smarter" or DO/?DO-aware ... *I had decided
> against attempting to pair them, in case there was some unforeseen issue
> leading to a mismatch. *But, that works or should. *It's simple enough.


Well, you're patching an existing model, so that can complicate things
compared to designing it to suit ...

Wouldn't a simple state flag variable work? Something like the
following, if (LOOP) and (+LOOP) include UNLOOP as part of their
behavior?

VARIABLE ?do?

: 2DUP= ( x1 x2 -- x1 x2 flag ) 2DUP = ;
: DO ?do? @ ?do? OFF [COMPILE] (DO) HERE 0 , ; IMMEDIATE
: ?DO POSTPONE 2DUP= POSTPONE IF POSTPONE DO TRUE ?do? ! ; IMMEDIATE

: COMPLETE-?DO ( x dest | x -- ) ?do? @ IF POSTPONE THEN THEN ?do? ! ;

: LOOP POSTPONE (LOOP) , COMPLETE-?DO ; IMMEDIATE
: +LOOP POSTPONE (+LOOP) , COMPLETE-?DO ; IMMEDIATE


> My ?DO is putting two addresses onto the stack, one for the loop and one
> for the forward branch that needs resolving. *Because of ?DO needing two
> addresses and it "passing" both to LOOP and +LOOP , I changed DO to also
> put two addresses onto the stack instead of only one.


A variety of ways to implement it, but its probably not needed to have
DO include a dummy jump that is never taken.
Reply With Quote
  #15 (permalink)  
Old 03-31-2012, 07:32 PM
BruceMcF
Guest
 
Posts: n/a
Default Re: Does ?DO force DO to become bloated?

On Mar 31, 2:56*pm, Hans Bezemer <the.beez.spe...@gmail.com> wrote:
> Elizabeth D. Rather wrote:
>> The function of ?DO is simply to determine whether to proceed with DO or
>> not. So there's no need to incorporate DO's logic in ?DO or vice-versa.
>> Just compile ?DO followed by the runtime of DO, and all that will be
>> skipped if ?DO's test fires.


> "Simply.."


> * * * * 2DUP <> IF DO .. LOOP ELSE 2DROP THEN


> Too horrible for words.. Elegant is different.


From the text description, it sounds like the ?DO runtime, aka (?DO)
or do_QDO would clean up the loop parameters before taking the branch,
rather than laboriously compiling that process into each ?DO-LOOP:

> Alternatively, the compile-time ?DO can compile a reference to the
> runtime ?DO which checks the stack arguments and, if necessary, discard
> the loop parameters and branch to the address beyond the next LOOP or
> +LOOP. Then compile a reference to the normal runtime for DO, which will
> be part of what gets skipped if necessary.

Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 07:35 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.