started compiler words
[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 ;;; This is the very first word
12         
13         ;; FORTH is the last word of WORDLIST FORTH
14         WORD p_forth,'FORTH',dovalue
15         ;; ( -- )
16         ;; Change to use this wordlist
17         dq last_forth_word
18         dq inline_code
19         mov rax,qword [p_forth_DFA]
20         mov qword [p_wordlist],rax
21         popr rsi
22         next
23
24         WORD p_syscall,'SYSCALL',dodoes,,,8
25         ;; ( -- )
26         ;; Change to use this wordlist
27         dq last_syscall_word
28         dq inline_code
29         mov rax,qword [p_syscall_DFA]
30         mov qword [p_wordlist],rax
31         popr rsi
32         next
33
34 last_wordlists_word:
35         WORD p_wordlists,'WORDLISTS',dodoes,,,8
36         ;; ( -- )
37         ;; Change to use this wordlist
38         dq p_wordlists_TFA
39         dq inline_code
40         mov rax,qword [p_wordlists_DFA]
41         mov qword [p_wordlist],rax
42         popr rsi
43         next
44         
45 include 'wordlists.asm'
46
47         WORD return_stack,'RS',dovariable
48         ;; The return stack
49         rb 1048576              ; 1 Mb return stack
50 RS_TOP:                         ; The initial rbp
51         
52         WORD data_stack,'DS',dovariable
53         ;; The data stack
54         rb 1048576              ; 1 Mb data stack
55 DS_TOP:                         ; The initial rsp
56
57         WORD inline_code,'[ASM]',fasm
58         ;; ( -- )
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".
63         jmp qword rsi
64
65         WORD p_exit, 'EXIT',fasm
66         ;; ( -- ) ( R: addr -- )
67         ;; Returns execution to the calling definition as per the
68         ;; return stack.
69 exit:
70         popr rsi
71         next
72
73         ;; TERMINATE0 terminates the program with code 0
74         ;; ( -- )
75         WORD terminate, 'TERMINATE0',fasm
76         pop rdx
77 terminate_special:
78         mov eax,60
79         syscall
80
81 ;;; Execution semantics for FORTH defition word
82 ;;; At entry, rsi points into the calling definition, at the cell
83 ;;; following the cell indicating this word, rax points to the CFA of
84 ;;; this word.
85 doforth:
86         pushr rsi
87         lea rsi, [rax+8]        ; rsi = the DFA of the rax word
88         next
89
90 ;;; Execution semantics for DOES>
91 ;;; The cell at [cfa-8] holds an adjustment offset.
92 dodoes:
93         pushr rsi
94         lea rsi, [rax+8]        ; rsi = the DFA of the rax word
95         add rsi,[rax-8]         ; adjust rsi to the DOES> part
96         next
97
98         ;; Execution semantics for a variable ( -- addr )
99         ;; rax points to CFA field
100 dovariable:
101         add rax,8
102         push rax
103         next
104
105         ;; Execution semantics for a constant ( -- v )
106         ;; rax points to CFA field
107 dovalue:
108         push qword [rax+8]
109         next
110
111         ;; Execution semantics for a string constant ( -- addr n )
112         ;; rax points to CFA field
113 dostring:
114         cfa2dfa rax
115         pushpname rax
116         next
117
118 include 'memory.asm'
119 include 'stack.asm'
120 include 'math.asm'
121 include 'stdio.asm'
122 include 'compile.asm'
123
124         WORD p_program_version,'PROGRAM_VERSION',dostring
125         STRING 'RRQ Forth version 0.1 - 2021-05-13',10
126
127         WORD p_stdin,'STDIN',dovalue
128         ;; Initialised to hold a STREAM for fd 0
129         dq 0
130
131 ;;; The main entry point.
132 ;;; This word is also the last word before syscalls
133 last_forth_word:
134         WORD p_quit,'QUIT',fasm
135         ;; QUIT is the program entry point ********************
136 main:
137         mov rsp,DS_TOP
138         mov rbp,RS_TOP
139         ;; Initialize STREAM STDIN
140         push 0
141         push 10000
142         DOFORTH p_stream
143         pop qword [p_stdin_DFA]
144
145         ;; Initial blurb
146         FORTH
147         dq p_program_version
148         dq p_tell
149         dq p_stdin
150         dq p_read_word
151         dq p_tell
152         dq p_nl
153         dq p_emit
154         ENDFORTH
155         
156         ;; DOFORTH p_words
157         
158         push 0
159         DOFORTH sys_exit
160
161         previous_word = last_wordlists_word
162
163 include 'syscalls.asm'
164
165         
166 last_word:
167         
168 heap_start:
169         rb 1048576              ; +1 Mb heap
170         rb 1048576              ; +1 Mb heap
171         rb 1048576              ; +1 Mb heap