Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site utah-cs.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!utah-cs!carr From: carr@utah-cs.UUCP (Harold Carr) Newsgroups: net.lang.forth Subject: CREATEDate: Fri, 12-Oct-84 14:10:42 EDT Article-I.D.: utah-cs.3068 Posted: Fri Oct 12 14:10:42 1984 Date-Received: Sat, 13-Oct-84 06:44:13 EDT Organization: Univ of Utah CS Dept Lines: 106 Could someone enlighten me on why one would use CREATE ... DOES> in some instances and in others? Also, I am very interested in Forth's meta-defining words and would appreciate examples of interesting and powerful ways of using them. Here are a couple of examples of using ( index -- ) ( DOES> alters the code field and first parameter of ) ( word defined by . When the DOES> part executes ) ( it begins with the address of the first parameter of ) ( the new word on the stack. ) swap 2* 2* + @ execute ; ( Execute the function in the indexed slot. ) is run. In this case, the code allocates space in the new word for a vector initialized to zeros. The DOES> part defines the run-time words for the newly created word. When the new word is run its parameter field address is pushed on Forth's parameter stack (the user has already pushed an index before it). The parameter address is the base of the vector. It swaps these two items, leaving the index on top, which is then multiplied by four to create a thirty-two bit word index. This index is then added to the base. The @ operator gets the contents of the indexed slot and leaves it on the stack. The contents should be the address of another executable word. Execute simply executes the word whose address is on the top of the stack. By defining the following auxilary words (shown without comment): : put [compile] ' ; : offset-in 2* 2* [compile] ' + ! ; We can create a key-stroke dispatch table: 26 xeq-array control-keys ... put backward 2 offset-in control-keys put forward 6 offset-in control-keys put next 14 offset-in control-keys put previous 21 offset-in control-keys ... This creates an execution array for control keys. Then we install the functions associated with each key. Note, that by using the execution array rather than a case statement, we can dynamically redefine the keys. To run any of the functions in the array we simply do: 14 control-keys Control-keys takes its index from the stack, fetches the function and executes it. A simple loop will now listen to the keyboard: : keys begin key dup 27 <= if control-keys else regular-keys then again ; A second example (sent to me by Mitch Bradley) uses CREATE to create an automatically indexed byte array: : carray ( array-size --name) create ( Create a dictionary entry for the next word in the input stream, without allocating any parameter field memory. ) allot ( Add array-size bytes to the parameter field of the most recently defined word. ) does> ( index -- byte-address ) ( Marks the termination of the defining part of a high-level defining word and begins the definition of the run-time actions. On execution of words defined with CARRAY, the sequence of words between DOES> and ; will be executed, with the address of the word's parameter field on the stack. ) + ; ( Add index to base. ) I am still not sure why one would use CREATE rather than DOES> here. I'll be waiting to hear from you. Forth programmers remind me of Lisp hackers: fearless, creative and free - The environment is so open and powerful (no secret black boxes called compilers), we just can't wait to get our hands on it an change it! Harold Carr arpa: CARR@UTAH-20 uucp: harpo!utah-cs!carr