expand to handle core block based streams
[rrq/rrqforth.git] / rrqforth.asm
1 ; This is a forth interpreter for x86_64 (elf64)
2         format elf64 executable
3         entry main
4
5 include 'machine.asm'
6
7 ;;; ============================================================
8
9         segment readable writable executable
10
11         WORD return_stack,'RS',dovariable
12         ;; The return stack
13         rb 1048576              ; 1 Mb return stack
14 RS_TOP:                         ; The initial rbp
15         
16         WORD data_stack,'DS',dovariable
17         ;; The data stack
18         rb 1048576              ; 1 Mb data stack
19 DS_TOP:                         ; The initial rsp
20
21         WORD inline_code,'[ASM]',fasm
22         ;; ( -- )
23         ;; This transitions execution into inline assembler in the
24         ;; calling word defintion. Note that it stops advancing rsi;
25         ;; code should use FORTH macro to reenter forth execution, or
26         ;; exit to the calling definition via "jmp exit".
27         jmp qword rsi
28
29 ;;; Execution semantics for FORTH defition word
30 ;;; At entry, rsi points into the calling definition, at the cell
31 ;;; following the cell indicating this word, rax points to the CFA of
32 ;;; this word.
33 doforth:
34         pushr rsi
35         lea rsi, [rax+8]        ; rsi = the DFA of the rax word
36         next
37
38         WORD p_exit, 'EXIT',fasm
39         ;; ( -- ) ( R: addr -- )
40         ;; Returns execution to the calling definition as per the
41         ;; return stack.
42 exit:
43         popr rsi
44         next
45
46         ;; Execution semantics for a variable ( -- addr )
47         ;; rax points to doer field
48 dovariable:
49         push rax+16
50         next
51
52         ;; Execution semantics for a constant ( -- v )
53         ;; rax points to doer field
54 dovalue:
55         push qword [rax+16]
56         next
57
58         ;; Execution semantics for a string constant ( -- addr n )
59         ;; rax points to doer field
60 dostring:
61         add rax,16
62         mov bl,[rax]
63         mov byte [rsp],bl
64         push rax+1
65         next
66
67 include 'wordlists.asm'
68 include 'syscalls.asm'
69 include 'memory.asm'
70 include 'stack.asm'
71 include 'math.asm'
72 include 'stdio.asm'
73
74         WORD p_program_version,'PROGRAM_VERSION',dostring
75         db length
76 program_version_string: 
77         db 'RRQ Forth version 0.1 - 2021-05-13',10
78         length = $ - program_version_string
79
80         WORD p_stdin,'STDIN',dovalue
81         ;; Initialised to hold a STREAM for fd 0
82         dq 0
83         
84         WORD p_quit,'QUIT',fasm
85         ;; QUIT is the program entry point ********************
86 main:
87         mov rsp,DS_TOP
88         mov rbp,RS_TOP
89         ;; Initialize STREAM STDIN
90         push 0
91         push 10000
92         DOFORTH p_stream
93         pop qword [p_stdin_DFA]
94
95         ;; read a word
96         push qword 1            ; ( fd ) =stdout
97         push qword [p_stdin_DFA]
98         FORTH
99         dq p_read_word          ; ( fd s n )
100         dq sys_write
101         ENDFORTH
102
103         push qword 1                    ; stdout
104         push qword program_version_string ; address of string
105         push qword length               ; length of string (cheating)
106         DOFORTH sys_write               ; printout
107         pop rax                         ; ignore errors
108         
109         push 0
110         DOFORTH sys_exit
111
112         ;; TERMINATE0 terminates the program with code 0
113         ;; ( v -- )
114         WORD terminate, 'TERMINATE',fasm
115         pop rdx
116 terminate_special:
117         mov eax,60
118         syscall
119
120 last_word:
121         ;; FORTH is the last word of VOCABULARY FORTH
122         WORD forth,'FORTH',dovalue
123         dq forth_TFA
124         dq 0
125
126         
127 heap_start: