1 ; This is a forth interpreter for x86_64 (elf64)
2 format elf64 executable
5 previous_word = 0 ; Used for chaining the words
9 ;;; ============================================================
11 segment readable executable
13 ;;; This is the very first word
15 ;; FORTH is the last word of WORDLIST FORTH
16 WORD p_forth,'FORTH',dowordlist
18 ;; Change to use this wordlist
22 WORD p_system,'SYSTEM',dowordlist
24 ;; Change to use this wordlist
29 WORD p_wordlists,'WORDLISTS',dowordlist
31 ;; Change to use this wordlist
35 ;;; ========================================
36 ;;; These are the core "execution semantics" words, which are placed
37 ;;; first so as to remain at the same binary address at successive
38 ;;; compilations, which is helful for declaring special debugging gdb
41 ;;; The DO* words are declared as "variables" to provide their
42 ;;; assembled address when used in FORTH.
44 ;;; The register context at entry to an "execution semantcs" code
46 ;;; rax = cfa* of word to execute
47 ;;; rsi = cell* in the calling definition, after calling cell
48 ;;; rsp = data stack pointer
49 ;;; rbp = return stack pointer
52 WORD p_dofasm,'doFASM',dovariable
53 ;; Execution semantics for assembly words.
58 WORD p_doforth,'doFORTH',dovariable ;
59 ;; Execution semantics for FORTH defition word.
62 lea rsi, [rax+8] ; rsi = the DFA of the rax word
65 WORD p_dodoes,'doDOES',dovariable
66 ;; Execution semantics for DOES>
67 ;; [cfa-8] holds the adjustment offset ("does offset")
70 lea rsi, [rax+8] ; rsi = the DFA of the rax word
71 add rsi,qword [rax-8] ; adjust rsi by the "does offset'
74 WORD p_dovariable,'doVARIABLE',dovariable
75 ;; Execution semantics for a variable ( -- addr )
76 ;; rax points to CFA field
78 lea rax, [rax+8] ; rsi = the DFA of the rax word
82 WORD p_dovalue,'doVALUE',dovariable
83 ;; Execution semantics for a value constant ( -- v )
84 ;; rax points to CFA field
86 lea rax, [rax+8] ; rsi = the DFA of the rax word
90 WORD p_dostring,'doSTRING',dovariable
91 ;; Execution semantics for a string constant ( -- addr n )
92 ;; rax points to CFA field
94 lea rax, [rax+8] ; rsi = the DFA of the rax word
98 WORD p_dowordlist,'doWORDLIST',dovariable
99 ;; Execution semantics for DOES>
100 ;; [cfa-8] holds the adjustment offset ("does offset")
103 lea rsi, [rax+8] ; rsi = the DFA of the rax word
104 add rsi,qword [rax-8] ; adjust rsi by the "does offset'
108 include 'syscalls.asm'
110 ;;; ========================================
111 ;;; The stacks are placed here.
113 segment readable writable
115 WORD return_stack,'RETURN-STACK',dovariable
118 rb 1048576 ; 1 Mb return stack
119 RS_TOP: ; The initial rbp
122 WORD data_stack,'DATA-STACK',dovariable
125 rb 1048576 ; 1 Mb data stack
126 DS_TOP: ; The initial rsp
128 ;;; ========================================
129 ;;; Core execution control words
131 segment readable executable
133 ;;; At fasm compilation: reset previous_word to make a new word list
134 ;;; Words above belong to the SYSTEM wordlist, and the following
135 ;;; belong to the FORTH wordlist.
136 previous_word = last_wordlists_word
138 WORD inline_code,'[ASM]',fasm
140 ;; This transitions execution into inline assembler in the
141 ;; calling word defintion. Note that it stops advancing rsi;
142 ;; code should use FORTH macro to reenter forth execution, or
143 ;; exit to the calling definition via "jmp exit".
146 WORD p_execute,'EXECUTE',fasm
151 jmp qword [rax] ; goto code of that FORTH word (64 bit jump)
153 WORD p_exit, 'EXIT',fasm
154 ;; ( -- ) ( R: addr -- )
155 ;; Returns execution to the calling definition as per the
161 ;; TERMINATE0 terminates the program with code 0
163 WORD p_terminate, 'TERMINATE0',fasm
169 WORD p_branch,'BRANCH',fasm
171 ;; Using subsequent inline cell as branch offset, branch
177 WORD p_zero_branch,'0BRANCH',fasm
179 ;; Using subsequent inline cell as branch offset, branch
180 ;; accordingly if the stacked value is zero, otherwise just
181 ;; skip over the branch offset
184 jne p_zero_branch_SKIP
190 ;;; ========================================
191 ;;; Core extension(s)
193 segment readable writable executable
195 include 'wordlists.asm'
201 include 'compile.asm'
203 WORD p_program_version,'PROGRAM_VERSION',dostring
204 STRING 'RRQ Forth version 0.1 - 2021-05-13',10
206 WORD p_stdin,'STDIN',dovalue
207 ;; Initialised to hold a STREAM for fd 0
210 ;;; The main entry point.
211 ;;; This word is also the last word before syscalls
213 WORD p_quit,'QUIT',fasm
214 ;; QUIT is the program entry point ********************
218 cmp qword [p_stdin_DFA],0
219 jne p_quit_INITIALIZED
224 pop qword [p_stdin_DFA] ; Assign STDIN
235 BRANCH 0,p_quit_ERROR
240 STRING 10,'*** Unknown word: '
249 mov rbp,RS_TOP ; reset the return stack
252 ;;; ========================================
254 segment readable writable
257 rb 1048576 ; +1 Mb heap
258 rb 1048576 ; +1 Mb heap
259 rb 1048576 ; +1 Mb heap
260 rb 1048576 ; +1 Mb heap
261 rb 1048576 ; +1 Mb heap