;;; This file contains words dealing with word lists (vocabularies) ;;; ;;; CURRENT-WORDLIST (variable) points out "the current wordlist" ;;; SYSCALLS is a wordl list ;;; FORTH is a word list ;;; ;;; !! When a word list word is created, it gets added to the tail end ;;; of the current word list as way of making all word list words be ;;; present in all word lists. This is different to all other kinds of ;;; words, which instead are added to the head end of the current word ;;; list. ;;; ;;; !! A word list word is created, it is initialised to the head end ;;; of the current word list. It will this be an extension to that ;;; current word list. ;;; ;;; EMPTY-WORDLIST is a word list word for an empty word list. It thus ;;; only contains word list words. ;;; ;;; WORDLIST ( "name" -- ) = start WORD p_tfa2cfa,'TFA>CFA',fasm ;; ( tfa -- cfa ) ;; Advance a word tfa pointer to the cfa field mov rax,qword[rsp] tfa2cfa rax mov qword [rsp],rax next WORD p_tfa2dfa,'TFA>DFA',fasm ;; ( tfa -- dfa ) ;; Advance a word tfa pointer to the dfa field mov rax,qword[rsp] tfa2dfa rax mov qword [rsp],rax next WORD p_dfa2tfa,'DFA>TFA',fasm ;; ( dfa -- tfa ) ;; Advance a word tfa pointer to the dfa field mov rax,qword[rsp] mov rax,qword [rax-24] ; tfa mov qword [rsp],rax next WORD p_wordlist,'CURRENT-WORDLIST',dovariable ;; CURRENT-WORDLIST points to cfa of the currently active wordlist. dq p_forth_DFA WORD p_words,'WORDS',fasm ;; ( -- ) ;; Dump all words pushr rsi mov rax,qword [p_wordlist_DFA] ; current wordlist word mov rax,[rax] ; list start sub rsp,8 ; use stack to hold ptr p_words_LOOP: mov qword [rsp],rax cmp rax,0 je p_words_END ;; tfa>pfa tfa2pfa rax push 1 ;; pfa@ => ( chars* length) pushpname rax DOFORTH sys_write pop rax ; ignore errors push qword 10 DOFORTH p_emit mov rax,qword [rsp] mov rax,qword [rax] jmp p_words_LOOP p_words_END: popr rsi next WORD p_strncmp,'STRNCMP',fasm ;; ( chars1 chars2 n -- flag ) ;; Compare bytes until one is NUL, return <0, =0 or >0 to ;; indicate that chars1 is lesser, they are equal, or chars2 ;; is lesser in ascii ordering respectively. pop rdx pop rbx pop rax xor rcx,rcx ;; rax = chars1, rbx = chars2, cl = byte acc, rdx = length inc rdx p_strncmp_loop: dec rdx je p_strncmp_end mov cl,[rax] inc rax sub cl,[rbx] inc rbx je p_strncmp_loop p_strncmp_end: push rcx next WORD p_find,'FIND' ;; ( chars length -- [ chars 0 | cfa 1 ) ;; Search the current wordlists for the given pname pushr rsi mov rcx,[p_wordlist_DFA] mov rcx,qword [rcx] mov rbx,[rsp] mov rax,[rsp+8] p_find_loop: cmp rcx,0 je p_find_done cmp rbx,qword [rcx+16] ; compare lengths jne p_find_nextword push rcx ;; check word push rax tfa2pname rcx push rcx push rbx DOFORTH p_strncmp pop rax ; return value pop rcx cmp rax,0 je p_find_done mov rbx,[rsp] mov rax,[rsp+8] p_find_nextword: mov rcx,[rcx] jmp p_find_loop p_find_found: mov qword [rsp+8],rcx ; replace chars with tfa mov rcx,1 p_find_done: push rcx popr rsi next