Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #4472 > unrolled thread
| Started by | m_l_g3 <m_l_g3@yahoo.com> |
|---|---|
| First post | 2011-07-28 12:22 -0700 |
| Last post | 2011-08-01 21:03 -0700 |
| Articles | 12 — 7 participants |
Back to article view | Back to comp.lang.forth
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
| From | m_l_g3 <m_l_g3@yahoo.com> |
|---|---|
| Date | 2011-07-28 12:22 -0700 |
| Subject | factoring 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]
| From | Hugh Aguilar <hughaguilar96@yahoo.com> |
|---|---|
| Date | 2011-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]
| From | mlg3 <m_l_g3@yahoo.com> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | mlg3 <m_l_g3@yahoo.com> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | arc <arc@vorsicht-bissig.de> |
|---|---|
| Date | 2011-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]
| From | "arc@vorsicht-bissig.de" <arc@vorsicht-bissig.de> |
|---|---|
| Date | 2011-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]
| From | Julian Fondren <ayrnieu@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2011-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]
| From | Hugh Aguilar <hughaguilar96@yahoo.com> |
|---|---|
| Date | 2011-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