1 ; This is a forth interpreter for x86_64 (elf64)
2 format elf64 executable
7 ;;; ============================================================
9 segment readable writable executable
11 ;;; ========================================
12 ;;; These are the core "execution semantics" words, which are placed
13 ;;; first so as to remain at the same binary address at successive
14 ;;; compilations, which is helful for declaring special debugging gdb
17 ;;; The DO* words are declared as "variables" to provide their
18 ;;; assembled address when used in FORTH.
20 ;;; The register context at entry to an "execution semantcs" code
22 ;;; rax = cfa* of word to execute
23 ;;; rsi = cell* in the calling definition, after calling cell
24 ;;; rsp = data stack pointer
25 ;;; rbp = return stack pointer
28 previous_word = 0 ; Used for chaining the words
30 WORD p_dofasm,'doFASM',dovariable
31 ;; Execution semantics for assembly words.
36 WORD p_doforth,'doFORTH',dovariable ;
37 ;; Execution semantics for FORTH defition word.
40 lea rsi, [rax+8] ; rsi = the DFA of the rax word
43 WORD p_dodoes,'doDOES',dovariable
44 ;; Execution semantics for DOES>
45 ;; [cfa-8] holds the adjustment offset ("does offset")
48 lea rsi, [rax+8] ; rsi = the DFA of the rax word
49 add rsi,qword [rax-8] ; adjust rsi by the "does offset'
52 WORD p_dovariable,'doVARIABLE',dovariable
53 ;; Execution semantics for a variable ( -- addr )
54 ;; rax points to CFA field
56 lea rax, [rax+8] ; rsi = the DFA of the rax word
60 WORD p_dovalue,'doVALUE',dovariable
61 ;; Execution semantics for a value constant ( -- v )
62 ;; rax points to CFA field
64 lea rax, [rax+8] ; rsi = the DFA of the rax word
68 WORD p_dostring,'doSTRING',dovariable
69 ;; Execution semantics for a string constant ( -- addr n )
70 ;; rax points to CFA field
72 lea rax, [rax+8] ; rsi = the DFA of the rax word
76 include 'syscalls.asm'
78 ;;; ========================================
79 ;;; The stacks are placed here.
81 ;segment readable writable
83 WORD return_stack,'RETURN-STACK',dovariable
86 rb 1048576 ; 1 Mb return stack
87 RS_TOP: ; The initial rbp
90 WORD data_stack,'DATA-STACK',dovariable
93 rb 1048576 ; 1 Mb data stack
94 DS_TOP: ; The initial rsp
97 ;;; ========================================
98 ;;; Core execution control words
100 ;segment readable executable
102 ;;; At fasm compilation: reset previous_word to make a new word list
103 ;;; Words above belong to the SYSTEM wordlist, and the following
104 ;;; belong to the FORTH wordlist.
107 WORD p_system,'SYSTEM',dovariable
109 ;; The SYSTEM word list
110 dq last_system_word ; tfa of last SYSTEM word
111 dq p_forth_DFA ; dfa of successor word list
113 WORD inline_code,'[ASM]',fasm
115 ;; This transitions execution into inline assembler in the
116 ;; calling word defintion. Note that it stops advancing rsi;
117 ;; code should use FORTH macro to reenter forth execution, or
118 ;; exit to the calling definition via "jmp exit".
121 WORD p_execute,'EXECUTE',fasm
126 jmp qword [rax] ; goto code of that FORTH word (64 bit jump)
128 WORD p_exit, 'EXIT',fasm
129 ;; ( -- ) ( R: addr -- )
130 ;; Returns execution to the calling definition as per the
136 ;; TERMINATE0 terminates the program with code 0
138 WORD p_terminate, 'TERMINATE0',fasm
144 WORD p_branch,'BRANCH',fasm
146 ;; Using subsequent inline cell as branch offset, branch
152 WORD p_zero_branch,'0BRANCH',fasm
154 ;; Using subsequent inline cell as branch offset, branch
155 ;; accordingly if the stacked value is zero, otherwise just
156 ;; skip over the branch offset
159 jne p_zero_branch_SKIP
165 ;;; ========================================
166 ;;; Core extension(s)
168 ;segment readable writable executable
170 include 'wordlists.asm'
176 include 'compile.asm'
178 WORD p_program_version,'PROGRAM_VERSION',dostring
179 STRING 'RRQ Forth version 0.1 - 2021-05-13',10
181 WORD p_stdin,'STDIN',dovalue
182 ;; Initialised to hold a STREAM for fd 0
185 ;;; The main entry point.
186 ;;; This word is also the last word before syscalls
188 WORD p_quit,'QUIT',fasm
189 ;; QUIT is the program entry point ********************
193 cmp qword [p_stdin_DFA],0
194 jne p_quit_INITIALIZED
199 pop qword [p_stdin_DFA] ; Assign STDIN
210 BRANCH 0,p_quit_ERROR
215 STRING 10,'*** Unknown word: '
224 mov rbp,RS_TOP ; reset the return stack
227 ;;; ========================================
229 ;segment readable writable
232 rb 1048576 ; +1 Mb heap
233 rb 1048576 ; +1 Mb heap
234 rb 1048576 ; +1 Mb heap
235 rb 1048576 ; +1 Mb heap
236 rb 1048576 ; +1 Mb heap