Path: utzoo!attcan!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma From: toma@tekgvs.LABS.TEK.COM (Tom Almy) Newsgroups: comp.lang.forth Subject: Re: Forth Implementation Question Message-ID: <5980@tekgvs.LABS.TEK.COM> Date: 22 Sep 89 15:46:29 GMT References: <1715@thumper.bellcore.com> <7972@medusa.cs.purdue.edu> <7990@medusa.cs.purdue.edu> <427@midian.UUCP> Reply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy) Organization: Tektronix, Inc., Beaverton, OR. Lines: 54 Arrgh! I've read enough. It's not *that* difficult to implement a Forth with dynamic memory management. I've played around with it. You just have to use "token threading". The "compilation addresses" that are compiled into a colon definition are actually indices into a table of real compilation addresses. When the body of a colon definition gets moved, all that is necessary is to revise the address in the table. The only other important issues: 1) code words must use position independent code so they can be relocated or else the garbage collector must know they are immovable. 2) colon definitions must also be relocatable (the branch functions must use relative addressing). While the dictionary organization allows shadowing of definitions (a luxury not available in other languages, typically), I wrote a REDEFINE word that would replace the earlier definition with a new one. This allows fixing definitions without having to recompile any of the following words in the dictionary (a big plus). While I never concerned myself with a selective FORGET, it wouldn't be that difficult to safely implement. I propose two schemes: 1) (Name field, the header, is atached somehow to the definition body) -- Replace pointer in token table with pointer to word called *DELETED* defined: : *DELETED* ABORT" Attempt to execute deleted function" ; If FOO uses BAR (: FOO BAR 10 + ; for example) and BAR is forgotten, the if FOO is decompiled, it will look like : FOO *DELETED* 10 + ; and will cause an error if executed. 2) A somewhat friendlier implementation would use second token table pointing to the name field. FORGET would replace the body with one that does the abort, but decompiling would yield the original definition of FOO, and the "error" definition of BAR. A later re-definition of BAR, using REDEFINE, would allow FOO to work again. The garbage collector would mark unused tokens and delete the name fields (and bodies) of any tokens that were not used and had "error" bodies. (Note that just deleting unused tokens would not work because the system would start going away as top level words started going away!). As a heretic remark, anyone that is really interested in a dynamic Forth (with all its attendant bloating and sluggishness) should look at LISP or, better yet Smalltalk. I spent a year on a Smalltalk implementation, and the guts of Smalltalk bear a suprising resemblence to Forth + dynamic memory management. Get a copy of "Smalltalk-80 The Language and Its Implementation", by Adele Goldberg and David Robson, and plow your way through Part Four. Lots of it looks like a direct steal from Forth! Of course the Smalltalk language is a lot different, but it compiles into token threaded code for a stack machine! A hot Forth/Smalltalk programmer could easily add a Forth like compiler to the environment and run Forth programs. Tom Almy toma@tekgvs.labs.tek.com Standard Disclaimers Apply