draft EVALUATE-STREAM
[rrq/rrqforth.git] / rrqforth.asm
index 0f7e8fbf3f9c944834555d5abdbffbfc1587eab1..db4fe33e1b3df0e3ca777aae77a69fa0c905a97f 100644 (file)
@@ -8,6 +8,42 @@ include 'machine.asm'
 
        segment readable writable executable
 
+;;; This is the very first word
+       
+       ;; FORTH is the last word of WORDLIST FORTH
+       WORD p_forth,'FORTH',dovalue
+       ;; ( -- )
+       ;; Change to use this wordlist
+       dq last_forth_word
+       dq inline_code
+       mov rax,qword [p_forth_DFA]
+       mov qword [p_wordlist],rax
+       popr rsi
+       next
+
+       WORD p_syscall,'SYSCALL',dodoes,,,8
+       ;; ( -- )
+       ;; Change to use this wordlist
+       dq last_syscall_word
+       dq inline_code
+       mov rax,qword [p_syscall_DFA]
+       mov qword [p_wordlist],rax
+       popr rsi
+       next
+
+last_wordlists_word:
+       WORD p_wordlists,'WORDLISTS',dodoes,,,8
+       ;; ( -- )
+       ;; Change to use this wordlist
+       dq p_wordlists_TFA
+       dq inline_code
+       mov rax,qword [p_wordlists_DFA]
+       mov qword [p_wordlist],rax
+       popr rsi
+       next
+       
+include 'wordlists.asm'
+
        WORD return_stack,'RS',dovariable
        ;; The return stack
        rb 1048576              ; 1 Mb return stack
@@ -26,6 +62,13 @@ DS_TOP:                              ; The initial rsp
        ;; 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
@@ -34,6 +77,39 @@ exit:
        popr rsi
        next
 
+       ;; TERMINATE0 terminates the program with code 0
+       ;; ( -- )
+       WORD 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
+
+;;; Execution semantics for a "fasm" WORD
+dofasm:
+       add rax,8
+       jmp rax
 ;;; Execution semantics for FORTH defition word
 ;;; At entry, rsi points into the calling definition, at the cell
 ;;; following the cell indicating this word, rax points to the CFA of
@@ -67,20 +143,16 @@ dovalue:
        ;; Execution semantics for a string constant ( -- addr n )
        ;; rax points to CFA field
 dostring:
-       add rax,8
-       xor rbx,rbx
-       mov bl,[rax]
-       inc rax
-       push rax
-       push rbx
+       cfa2dfa rax
+       pushpname rax
        next
 
-include 'wordlists.asm'
-include 'syscalls.asm'
 include 'memory.asm'
 include 'stack.asm'
 include 'math.asm'
+include 'logic.asm'
 include 'stdio.asm'
+include 'compile.asm'
 
        WORD p_program_version,'PROGRAM_VERSION',dostring
        STRING 'RRQ Forth version 0.1 - 2021-05-13',10
@@ -88,42 +160,58 @@ include 'stdio.asm'
        WORD p_stdin,'STDIN',dovalue
        ;; Initialised to hold a STREAM for fd 0
        dq 0
-       
+
+;;; The main entry point.
+;;; This word is also the last word before syscalls
+last_forth_word:
        WORD p_quit,'QUIT',fasm
        ;; QUIT is the program entry point ********************
 main:
        mov rsp,DS_TOP
        mov rbp,RS_TOP
-       ;; Initialize STREAM STDIN
+       cmp qword [p_stdin_DFA],0
+       jne p_quit_INITIALIZED
+       ;; Initialize STDIN
        push 0
        push 10000
        DOFORTH p_stream
-       pop qword [p_stdin_DFA]
+       pop qword [p_stdin_DFA] ; Assign STDIN
 
+p_quit_INITIALIZED:
        ;; Initial blurb
-       push qword 1                    ; stdout
-       DOFORTH p_program_version       ; version string => ( s n )
-       DOFORTH sys_write               ; printout
-       pop rax                         ; ignore errors
-
-       DOFORTH p_words
-       
-       push 0
-       DOFORTH sys_exit
+       FORTH
+       dq p_program_version
+       dq p_tell
+       dq p_stdin
+       dq p_clear_stream
+       dq p_stdin
+       dq p_evaluate_stream
+       BRANCH 0,p_quit_ERROR
+       dq p_false
+       dq sys_exit
+p_quit_ERROR:
+       dq p_literal_string
+       STRING 10,'*** Unknown word: '
+       dq p_tell
+       dq p_this_word
+       dq p_2get
+       dq p_tell
+       dq p_literal_string
+       STRING 10
+       dq p_tell
+       ENDFORTH
+       mov rbp,RS_TOP          ; reset the return stack
+       jmp main
+
+       ;; At fasm compilation: reset to make a new word list
+       previous_word = last_wordlists_word
 
-       ;; TERMINATE0 terminates the program with code 0
-       ;; ( v -- )
-       WORD terminate, 'TERMINATE',fasm
-       pop rdx
-terminate_special:
-       mov eax,60
-       syscall
+include 'syscalls.asm'
 
+       
 last_word:
-       ;; FORTH is the last word of VOCABULARY FORTH
-       WORD forth,'FORTH',dovalue
-       dq forth_TFA
-       dq 0
-
        
 heap_start:
+       rb 1048576              ; +1 Mb heap
+       rb 1048576              ; +1 Mb heap
+       rb 1048576              ; +1 Mb heap