: random-package ;
VARIABLE randval
: init-rand ( seed -- )
randval ! ;
: rand ( range -- rand# )
randval @ 21709 + 15273 * randval !
mod ;
HIDE randval
(No flames on the "randomness" of this random package, please :-)
HIDE is a word which, like tic ('), searches the dictionary for the
target word. HIDE also keeps a trailing pointer to the previous
word in the dictionary. When it finds the target word in the dictionary,
it takes it out of the dictionary search path by changing the previous
word's next pointer to point to the word following the target word.
This allows a VARIABLE or procedure word to be used normally in a
"package" and then be hidden from subsequent definitions.
a) Is this a useful construct, or is it the attempt of an
admittedly neophyte forth programmer (me) to force
other language ideas onto forth?
b) Can HIDE be written in forth, or must it be written in
assembly language?
c) Is there another (easier) way to do this that I am not
aware of?
Tim Olson
Advanced Micro Devices
ihnp4!amdcad!tim
no.6: "What do you want?"
no.2: "Information."
no.6: "You won't get it!"
--John J Wavrik
Math Dept - UCSD
..ucbvax!sdcsvax!sdcc3!ma168x
I think an easier way of doing this is to use the sequence
' WORD-TO-HIDE NFA HEX 20 TOGGLE
This will set the 'smudge' bit in the word's name length field and hide it
quite nicely. It also doesn't require you to address into the header which
is prohibited in the Forth '79 standard.
Another way of doing this is by putting the 'local' word in a vocabulary
used by the package you are building. Then it will be visible anytime you
want it and invisible when you don't want it. My assembler uses words like
[ and ] for addressing modes. These are normal Forth words as well. When
I am using the assembler, I set the context to ASSEMBLER and the assembler
definitions for these words become visible. When I end a CODE definition,
I set the context back to FORTH and the normal definitions become visible.
--
...smeagol\ Steve Schlaifer
......wlbr->!jplgodo!steve Advance Projects Group, Jet Propulsion Labs
....logico/ 4800 Oak Grove Drive, M/S 156/204
Pasadena, California, 91109
+1 818 354 3171
> c) Is there another (easier) way to do this that I am not
> aware of?
If you have '83, you might wish to look at the finer points of
vocabulary and context words. It is possible to create "statics"
this way. This feature is often under-used, but useful.
Yes, i think this is a useful construct. It'd be nice too, if it
would "collapse" the now-useless word header to regain some dictionary
space. Of course, it would also have to relocate everything defined after
the target word. Could be tricky!
> b) Can HIDE be written in forth, or must it be written in
> assembly language?
I haven't played with FORTH in a long time, but i'm fairly certain that
it could be used to implement HIDE.
> c) Is there another (easier) way to do this that I am not
> aware of?
You could also corrupt the name field (e.g. blank fill it) to make the
word lexically unrecognizable. I think the pointer-shifting scheme is better
though, as it removes the word from the search stream altogether.
--
Pete Yadlowsky University of Virginia, Academic Computing Center
UUCP: decvax!mcnc!ncsu!uvacs!pmy
CSNET: pmy@virginia
"If ya can't stand the heat ... it's too hot!"
I believe map-Forth (Michael A Perry's version for my old CompuPro 68000)
included the words:
INTERNAL
<<boring and/or dangerous words to be hidden here>>
EXTERNAL
<<the visible stuff>>
MODULE (actually does the work)
I recall that both INTERNAL and EXTERNAL merely left addresses on the
data stack, and that MODULE patched the vocabulary search chain to
miss the internals. Woe be unto him whose internal or external definitions
which (on purpose or not) swallowed any of the data stack or left any extra!
Other than this caveat, I thought the idea and the implementation were
really first-class -- only a tiny bit of code.
As a side note, compressing the headers might not always be a good
idea, since the same Forth package had a tracer (hooked into NEXT) that
printed out the names of the currently executing words and the top few
values on the stack. I had a few words with headers missing that always
screwed up the trace output.
--
+----------------+
! II CCCCCC ! Jim Cathey
! II SSSSCC ! ISC Systems Corp.
! II CC ! Spokane, WA
! IISSSS CC ! UUCP: ihnp4!tektronix!reed!iscuva!jimc
! II CCCCCC ! (509)927-5757
+----------------+
"With excitement like this, who is needing enemas?"
Which caused me to define these as so:
: INTERNAL LATEST 12543 ;
: EXTERNAL 12543 <> ABORT" Where is INTERNAL?"
LATEST N>LINK
25314 ;
: MODULE 25314 <> ABORT" Where is EXTERNAL?"
! ;
(This code will not work for Laxen & Perry F83 because of the hashed
vocabularies)
My current favorite technique (because it allows referencing the hidden words)
is a function which moves a word into a different vocabulary.
FooVoc DEFINITIONS BarVoc REVOC FooBar
moves word FooBar from vocabulary BarVoc to vocabulary FooVoc.
The implementation is straightforward, but is very system dependent.
Tom Almy
Tektronix
There are actually two different techniques that can be used.
>> a) Is this a useful construct, or is it the attempt of an
>> admittedly neophyte forth programmer (me) to force
>> other language ideas onto forth?
>Yes, i think this is a useful construct.
So useful in fact, that it has already been done as a part of the language.
>> b) Can HIDE be written in forth, or must it be written in
>> assembly language?
>I haven't played with FORTH in a long time, but i'm fairly certain that
>it could be used to implement HIDE.
As I said, there are two ways to do this. The easiest is to use "Smudge".
>> c) Is there another (easier) way to do this that I am not
>> aware of?
>
>You could also corrupt the name field (e.g. blank fill it) to make the
>word lexically unrecognizable. I think the pointer-shifting scheme is better
>though, as it removes the word from the search stream altogether.
This is almost exactly what "smudge" does. The MSB of the first byte in the
name field can be used to fool ' (tick) into missing the definition, subsequent
smudges to an already existing definition toggle the bit.
An extension of the "smudge" is the "vocabulary" or "context" word. In these
cases, the NFA can be use to remove/enable an entire group of words from
the the vocabulary. For example, when you use the "editor" word, the
editor vocabulary "overrides" the forth definitions of the same name.
If you want the original forth definitions, just type "forth", and you
are back to the basic vocabulary. Your forth documentation should give
more explanation of VOCABULARY, CONTEXT, CURRENT, and DEFINITIONS.
Another use of the "smudge" technique is to hide old definitions. This
is useful in our case because we use overlays, but it may also be useful
if you have many source files that are mixed and matched to make long
programs. For example:
: TODAY original definition ;
( lots of code, several source files, overlays, branch vocabularies, etc.)
: TODAY new definition, may include the existing TODAY ;
LOCAL TODAY LOCAL TODAY ( smudges both versions)
GLOBAL TODAY ( unsmudges only the later version)
Now if I'm in the wrong vocabulary and type TODAY, I'll get an error
message rather than the old version.
It should be very easy to write LOCAL in Forth, e.g.
: LOCAL ', 4 - DUP @ BITMASK @ OR SWAP ! ;
where 4 should be replaced by the difference (in your implementation)
between the address
returned by ', and the word you want to smudge and BITMASK is a variable
containing the smudge bit pattern. GLOBAL is much harder to write unless
you have access to the more primitive words used by ' or [']. (Send
e-mail if you want to know how we do it.) I hope this is helpful.
--
-------------------------------------------------------------------------
Steve Willner Phone 617-495-7123 Bitnet: willner@cfa1
60 Garden St. FTS: 830-7123 UUCP: willner@cfa
Cambridge, MA 02138 USA Telex: 921428 satellite cam