+
+;;; ========================================
+;;; The stacks are placed here.
+
+ segment readable writable
+
+ WORD return_stack,'RETURN-STACK',dovariable
+ ;; The return stack
+ BLOCK RS_TOP
+ rb 1048576 ; 1 Mb return stack
+RS_TOP: ; The initial rbp
+
+last_system_word:
+ WORD data_stack,'DATA-STACK',dovariable
+ ;; The data stack
+ BLOCK DS_TOP
+ rb 1048576 ; 1 Mb data stack
+DS_TOP: ; The initial rsp
+
+;;; ========================================
+;;; Core execution control words
+
+ segment readable executable
+
+; At fasm compilation: reset previous_word to make a new word list
+previous_word = last_wordlists_word
+
+ WORD inline_code,'[ASM]',fasm
+ ;; ( -- )
+ ;; This transitions execution into inline assembler in the
+ ;; calling word defintion. Note that it stops advancing rsi;
+ ;; code should use FORTH macro to reenter forth execution, or
+ ;; exit to the calling definition via "jmp exit".
+ jmp qword rsi
+
+ WORD p_execute,'EXECUTE',fasm
+ ;; ( tfa -- )
+ ;; Execute the word
+ pop rax
+ tfa2cfa rax
+ jmp qword [rax] ; goto code of that FORTH word (64 bit jump)
+
+ WORD p_exit, 'EXIT',fasm
+ ;; ( -- ) ( R: addr -- )
+ ;; Returns execution to the calling definition as per the
+ ;; return stack.
+exit:
+ popr rsi
+ next
+
+ ;; TERMINATE0 terminates the program with code 0
+ ;; ( -- )
+ WORD p_terminate, 'TERMINATE0',fasm
+ pop rdx
+terminate_special:
+ mov eax,60
+ syscall
+
+ WORD p_branch,'BRANCH',fasm
+ ;; ( -- )
+ ;; Using subsequent inline cell as branch offset, branch
+ ;; accordingly
+ add rsi,qword [rsi]
+ add rsi,8
+ next
+
+ WORD p_zero_branch,'0BRANCH',fasm
+ ;; ( v -- )
+ ;; Using subsequent inline cell as branch offset, branch
+ ;; accordingly if the stacked value is zero, otherwise just
+ ;; skip over the branch offset
+ pop rax
+ cmp rax,0
+ jne p_zero_branch_SKIP
+ add rsi,qword [rsi]
+p_zero_branch_SKIP:
+ add rsi,8
+ next
+
+;;; ========================================
+;;; Core extension(s)
+
+ segment readable writable executable
+
+include 'wordlists.asm'