+p_stream_MEM:
+ push 32 ; size of detached header (wastefull?)
+ DOFORTH p_malloc ; ( block addr )
+ pop rax ; header address
+ pop rbx ; block address
+ mov rcx,[rbx] ; block content size (excludes size field)
+ add rbx,8 ; block content address
+ mov qword [rax],rbx ; save block content address
+ mov qword [rax+8],-1 ; -1 = memblock flag
+ mov qword [rax+16],rcx ; save block content size
+ mov qword [rax+24],0 ; current position
+ push rax
+ jmp exit
+
+ WORD p_unstream,'UNSTREAM',fasm
+ ;; ( stream -- )
+ ;; Release mmap-ed memory
+ pushr rsi
+ mov rax,qword [rsp]
+ mov rbx,qword [rax+8]
+ cmp rbx,0
+ jl p_unstream_incore
+ ;; unstream fd stream
+ push rbx
+ DOFORTH sys_close
+ pop rax
+ mov rax,qword [rsp]
+ push qword [rax+16]
+ add qword [rax+16],32
+ DOFORTH sys_munmap
+ pop rax
+ popr rsi
+ next
+p_unstream_incore:
+ mov rbx,qword [rax+16]
+ mov rax,qword [rax]
+ mov qword [rsp],rax
+ push rbx
+ DOFORTH sys_munmap
+ pop rax
+ popr rsi
+ next
+
+ WORD p_clear_stream,'CLEAR-STREAM',fasm
+ ;; ( stream -- )
+ ;; "Clear" the stream by moving its "current position" to the
+ ;; "fill position".
+ pop rax
+ mov rbx,qword [rax+16] ; copy fill
+ mov qword [rax+24],rbx ; into current
+ next
+
+ WORD p_stream_nchars,'STREAM-NCHARS',fasm
+ ;; ( stream -- n )
+ ;; Scan over whitespace in the stream buffer (without actually
+ ;; consuming) and tell how much then remains.
+ pushr rsi
+ mov rcx,qword [rsp]
+ mov rbx,qword [rcx+16] ; fill
+ sub rbx,qword [rcx+24] ; current
+ cmp qword [rcx+8],-1
+ je p_stream_nchars_memblock
+ mov rsi,rcx
+ add rsi,32
+ jmp p_stream_nchars_skipblanks
+p_stream_nchars_memblock:
+ mov rsi,qword [rcx]
+p_stream_nchars_skipblanks:
+ add rsi,qword [rcx+24] ;
+ cmp rbx,0
+ je p_stream_nchars_done
+p_stream_nchars_loop:
+ lodsb
+ cmp al,32
+ jg p_stream_nchars_done
+ dec rbx
+ jg p_stream_nchars_loop
+p_stream_nchars_done:
+ mov qword [rsp],rbx
+ popr rsi
+ next
+
+;;; ========================================
+;;; Copy line to PAD
+;;; READ-STREAM-LINE ( stream -- n )
+
+ WORD p_read_stream_line,'READ-STREAM-LINE'
+ ;; ( stream -- n )
+ ;; Read stream until next newline
+ dq p_gtR, p_pad
+p_read_stream_line_loop:
+ dq p_Rget, p_read_stream_char
+ dq p_dup, p_0less
+ BRANCH 1,p_read_stream_line_done
+ dq p_dup, p_nl, p_equal
+ BRANCH 1,p_read_stream_line_done
+ dq p_over, p_Cput, p_literal,1, p_plus
+ BRANCH ,p_read_stream_line_loop
+p_read_stream_line_done:
+ dq p_drop, p_literal,0, p_over, p_Cput
+ dq p_pad, p_minus, p_return
+
+
+;;; ========================================
+;;; Stream reading
+;;; READ-STREAM-CHAR ( stream -- ch )
+