1 format ELF64 executable
3 ;; The code in this macro is placed at the end of each Forth word. When we are
4 ;; executing a definition, this code is what causes execution to resume at the
5 ;; next word in that definition.
7 ;; RSI points to the address of the definition of the next word to execute.
8 lodsq ; Load value at RSI into RAX and increment RSI
9 ;; Now RAX contains the location of the next word to execute. The first 8
10 ;; bytes of this word is the address of the codeword, which is what we want
12 jmp qword [rax] ; Jump to the codeword of the current word
15 ;; pushr and popr work on the return stack, whose location is stored in the
26 segment readable executable
29 cld ; Clear direction flag so LODSQ does the right thing.
30 mov rbp, return_stack_top ; Initialize return stack
37 ;; The codeword is the code that will be executed at the beginning of a forth
38 ;; word. It needs to save the old RSI and update it to point to the next word to
41 pushr rsi ; Save old value of RSI on return stack; we will continue execution there after we are done executing this word
42 lea rsi, [rax + 8] ; RAX currently points to the address of the codeword, so we want to continue at RAX+8
43 next ; Execute word pointed to by RSI
45 ;; This word is called at the end of a Forth definition. It just needs to
46 ;; restore the old value of RSI (saved by 'docol') and resume execution.
53 ;; LIT is a special word that reads the next "word pointer" and causes it to be
54 ;; placed on the stack rather than executed.
83 ;; Read a word from standard input and push it onto the stack as a pointer and a
84 ;; size. The pointer is valid until the next call to READ_WORD.
92 ;; Read characters into .char_buffer until one of them is not whitespace.
99 cmp [.char_buffer], ' '
101 cmp [.char_buffer], $A
105 ;; We got a character that wasn't whitespace. Now read the actual word.
109 mov al, [.char_buffer]
118 mov rsi, .char_buffer
122 cmp [.char_buffer], ' '
124 cmp [.char_buffer], $A
166 push you_typed_string
167 push you_typed_string.length
192 dq LIT, you_typed_string
193 dq LIT, you_typed_string.length
200 segment readable writable
202 you_typed_string db 'You typed: '
203 .length = $ - you_typed_string
207 READ_WORD.max_size = $FF
208 READ_WORD.buffer rb READ_WORD.max_size
209 READ_WORD.length db ?
210 READ_WORD.char_buffer db ?