added short string macro
[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         WORD p_exit, 'EXIT',fasm
30         ;; ( -- ) ( R: addr -- )
31         ;; Returns execution to the calling definition as per the
32         ;; return stack.
33 exit:
34         popr rsi
35         next
36
37 ;;; Execution semantics for FORTH defition word
38 ;;; At entry, rsi points into the calling definition, at the cell
39 ;;; following the cell indicating this word, rax points to the CFA of
40 ;;; this word.
41 doforth:
42         pushr rsi
43         lea rsi, [rax+8]        ; rsi = the DFA of the rax word
44         next
45
46 ;;; Execution semantics for DOES>
47 ;;; The cell at [cfa-8] holds an adjustment offset.
48 dodoes:
49         pushr rsi
50         lea rsi, [rax+8]        ; rsi = the DFA of the rax word
51         add rsi,[rax-8]         ; adjust rsi to the DOES> part
52         next
53
54         ;; Execution semantics for a variable ( -- addr )
55         ;; rax points to CFA field
56 dovariable:
57         add rax,8
58         push rax
59         next
60
61         ;; Execution semantics for a constant ( -- v )
62         ;; rax points to CFA field
63 dovalue:
64         push qword [rax+8]
65         next
66
67         ;; Execution semantics for a string constant ( -- addr n )
68         ;; rax points to CFA field
69 dostring:
70         add rax,8
71         xor rbx,rbx
72         mov bl,[rax]
73         inc rax
74         push rax
75         push rbx
76         next
77
78 include 'wordlists.asm'
79 include 'syscalls.asm'
80 include 'memory.asm'
81 include 'stack.asm'
82 include 'math.asm'
83 include 'stdio.asm'
84
85         WORD p_program_version,'PROGRAM_VERSION',dostring
86         STRING 'RRQ Forth version 0.1 - 2021-05-13',10
87
88         WORD p_stdin,'STDIN',dovalue
89         ;; Initialised to hold a STREAM for fd 0
90         dq 0
91         
92         WORD p_quit,'QUIT',fasm
93         ;; QUIT is the program entry point ********************
94 main:
95         mov rsp,DS_TOP
96         mov rbp,RS_TOP
97         ;; Initialize STREAM STDIN
98         push 0
99         push 10000
100         DOFORTH p_stream
101         pop qword [p_stdin_DFA]
102
103         ;; read a word
104         push qword 1            ; ( fd ) =stdout
105         push qword [p_stdin_DFA]
106         FORTH
107         dq p_read_word          ; ( fd s n )
108         dq sys_write
109         ENDFORTH
110
111         push qword 1                    ; stdout
112         DOFORTH p_program_version       ; version string => ( s n )
113         DOFORTH sys_write               ; printout
114         pop rax                         ; ignore errors
115         
116         push 0
117         DOFORTH sys_exit
118
119         ;; TERMINATE0 terminates the program with code 0
120         ;; ( v -- )
121         WORD terminate, 'TERMINATE',fasm
122         pop rdx
123 terminate_special:
124         mov eax,60
125         syscall
126
127 last_word:
128         ;; FORTH is the last word of VOCABULARY FORTH
129         WORD forth,'FORTH',dovalue
130         dq forth_TFA
131         dq 0
132
133         
134 heap_start: