Special Feature: ColorForth Commentary
COLOR.ASM: Dictionary
NOTICE: This is a work in progress. Parts of my commentary are still very rough. However, I have it up on the web because even in this rough form it may be useful to ColorForth enthusiasts. Expect the contents of these files to change frequently.
Adding temporary definitions
mark: ;Set beginning of definitions that will be removed by empty. ;[Refs: forth2] mov ecx, macros ; Save # words in MACRO wordlist. mov mk, ecx mov ecx, forths ; Save # words in FORTH wordlist. mov mk+4, ecx mov ecx, h ; Save end-of-dictionary pointer. mov mk+2*4, ecx ret empty: ;"empt" ;[Refs: forth2] mov ecx, mk+2*4 ; Restore end-of-dictionary pointer. mov h, ecx mov ecx, mk+4 ; Restore # words in FORTH wordlist. mov forths, ecx mov ecx, mk ; Restore # words in MACRO wordlist. mov macros, ecx mov class, 0 ; (?) ret
Finding words
These routines return with ECX = offset into wordlist to word if zero flag set(?) -- [note how instructions affect zero flag]
mfind: ;Look up word in MACRO wordlist. ;[Refs: qcompile, compile] mov ecx, macros push edi lea edi, [macro0-4+ecx*4] jmp @f find: ;Look up word in FORTH wordlist. ;[Refs: ex1, ex2, qcompile] mov ecx, forths push edi lea edi, [forth0-4+ecx*4] @@: std repne scasd cld pop edi ret
Executing words
ex1: ;[Refs: ex1, aword, eout] dec words ; from keyboard jz @f drop jmp ex1 @@: call find jnz abort1 drop jmp [forth2+ecx*4] execute: ;Used by inter to handle yellow (color=1, execute) words. ;[Refs: spaces] mov lit, offset alit dup_ mov eax, [-4+edi*4] ; Grab the next pre-parsed word. ex2: ;[Refs: none] and eax, -20o ; Mask out color bits (bits 0..3). call find ; Look up word in FORTH wordlist. jnz abort ; If not found, abort. drop jmp [forth2+ecx*4] ; Run the word's definition.
Canceling execution
abort: ;[Refs: ex2, qcompile (qring, insert1) ] mov curs, edi shr edi, 10-2 mov blk, edi abort1: ;[Refs: ex1, copy] mov esp, gods ; [RST] mov spaces+3*4, offset forthd mov spaces+4*4, offset qcompile mov spaces+5*4, offset cnum mov spaces+6*4, offset cshort mov eax, 57o ; ? ; (57o = value for '?' in encoding scheme) call echo_ jmp accept
Adding words to the dictionary
ColorForth offers two routines to add a word to the dictionary — one routine for each wordlist. The address of the routine to use is stored in adefine, the word-definition vector. Macro_ uses sdefine to store the address of macrod into this vector, while forth uses sdefine to store the address of forthd.
Sdefine takes the address of a word-definition routine, but it takes the address off the return stack. This allows the caller to pass the address simply by calling sdefine (as long as the address is intended to be the address of the instruction following the call). This leads to simpler code than would be required to pass an address on the data stack. Of course this means that (1) the code after the call is not run when sdefine returns, and (2) sdefine returns not to its caller but to its caller's caller.
sdefine: ;Sets word-definition vector. Called when current wordlist changes. ;[Refs: macro_, forth] pop adefine ; [RST] ret macro_: ;"macro" ;Points word-definition vector at macrod. ;[Refs: adefine, forth2] call sdefine ; Does NOT fall through to macrod. macrod: ;Defines new word and adds it to the MACRO wordlist. ;Used by inter to handle red (color=3, define) words ; (if the current wordlist is MACRO). ;[Refs: variable (adefine)] mov ecx, macros inc macros lea ecx, [macro0+ecx*4] jmp @f forth: ;Points word-definition vector at forthd. ;[Refs: forth2] call sdefine ; Does NOT fall through to forthd. forthd: ;Defines new word and adds it to the FORTH wordlist. ;Used by inter to handle red (color=3, define) words ; (if the current wordlist is FORTH). ;[Refs: abort1, variable] mov ecx, forths ; Increment number of words in the inc forths ; FORTH wordlist. lea ecx, [forth0+ecx*4] ; Make offset into FORTH word array. @@: mov edx, [-4+edi*4] ; Grab pre-parsed word. and edx, -20o ; Clear color bits (bits 0..3). mov [ecx], edx ; Store result at end of word array. mov edx, h ; Store end-of-dictionary pointer mov [forth2-forth0+ecx], edx ; into wordlist's address array. lea edx, [forth2-forth0+ecx] ; Get address of address-array cell. shr edx, 2 ; Convert it into DWORD address. mov last, edx ; Store it (to allow optimization). mov list, esp ; -- ???? -- mov lit, offset adup ; -- ???? -- test class, -1 ; Call custom routine only if jz @f ; vector is non-zero. jmp [class] @@: ret ; Otherwise simply return. ;;;;;;;;;;;;;;;;;;NOTE--TEMP ; ECX = byte pointer to word within word array. ; EDX = DWORD pointer to addr within addr array. ;;;;;;;;;;;;;;;;;;NOTE--TEMP
Check the index for other entries.