1 ; This is a forth interpreter for x86_64 (elf64)
2 format elf64 executable
7 ;;; ============================================================
9 segment readable writable executable
11 ;;; This is the very first word
13 ;; FORTH is the last word of WORDLIST FORTH
14 WORD p_forth,'FORTH',dovalue
16 ;; Change to use this wordlist
19 mov rax,qword [p_forth_DFA]
20 mov qword [p_wordlist],rax
24 WORD p_syscall,'SYSCALL',dodoes,,,8
26 ;; Change to use this wordlist
29 mov rax,qword [p_syscall_DFA]
30 mov qword [p_wordlist],rax
35 WORD p_wordlists,'WORDLISTS',dodoes,,,8
37 ;; Change to use this wordlist
40 mov rax,qword [p_wordlists_DFA]
41 mov qword [p_wordlist],rax
45 include 'wordlists.asm'
47 WORD return_stack,'RS',dovariable
49 rb 1048576 ; 1 Mb return stack
50 RS_TOP: ; The initial rbp
52 WORD data_stack,'DS',dovariable
54 rb 1048576 ; 1 Mb data stack
55 DS_TOP: ; The initial rsp
57 WORD inline_code,'[ASM]',fasm
59 ;; This transitions execution into inline assembler in the
60 ;; calling word defintion. Note that it stops advancing rsi;
61 ;; code should use FORTH macro to reenter forth execution, or
62 ;; exit to the calling definition via "jmp exit".
65 WORD p_execute,'EXECUTE',fasm
70 jmp qword [rax] ; goto code of that FORTH word (64 bit jump)
72 WORD p_exit, 'EXIT',fasm
73 ;; ( -- ) ( R: addr -- )
74 ;; Returns execution to the calling definition as per the
80 ;; TERMINATE0 terminates the program with code 0
82 WORD terminate, 'TERMINATE0',fasm
88 WORD p_branch,'BRANCH',fasm
90 ;; Using subsequent inline cell as branch offset, branch
96 WORD p_zero_branch,'0BRANCH',fasm
98 ;; Using subsequent inline cell as branch offset, branch
99 ;; accordingly if the stacked value is zero, otherwise just
100 ;; skip over the branch offset
103 jne p_zero_branch_SKIP
109 ;;; Execution semantics for a "fasm" WORD
113 ;;; Execution semantics for FORTH defition word
114 ;;; At entry, rsi points into the calling definition, at the cell
115 ;;; following the cell indicating this word, rax points to the CFA of
119 lea rsi, [rax+8] ; rsi = the DFA of the rax word
122 ;;; Execution semantics for DOES>
123 ;;; The cell at [cfa-8] holds an adjustment offset.
126 lea rsi, [rax+8] ; rsi = the DFA of the rax word
127 add rsi,[rax-8] ; adjust rsi to the DOES> part
130 ;; Execution semantics for a variable ( -- addr )
131 ;; rax points to CFA field
137 ;; Execution semantics for a constant ( -- v )
138 ;; rax points to CFA field
143 ;; Execution semantics for a string constant ( -- addr n )
144 ;; rax points to CFA field
155 include 'compile.asm'
157 WORD p_program_version,'PROGRAM_VERSION',dostring
158 STRING 'RRQ Forth version 0.1 - 2021-05-13',10
160 WORD p_stdin,'STDIN',dovalue
161 ;; Initialised to hold a STREAM for fd 0
164 ;;; The main entry point.
165 ;;; This word is also the last word before syscalls
167 WORD p_quit,'QUIT',fasm
168 ;; QUIT is the program entry point ********************
172 cmp qword [p_stdin_DFA],0
173 jne p_quit_INITIALIZED
178 pop qword [p_stdin_DFA] ; Assign STDIN
189 BRANCH 0,p_quit_ERROR
194 STRING 10,'*** Unknown word: '
203 mov rbp,RS_TOP ; reset the return stack
206 ;; At fasm compilation: reset to make a new word list
207 previous_word = last_wordlists_word
209 include 'syscalls.asm'
215 rb 1048576 ; +1 Mb heap
216 rb 1048576 ; +1 Mb heap
217 rb 1048576 ; +1 Mb heap