tim@amdcad.UUCP (Tim Olson) (06/25/86)
I have been recently thinking of a way to implement something like the 'C' static scoping type in forth. This would allow a word or group of words to use a VARIABLE without letting the VARIABLE be visible outside the group; something like: : 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!"
ma168a@sdcc3.UUCP (John Wavrik) (06/26/86)
In article <12110@amdcad.UUCP>, tim@amdcad.UUCP (Tim Olson) writes: > I have been recently thinking of a way to implement something like the > 'C' static scoping type in forth. This would allow a word or group of > words to use a VARIABLE without letting the VARIABLE be visible outside > the group; > > c) Is there another (easier) way to do this that I am not > aware of? When a name is re-used in Forth, the earlier definition remains in the dictionary and is automatically used by all words compiled when it was active. You can have many variables named X -- and all will be, in effect local. The problem comes if you would later like to refer to a variable (or other object) that has been "covered". One way to do this (absolutely against standards!) is to define a word ZAP which locates the name field of a word and changes the length byte to zero (make sure to preserve the higher bits if necessary); or the first character of the name to ascii 0; or in any other way destroys the name field so that the word will not be found in a dictionary search [the best change is system dependent]. Vocabularies can also be used to equip sub-applications with special names without destroying access to previous words with the same name. Some Forth systems (e.g. MMS-Forth) provide for a temporary dictionary area used only during compilation. Words can have their name fields in the temporary area. This creates local words -- with a saving of space in the main dictionary (local words have no headers and are not linked into the dictionary when the temporary area is deleted - but their body is left in the dictionary). There have been some experiments in Forth syntax in which stack manipulation is eliminated by making all arguments to a word into named local variables (whose scope is just the word being defined). See Dr. Dobbs journal of a few years ago. --John J Wavrik Math Dept - UCSD ..ucbvax!sdcsvax!sdcc3!ma168x
steve@jplgodo.UUCP (06/26/86)
In article <12110@amdcad.UUCP>, tim@amdcad.UUCP (Tim Olson) writes: > [ summary: a way of hiding a word to make its scope local is to fiddle > with the link pointers and remove it from the dictionary chain] 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
rb@cci632.UUCP (Rex Ballard) (07/02/86)
In article <12110@amdcad.UUCP> tim@amdcad.UUCP (Tim Olson) writes: >I have been recently thinking of a way to implement something like the >'C' static scoping type in forth. This would allow a word or group of >words to use a VARIABLE without letting the VARIABLE be visible outside >the group; > 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.
pmy@uvacs.UUCP (07/07/86)
> I have been recently thinking of a way to implement something like the > 'C' static scoping type in forth. This would allow a word or group of > words to use a VARIABLE without letting the VARIABLE be visible outside > the group; something like: > > : 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? 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!"
jimc@iscuva.UUCP (07/15/86)
> I have been recently thinking of a way to implement something like the > 'C' static scoping type in forth. This would allow a word or group of > words to use a VARIABLE without letting the VARIABLE be visible outside > the group; something like: 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?"
toma@tekgvs.UUCP (Thomas Almy) (07/16/86)
In article <242@iscuva.UUCP> jimc@iscuva.UUCP (Jim Cathey) writes: >> I have been recently thinking of a way to implement something like the >> 'C' static scoping type in forth. This would allow a word or group of >> words to use a VARIABLE without letting the VARIABLE be visible outside >> the group; something like: > >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! 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
rb@cci632.UUCP (Rex Ballard) (07/21/86)
In article <622@uvacs.UUCP> pmy@uvacs.UUCP writes: >> I have been recently thinking of a way to implement something like the >> 'C' static scoping type in forth. This would allow a word or group of >> words to use a VARIABLE without letting the VARIABLE be visible outside >> the group; something like: >> >> HIDE randval >> >> 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. 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.