;;; 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_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 jle 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',fasm ;; ( chars* length -- [ chars* length 0 ]|[ tfa ] ) ;; Search the current wordlists for the given pname pushr rsi mov rcx,[p_wordlist_DFA] mov rcx,qword [rcx] ; use rcx for word list traversing mov rbx,qword [rsp] ; rbx is input length mov rsi,qword [rsp+8] ; rsi is input chars* p_find_loop: cmp rcx,0 je p_find_notfound ; jump at end of word list cmp rbx,qword [rcx+24] ; compare lengths jne p_find_nextword ; jump on length mismatch push rcx ; save tfa for later ;; check word push rsi ; input chars tfa2pname rcx push rcx ; word pname push rbx ; length DOFORTH p_strncmp ; ( s1* s2 n -- v ) pop rax ; return value v pop rcx ; restore tfa cmp rax,0 je p_find_found mov rbx,qword [rsp] mov rsi,qword [rsp+8] p_find_nextword: mov rcx,qword [rcx] jmp p_find_loop p_find_notfound: xor rcx,rcx sub rsp,16 p_find_found: add rsp,8 mov qword [rsp],rcx ; replace with tfa / 0 popr rsi next