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


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

factoring exercise

Started bym_l_g3 <m_l_g3@yahoo.com>
First post2011-07-28 12:22 -0700
Last post2011-08-01 21:03 -0700
Articles 12 — 7 participants

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


Contents

  factoring exercise m_l_g3 <m_l_g3@yahoo.com> - 2011-07-28 12:22 -0700
    Re: factoring exercise Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-07-29 16:14 -0700
      Re: factoring exercise mlg3 <m_l_g3@yahoo.com> - 2011-08-03 01:36 +0400
        Re: factoring exercise Julian Fondren <ayrnieu@gmail.com> - 2011-08-02 17:25 -0500
          Re: factoring exercise mlg3 <m_l_g3@yahoo.com> - 2011-08-03 23:19 +0400
    Re: factoring exercise Julian Fondren <ayrnieu@gmail.com> - 2011-07-29 23:19 -0700
      Re: factoring exercise Julian Fondren <ayrnieu@gmail.com> - 2011-07-30 02:45 -0500
        Re: factoring exercise arc <arc@vorsicht-bissig.de> - 2011-08-09 10:47 +0000
      Re: factoring exercise "arc@vorsicht-bissig.de" <arc@vorsicht-bissig.de> - 2011-08-07 03:11 -0700
        Re: factoring exercise Julian Fondren <ayrnieu@gmail.com> - 2011-08-07 13:53 -0500
    Re: factoring exercise Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-07-30 02:14 -0500
    Re: factoring exercise Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-08-01 21:03 -0700

#4472 — factoring exercise

Fromm_l_g3 <m_l_g3@yahoo.com>
Date2011-07-28 12:22 -0700
Subjectfactoring exercise
Message-ID<44ea6cbf-3e3a-4a65-beb3-b4b3f70b2f07@fq4g2000vbb.googlegroups.com>
In a message that did not appear in google groups (does it work at
all? I will see) I wrote:


\ for Gforth:
: x>cflag ( cfa x1 -- xt x2 )
  dup restrict-mask and    if drop -3 else
  over interpret/compile?  if drop interpret/compile-comp @ -2 else
  dup immediate-mask and   if drop -1 else
                              drop 0 then then then
;
: x>iflag ( cfa x1 -- xt x2 )
  dup restrict-mask and    if drop -3 else
  over interpret/compile?  if drop interpret/compile-int @ -2 else
  dup immediate-mask and   if drop -1 else
                              drop 0 then then then
;
: search-compile ( addr len -- xt flag1 true | addr len false )
	2dup find-name dup if nip nip (name>x) x>cflag true then
;
: search-interpret ( addr len -- xt flag1 true | addr len false )
	2dup find-name dup if (name>x) x>iflag dup -3 = if 2drop 0 else 2nip
true then then
;

Obviously, x>cflag and x>iflag are a copy-paste, which is bad.

The exercise is to propose a better factoring.

[toc] | [next] | [standalone]


#4488

FromHugh Aguilar <hughaguilar96@yahoo.com>
Date2011-07-29 16:14 -0700
Message-ID<c123e369-af17-490e-84d7-b83631319691@f17g2000prf.googlegroups.com>
In reply to#4472
On Jul 28, 1:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
> In a message that did not appear in google groups (does it work at
> all? I will see) I wrote:
>
> \ for Gforth:
> : x>cflag ( cfa x1 -- xt x2 )
>   dup restrict-mask and    if drop -3 else
>   over interpret/compile?  if drop interpret/compile-comp @ -2 else
>   dup immediate-mask and   if drop -1 else
>                               drop 0 then then then
> ;
> : x>iflag ( cfa x1 -- xt x2 )
>   dup restrict-mask and    if drop -3 else
>   over interpret/compile?  if drop interpret/compile-int @ -2 else
>   dup immediate-mask and   if drop -1 else
>                               drop 0 then then then
> ;
> : search-compile ( addr len -- xt flag1 true | addr len false )
>         2dup find-name dup if nip nip (name>x) x>cflag true then
> ;
> : search-interpret ( addr len -- xt flag1 true | addr len false )
>         2dup find-name dup if (name>x) x>iflag dup -3 = if 2drop 0 else 2nip
> true then then
> ;
>
> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>
> The exercise is to propose a better factoring.

Well, the only difference seems to be the variables INTERPRET/COMPILE-
COMP and INTERPRET/COMPILE-INT --- so just pass the address of the
variable in as a parameter. If these aren't variables but are
functions, then pass the xt of the function in as a parameter.

The above solution increases what is done at run-time. If you want to
avoid this speed penalty, then write a function that executes at
compile-time and generates a colon word that will execute at run-time.
You can use my :NAME so that this function can be given the name of
the function that it is to generate. It is given the address of the
variable (INTERPRET/COMPILE-COMP or INTERPRET/COMPILE-INT) that it is
to use, and it compiles this as a literal (use LIT to do this). This
second solution is more complicated, so it would only be appropriate
if you are generating a lot of similar words and/or there is a lot of
concern about speed.

Are you actually writing a program and this question came up, or is
this just theoretical?

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


#4553

Frommlg3 <m_l_g3@yahoo.com>
Date2011-08-03 01:36 +0400
Message-ID<j19qk0$d2h$1@dont-email.me>
In reply to#4488
Hugh Aguilar wrote:
> On Jul 28, 1:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
>> In a message that did not appear in google groups (does it work at
>> all? I will see) I wrote:
>>
>> \ for Gforth:
>> : x>cflag ( cfa x1 -- xt x2 )
>>   dup restrict-mask and    if drop -3 else
>>   over interpret/compile?  if drop interpret/compile-comp @ -2 else
>>   dup immediate-mask and   if drop -1 else
>>                               drop 0 then then then
>> ;
>> : x>iflag ( cfa x1 -- xt x2 )
>>   dup restrict-mask and    if drop -3 else
>>   over interpret/compile?  if drop interpret/compile-int @ -2 else
>>   dup immediate-mask and   if drop -1 else
>>                               drop 0 then then then
>> ;
>> : search-compile ( addr len -- xt flag1 true | addr len false )
>>         2dup find-name dup if nip nip (name>x) x>cflag true then
>> ;
>> : search-interpret ( addr len -- xt flag1 true | addr len false )
>>         2dup find-name dup if (name>x) x>iflag dup -3 = if 2drop 0 else 2nip
>> true then then
>> ;
>>
>> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>>
>> The exercise is to propose a better factoring.
> 
> Well, the only difference seems to be the variables INTERPRET/COMPILE-
> COMP and INTERPRET/COMPILE-INT --- so just pass the address of the
> variable in as a parameter. If these aren't variables but are
> functions, then pass the xt of the function in as a parameter.
> 
> The above solution increases what is done at run-time. If you want to
> avoid this speed penalty, then write a function that executes at
> compile-time and generates a colon word that will execute at run-time.
> You can use my :NAME so that this function can be given the name of
> the function that it is to generate. It is given the address of the
> variable (INTERPRET/COMPILE-COMP or INTERPRET/COMPILE-INT) that it is
> to use, and it compiles this as a literal (use LIT to do this). This
> second solution is more complicated, so it would only be appropriate
> if you are generating a lot of similar words and/or there is a lot of
> concern about speed.
> 
> Are you actually writing a program and this question came up, or is
> this just theoretical?

I wrote a program and noticed the issue. So, it was encountered in 
practice rather than specially constructed.

The code is related to the RfD: FOUND. To illustrate some point (*), I 
needed words that find compilation and interpretation semantics of a 
name in Gforth.

(*) the point was that splitting the search-semantics functionality into 
two words is natural for dual-xt systems like Gforth but extremely 
confusing if not disastrous for classical systems like Win32Forth.

So search-compile and search-interpret have the stack effect of
( addr len -- xt flag1 true | addr len false )
where (addr,len) specifies the name to search for, the result (addr name 
false) indicates that the name was not found, true means that the name 
was found, xt is its xt, and flag1 is zero for words that must be 
COMPILE,-d in compilation state, and non-zero for words that must be 
EXECUTE-d in compilation state.

More precisely, the values for flag1 are:
0 -- ordinary word (e.g. DUP )
-1 -- immediate word (e.g. \ )
-2 -- a dual-xt word (e.g. TO )
-3 -- a compile-only word (e.g. IF )

As to FIND-NAME, it's a Gforth word, it has a variable stack effect and 
2DROP-s (addr,len) regardless of whether or not the name has been found, 
so I needed a 2DUP in front of it and a 2NIP in the "name found" branch 
to undo this 2DUP.

Now I have to apologize: I had a false impression that all people read 
Gforth source with no problems, and I am the only one intolerant to 
dual-xts and Gforth internals. x>cflag and x>iflag are a modified 
copy-paste from the Gforth stuff like:

: name>int ( nt -- xt )
     \G @i{xt} represents the interpretation semantics of the word [...]
     (name>x) (x>int) ;


The most confusing thing is interpret/compile-int -- this word is not a 
variable, it is a field ( addr -- addr+off).

 >> : x>iflag ( cfa x1 -- xt x2 )
cfa is called cfa but it may be used as an xt
x1 is a set of flags
 >>[..]
( cfa xt )
 >>   over interpret/compile?  if drop interpret/compile-int @ -2 else

here interpret/compile? takes cfa and checks if it is a dual-xt word;
DROP -- we just discard x1, x1 is not used for dual-xt words

And the line:

( cfa ) interpret-compile-int ( cfa+offset ) @ ( xt-int )

explains why cfa is not called xt: the code field is a struct, and we 
fetch a value from that struct. That value also points to some 
structure, but that structure is irrelevant and we call it xt -- an 
opaque execution token.

Anyway, I finally could illustrate my point, even if the code was not 
perfect, and I posted the code. After I posted it, I noticed that this 
is a demonstrative example: two definitions are almost identical, but in 
real world (in any [other] programming language and with a deadline) it 
would be copy-paste coding rather than factoring. On the other hand, I 
remembered how rethinking helped to avoid cumbersome stack manipulations 
when drawing a rectangle, and decided to start this thread.

So far I have seen only two more or less elegant solutions, one with R> 
2DROP ... EXIT (by Julian Fondren) and another with R@ @ EXECUTE ... R> 
CELL+ >R (by myself), the second one even less portable than the first.

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


#4554

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-08-02 17:25 -0500
Message-ID<86pqkn5u46.fsf@gmail.com>
In reply to#4553
mlg3 <m_l_g3@yahoo.com> writes:
> Now I have to apologize: I had a false impression that all people read
> Gforth source with no problems, and I am the only one intolerant to
> dual-xts and Gforth internals. x>cflag and x>iflag are a modified
> copy-paste from the Gforth stuff like:
>
> : name>int ( nt -- xt )
>     \G @i{xt} represents the interpretation semantics of the word [...]
>     (name>x) (x>int) ;
>
>
> The most confusing thing is interpret/compile-int -- this word is not
> a variable, it is a field ( addr -- addr+off).
>
>>> : x>iflag ( cfa x1 -- xt x2 )
> cfa is called cfa but it may be used as an xt
> x1 is a set of flags
>>>[..]
> ( cfa xt )
>>>   over interpret/compile?  if drop interpret/compile-int @ -2 else
>
> here interpret/compile? takes cfa and checks if it is a dual-xt word;
> DROP -- we just discard x1, x1 is not used for dual-xt words
>
> And the line:
>
> ( cfa ) interpret-compile-int ( cfa+offset ) @ ( xt-int )
>
> explains why cfa is not called xt: the code field is a struct, and we
> fetch a value from that struct. That value also points to some
> structure, but that structure is irrelevant and we call it xt -- an
> opaque execution token.

Is it safe to fetch from the wrong field?  If so,

  : (x>flag) ( cfa x1 -- xt-c xt-i x2 )
    dup restrict-mask and    if drop dup -3 else
    over interpret/compile?  if drop dup interpret/compile-comp @
                                swap interpret/compile-int @ -2 else
    immediate-mask and       if dup -1 else
                                dup 0 then then then ;

  : x>cflag ( cfa x1 -- xt x2 )  (x>flag) nip ;
  : x>iflag ( cfa x1 -- xt x2 )  (x>flag) rot drop ;

Maybe the fields are adjacent in gforth, and you can e.g.

  if drop interpret/compile-int 2@ ( xt-c xt-i ) -2 else

Maybe you can give (X>FLAG) a nicer name and use it in place of X>CFLAG
and X>IFLAG

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


#4568

Frommlg3 <m_l_g3@yahoo.com>
Date2011-08-03 23:19 +0400
Message-ID<j1c70d$mec$1@dont-email.me>
In reply to#4554
Julian Fondren wrote:
> mlg3 <m_l_g3@yahoo.com> writes:
>> Now I have to apologize: I had a false impression that all people read
>> Gforth source with no problems, and I am the only one intolerant to
>> dual-xts and Gforth internals. x>cflag and x>iflag are a modified
>> copy-paste from the Gforth stuff like:
>>
>> : name>int ( nt -- xt )
>>     \G @i{xt} represents the interpretation semantics of the word [...]
>>     (name>x) (x>int) ;
>>
>>
>> The most confusing thing is interpret/compile-int -- this word is not
>> a variable, it is a field ( addr -- addr+off).
>>
>>>> : x>iflag ( cfa x1 -- xt x2 )
>> cfa is called cfa but it may be used as an xt
>> x1 is a set of flags
>>>> [..]
>> ( cfa xt )
>>>>   over interpret/compile?  if drop interpret/compile-int @ -2 else
>> here interpret/compile? takes cfa and checks if it is a dual-xt word;
>> DROP -- we just discard x1, x1 is not used for dual-xt words
>>
>> And the line:
>>
>> ( cfa ) interpret-compile-int ( cfa+offset ) @ ( xt-int )
>>
>> explains why cfa is not called xt: the code field is a struct, and we
>> fetch a value from that struct. That value also points to some
>> structure, but that structure is irrelevant and we call it xt -- an
>> opaque execution token.
> 
> Is it safe to fetch from the wrong field?  If so,
> 
>   : (x>flag) ( cfa x1 -- xt-c xt-i x2 )
>     dup restrict-mask and    if drop dup -3 else
>     over interpret/compile?  if drop dup interpret/compile-comp @
>                                 swap interpret/compile-int @ -2 else
>     immediate-mask and       if dup -1 else
>                                 dup 0 then then then ;
> 
>   : x>cflag ( cfa x1 -- xt x2 )  (x>flag) nip ;
>   : x>iflag ( cfa x1 -- xt x2 )  (x>flag) rot drop ;

So far it is the best idea. But the word must be called (x>ciflag),
because "iflag" is not "interpretation flag", it is "interpretation
semantics and flag". (For some reason (or maybe without one)
Gforth calls the pair (cfa,flags) x).

But this approach is not usable in the general case where in

: foo
	test1 if quux else
	test2 if CORGE else
	test3 if garply else
		 waldo then then then ;
: bar
	test1 if quux else
	test2 if GRAULT else
	test3 if garply else
		 waldo then then then ;

it is not possible to execute both CORGE and GRAULT.

> 
> Maybe the fields are adjacent in gforth, and you can e.g.
> 
>   if drop interpret/compile-int 2@ ( xt-c xt-i ) -2 else
> 
> Maybe you can give (X>FLAG) a nicer name and use it in place of X>CFLAG
> and X>IFLAG

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


#4495

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-07-29 23:19 -0700
Message-ID<117106f5-99ee-46bd-958b-d9d63e8d147e@w24g2000yqw.googlegroups.com>
In reply to#4472
On Jul 28, 2:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>
> The exercise is to propose a better factoring.

Nobody's replied, so I will.


1. Variations on the obvious way:

  : (x>flag) ( cfa x1 a-i/c -- xt x2 )
    >r dup restrict-mask and  if drop -3 else
    over interpret/compile?   if drop r> execute @ -2 exit else
    dup immediate-mask and    if drop -1 else
                                 drop 0 then then then r>drop ;

  : x>iflag  ['] interpret/compile-int  (x>flag) ;
  : x>cflag  ['] interpret/compile-comp (x>flag) ;

...

  variable STATE
  : x>flag ( cfa x1 -- xt x2 )
    dup restrict-mask and     if drop -3 else
    over interpret/compile?   if drop STATE @ execute -2 else
    dup immediate-mask and    if drop -1 else
                                 drop 0 then then then ;

  : interpreting  ['] interpret/compile-int  STATE ! ;
  : compiling     ['] interpret/compile-comp STATE ! ;

...

  : later  r> r> 2>r ;
  : (x>flag) ( cfa x1 -- xt x2 )
    dup restrict-mask and    if drop -3 else
    over interpret/compile?  if drop later @ -2 exit else
    dup immediate-mask and   if drop -1 else
                                drop 0 then then then r>drop ;

  : x>iflag  (x>flag) interpret/compile-int ;
  : x>cflag  (x>flag) interpret/compile-comp ;


2. Breaking up x>ciflag

  : match  postpone if postpone r> postpone 2drop ; immediate

  ( cfa x1 -- cfa x1 | xt x2 )
  : restrict;   dup restrict-mask and match -3 then ;
  : interpret;  over interpret/compile?
                match interpret/compile-int @ -2 then ;
  : compile;    over interpret/compile?
                match interpret/compile-comp @ -2 then ;
  : immediate;  dup immediate-mask and match -1 then ;

  ( cfa x1 -- xt x2 )
  : x>iflag   restrict; interpret; immediate; drop 0 ;
  : x>cflag   restrict;   compile; immediate; drop 0 ;


3. Not doing it in x>ciflag

  : x>flag ( cfa x1 -- xt x2 f )
    dup restrict-mask and     if drop -3 false else
    over interpret/compile?   if drop true else
    dup immediate-mask and    if drop -1 false else
                                 drop 0 false then then then ;

  : search-compile ( addr len -- xt flag1 true | addr len false )
    2dup find-name dup 0= ?exit
    nip nip (name>x) x>flag if interpret/compile-comp @ -2 then true ;

  : search-interpret ( addr len -- xt flag1 true | addr len false )
    2dup find-name dup 0= ?exit
    (name>x) x>flag if interpret/compile-int @ -2 true exit then
    dup -3 = if 2drop 0 else 2nip true then ;

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


#4497

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-07-30 02:45 -0500
Message-ID<86zkjw43f9.fsf@gmail.com>
In reply to#4495
Julian Fondren <ayrnieu@gmail.com> writes:

> On Jul 28, 2:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
>> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>>
>> The exercise is to propose a better factoring.
>
> Nobody's replied, so I will.

Bah, there are three replies now, including this one that I sent through
Google Groups itself, and still Google Groups does not display any of
them.  http://www.eternal-september.org/ seems OK, with the Gnus reader.

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


#4657

Fromarc <arc@vorsicht-bissig.de>
Date2011-08-09 10:47 +0000
Message-ID<j1r37e$m09$1@dont-email.me>
In reply to#4497
Julian Fondren wrote:

> Julian Fondren <ayrnieu@gmail.com> writes:
>
>> On Jul 28, 2:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
>>> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>>>
>>> The exercise is to propose a better factoring.
>>
>> Nobody's replied, so I will.
>
> Bah, there are three replies now, including this one that I sent through
> Google Groups itself, and still Google Groups does not display any of
> them.  http://www.eternal-september.org/ seems OK, with the Gnus reader.

Google Groups also lost my reply (message ID: 
<1bcfe8e4-26c4-485f-99c6-556939b6ded5@glegroupsg2000goo.googlegroups.com> )
to your reply (message ID:
<117106f5-99ee-46bd-958b-d9d63e8d147e@w24g2000yqw.googlegroups.com> )
and your replay to that (message ID:  <86d3gh3vg2.fsf@gmail.com>). 

Seems as though a traditional newsfeed is a more reliable way of seeing
everything for the time being, so I'm now using a newsreader pointed at
eternal september myself: thanks for the heads-up.

I've submitted a bug notification about it, plus a bug notification
about the bug notification form not accepting the new Google Group URLs. 

-arc. 

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


#4636

From"arc@vorsicht-bissig.de" <arc@vorsicht-bissig.de>
Date2011-08-07 03:11 -0700
Message-ID<1bcfe8e4-26c4-485f-99c6-556939b6ded5@glegroupsg2000goo.googlegroups.com>
In reply to#4495
Hey, thanks for your post, I found it interesting, especially as I've got a vaguely similar case on my hands, which I might post in the next day or so. 

i was particularly intrigued by this option: 

On Saturday, 30 July 2011 18:19:33 UTC+12, Julian Fondren  wrote:


> 
>   : later  r> r> 2>r ;
>   : (x>flag) ( cfa x1 -- xt x2 )
>     dup restrict-mask and    if drop -3 else
>     over interpret/compile?  if drop later @ -2 exit else
>     dup immediate-mask and   if drop -1 else
>                                 drop 0 then then then r>drop ;
> 
>   : x>iflag  (x>flag) interpret/compile-int ;
>   : x>cflag  (x>flag) interpret/compile-comp ;
> 

took me a few minutes of thought to work out what LATER is doing, particularly as i momentarily forgot that the first thing on the return stack would be LATER's own context. 

it's sort of like a restricted version of COME FROM, isn't it?  Doesn't this sort of thing introduce the worry that the flow of control becomes difficult to understand? 

 

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


#4641

FromJulian Fondren <ayrnieu@gmail.com>
Date2011-08-07 13:53 -0500
Message-ID<86d3gh3vg2.fsf@gmail.com>
In reply to#4636
"arc@vorsicht-bissig.de" <arc@vorsicht-bissig.de> writes:

> Hey, thanks for your post, I found it interesting, especially as I've got a vaguely similar case on my hands, which I might post in the next day or so. 
>
> i was particularly intrigued by this option: 
>
> On Saturday, 30 July 2011 18:19:33 UTC+12, Julian Fondren  wrote:
>
>
>> 
>>   : later  r> r> 2>r ;
>>   : (x>flag) ( cfa x1 -- xt x2 )
>>     dup restrict-mask and    if drop -3 else
>>     over interpret/compile?  if drop later @ -2 exit else
>>     dup immediate-mask and   if drop -1 else
>>                                 drop 0 then then then r>drop ;
>> 
>>   : x>iflag  (x>flag) interpret/compile-int ;
>>   : x>cflag  (x>flag) interpret/compile-comp ;
>> 
>
> took me a few minutes of thought to work out what LATER is doing, particularly as i momentarily forgot that the first thing on the return stack would be LATER's own context. 
>
> it's sort of like a restricted version of COME FROM, isn't it?

I couldn't say.  I remember thinking these words similar to uses of
call/cc in Scheme.

> Doesn't this sort of thing introduce the worry that the flow of control becomes difficult to understand? 

Sure. This option, and the prior one with the STATE variable, weren't
all that serious.  Although if you were already familiar with LATER you
wouldn't've needed any minutes of thought to work out what it was doing
-- you wouldn't look at LATER itself, but at (X>FLAG) and its callers,
which are... only about as muddled as in the first option.

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


#4496

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2011-07-30 02:14 -0500
Message-ID<sO6dnUuSmOrFMq7TnZ2dnUVZ_u-dnZ2d@supernews.com>
In reply to#4472
m_l_g3 <m_l_g3@yahoo.com> wrote:
> In a message that did not appear in google groups (does it work at
> all? I will see) I wrote:
> 
> 
> \ for Gforth:
> : x>cflag ( cfa x1 -- xt x2 )
>  dup restrict-mask and    if drop -3 else
>  over interpret/compile?  if drop interpret/compile-comp @ -2 else
>  dup immediate-mask and   if drop -1 else
>                              drop 0 then then then
> ;
> : x>iflag ( cfa x1 -- xt x2 )
>  dup restrict-mask and    if drop -3 else
>  over interpret/compile?  if drop interpret/compile-int @ -2 else
>  dup immediate-mask and   if drop -1 else
>                              drop 0 then then then
> ;
> : search-compile ( addr len -- xt flag1 true | addr len false )
>        2dup find-name dup if nip nip (name>x) x>cflag true then
> ;
> : search-interpret ( addr len -- xt flag1 true | addr len false )
>        2dup find-name dup if (name>x) x>iflag dup -3 = if 2drop 0 else 2nip
> true then then
> ;
> 
> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
> 
> The exercise is to propose a better factoring.

But how can anyone do that without knowing what the code is supposed
to be for?  The stack handling is a mess, the names are a mess, and
the whole purpose is obscure.  There's no point refactoring it: better
simply to throw it all away and start again.

Andrew.

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


#4534

FromHugh Aguilar <hughaguilar96@yahoo.com>
Date2011-08-01 21:03 -0700
Message-ID<a151783f-c7d2-463e-abdd-5076cd23c332@h7g2000prf.googlegroups.com>
In reply to#4472
On Jul 28, 1:22 pm, m_l_g3 <m_l...@yahoo.com> wrote:
> In a message that did not appear in google groups (does it work at
> all? I will see) I wrote:
>
> \ for Gforth:
> : x>cflag ( cfa x1 -- xt x2 )
>   dup restrict-mask and    if drop -3 else
>   over interpret/compile?  if drop interpret/compile-comp @ -2 else
>   dup immediate-mask and   if drop -1 else
>                               drop 0 then then then
> ;
> : x>iflag ( cfa x1 -- xt x2 )
>   dup restrict-mask and    if drop -3 else
>   over interpret/compile?  if drop interpret/compile-int @ -2 else
>   dup immediate-mask and   if drop -1 else
>                               drop 0 then then then
> ;
> : search-compile ( addr len -- xt flag1 true | addr len false )
>         2dup find-name dup if nip nip (name>x) x>cflag true then
> ;
> : search-interpret ( addr len -- xt flag1 true | addr len false )
>         2dup find-name dup if (name>x) x>iflag dup -3 = if 2drop 0 else 2nip
> true then then
> ;
>
> Obviously, x>cflag and x>iflag are a copy-paste, which is bad.
>
> The exercise is to propose a better factoring.

You can pass the address of the variable (INTERPRET/COMPILE-INT or
INTERPRET/COMPILE-COMP) in as a parameter. It is also possible to pass
a function xt value in as a parameter, although this technique doesn't
apply to this example in which the only difference is a variable call
rather than a function call.

The above technique results in increased work being done at run-time.
Another technique is to write a function that runs at compile-time and
generates functions that run at run-time. You can use my :NAME to do
this. In your example, the variable address would be passed in to the
meta-function as a parameter and compiled into the generated function
as a literal (use LITERAL to do this). This is more complicated and
would primarily be appropriate for cases in which you are generating a
lot of related functions rather than just two as in your example.

I have abundant examples of both techniques in my novice package:
http://www.forth.org/novice.html

[toc] | [prev] | [standalone]


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


csiph-web