1 ;;; ========================================
2 ;;; Dynamic memory management. Allocated with MALLOC and released with
6 ;; Allocates memory (using brk)
7 WORD p_malloc,'MALLOC',fasm
8 pushr rsi ; pretend it's a FORTH word since it
9 ; ends via sys_mmap_asm
11 push qword 0 ; address of mapping (suggestion)
12 push rax ; length of mapping
13 push qword 3 ; protection mode PROT_READ | PROT_WRITE
14 push qword 8226 ; flags PRIVATE | ANONYMOUS | LOCKED
17 jmp sys_mmap_asm ; exit via sys_mmap
19 ;;; ========================================
20 ;;; Input stream handling.
22 ;;; An input stream for a file descriptor has a stream buffer that is
23 ;;; gradually filled on needs basis. The stream buffer includes a
24 ;;; header portion with:
25 ;;; * size of buffer (excluding the 32 byte head)
26 ;;; * source file descriptor (or -1 for pure in-core data)
28 ;;; * current read position
30 ;;; An input stream for a memory block as a "detached" stream head
35 ;;; * current read position (starts at 8 = after block size)
37 WORD p_stream,'STREAM',fasm
38 ;; ( fd size -- addr ) or ( block -1 -- addr )
39 ;; Allocates a stream buffer of the given size and initializes
40 ;; it to be filled from the given input file descriptor.
46 DOFORTH p_malloc ; ( fd size addr )
48 push qword [rsp+16] ; ( fd size addr addr size )
49 DOFORTH p_erase ; ( fd size addr )
50 pop rax ; addr ( fd size )
52 sub rbx,32 ; reduce by header size
60 push 32 ; size of detached header (wastefull?)
61 DOFORTH p_malloc ; ( block addr )
62 pop rax ; header address
63 pop rbx ; block address
64 mov rcx,[rbx] ; block content size (excludes size field)
65 add rbx,8 ; block content address
66 mov qword [rax],rbx ; save block content address
67 mov qword [rax+8],-1 ; -1 = memblock flag
68 mov qword [rax+16],rcx ; save block content size
69 mov qword [rax+24],0 ; current position
73 WORD p_clear_stream,'CLEAR-STREAM',fasm
75 ;; Clear buffer of input stream
77 mov rbx,qword [rax+16] ; copy fill
78 mov qword [rax+24],rbx ; into current
81 ;;; ========================================
83 ;;; READ-STREAM-CHAR ( stream -- ch )
85 WORD p_read_stream_char,'READ-STREAM-CHAR',fasm
89 mov rbx,[rax+16] ; fill
91 p_read_stream_char.READ:
92 mov rcx,[rax+24] ; current
94 jg p_read_stream_char.CHAR
96 ;; pull in more from the source, if any
97 cmp qword [rax+8],-1 ; fd == -1 for "no source"
98 je p_read_stream_char.EOF
100 push qword [rax+8] ; fd
103 push qword [rax] ; size
110 jle p_read_stream_char.EOF
111 mov qword[rax+16],rbx
112 jmp p_read_stream_char.READ
114 p_read_stream_char.EOF:
119 p_read_stream_char.CHAR:
128 ;;; ========================================
131 WORD p_pad,'PAD',dovariable
132 ;; A buffer for holding a word
135 WORD p_read_word,'READ-WORD',fasm
136 ;; ( stream -- char* length )
137 ;; Read next word from the given stream into the PAD
144 p_read_word_skipblanks:
147 dq p_read_stream_char
151 jl p_read_word_nomore
153 jle p_read_word_skipblanks
155 p_read_word_readword:
156 ;; ( buffer length stream )
157 mov rax,qword [rsp+16]
158 mov rcx,qword [rsp+8]
163 dq p_read_stream_char
167 jl p_read_word_nomore
169 jg p_read_word_readword
176 WORD p_tell,'TELL',fasm
178 ;; Write n bytes from chars* to stdout
192 WORD p_emit,'EMIT',fasm
194 ;; Write byte to stdout
197 mov [p_emit_buffer],al
206 WORD p_nl,'NL',dovalue
208 ;; Pushes a newline character on the stack
211 WORD p_sp,'SP',dovalue
213 ;; Pushes a space character on the stack