mov qword [rdi],0 ; OFF
add rdi,8
mov qword [rbx+8],rdi ; pCFA
- add rdi,8
mov qword [rdi],dovariable ; CFA
add rdi,8
mov qword [p_here_DFA],rdi ; allocate the space
;; ( "word" -- cfa )
;; Find the following word and push its cfa, or 0
pushr rsi
- DOFORTH p_stdin, p_read_word, p_find
+ DOFORTH p_input, p_get, p_read_word, p_find
cmp qword[rsp],0
jne p_quote_tfa
add rsp,16
add rsi,8
next
- WORD p_literal_string,'S"',fasm ;; " (fool emacs)
+ WORD p_literal_string,'S"',fasm,IMMEDIATE ;; " (fool emacs)
;; ( -- char* n )
;; Save string on heap to make available at interpretation
;; not for interactive use!!
+ cmp qword [p_state_DFA],0
+ je p_literal_string_executing
+ pushr rsi
+ mov rdi,qword [p_here_DFA]
+ mov qword [rdi],p_literal_string
+ add rdi,8
+ mov qword [p_here_DFA],rdi
+ DOFORTH p_double_quote
+ pop rcx
+ pop rsi
+ mov rdi,qword [p_here_DFA]
+ mov qword [rdi],rcx
+ add rdi,8
+p_literal_string_copy:
+ dec rcx
+ jl p_literal_string_copied
+ movsb
+ jmp p_literal_string_copy
+p_literal_string_copied:
+ mov qword [p_here_DFA],rdi
+ popr rsi
+ next
+
+p_literal_string_executing:
mov rax,qword [rsi]
add rsi,8
push rsi
popr rsi
next
+ WORD p_input,'INPUT',dovariable
+ ;; The current input stream for evaluate-stream
+ dq 0
+
WORD p_this_word,'THIS-WORD',dovariable
dq 0,0 ; ( n chars* )
;; ( stream* -- *?* flag )
;; Execute the words from the given stream
;; returns 1 if stream ends and 0 if an unknown word is found
- dq p_ltR ; Keep the stream on the return stack.
+ dq p_input, p_get, p_gtR ; save old stream on R-stack
+ dq p_input, p_put
p_evaluate_stream_PROMPT:
- dq p_depth
- dq p_dot
+ dq p_verboseQ, p_get
+ BRANCH 0,p_evaluate_stream_LOOP
+ dq p_depth, p_dot
dq p_literal_string
STRING '> '
dq p_tell
- dq p_Rget
+ dq p_input, p_get
dq p_clear_stream
p_evaluate_stream_LOOP:
- dq p_Rget
+ dq p_input, p_get
dq p_read_word
dq p_dup
BRANCH 0,p_evaluate_stream_END ; branch if 0 on TOP
- dq p_2dup
- dq p_this_word
- dq p_2put
+ dq p_2dup, p_this_word, p_2put
dq p_find
dq p_dup
BRANCH 0,p_evaluate_stream_NOTWORD ; branch if 0 on TOP
dq p_get
BRANCH 0,p_evaluate_stream_INTERPRET
dq p_dup
- dq p_cfa2flags_get
- dq p_literal, 1
+ dq p_tfa2flags_get
+ dq p_literal, 1 ; the immediate bit
dq p_and
- dq p_not
- BRANCH 0,p_evaluate_stream_INTERPRET
- dq p_comma
- BRANCH ,p_evaluate_stream_AFTER
+ BRANCH 0,p_evaluate_stream_COMPILE
p_evaluate_stream_INTERPRET:
+ dq p_tfa2cfa
dq p_execute
BRANCH ,p_evaluate_stream_AFTER
+p_evaluate_stream_COMPILE:
+ dq p_tfa2cfa
+ dq p_comma
+ BRANCH ,p_evaluate_stream_AFTER
p_evaluate_stream_NOTWORD:
dq p_drop
dq p_number
+ dq p_dup
BRANCH 0,p_evaluate_stream_BAD ; branch if 0
+ dq p_drop
+ dq p_state, p_get
+ BRANCH 0,p_evaluate_stream_AFTER ; branch if 0
+ dq p_literal, p_literal
+ dq p_comma, p_comma
p_evaluate_stream_AFTER:
- dq p_Rget
+ dq p_input, p_get
dq p_stream_nchars
BRANCH 0,p_evaluate_stream_PROMPT
BRANCH ,p_evaluate_stream_LOOP
dq p_2drop
dq p_literal, 1
p_evaluate_stream_BAD:
- dq p_Rgt
- dq p_drop
+ dq p_Rgt, p_input, p_put ; restore previous stream
dq p_exit
WORD p_colon,':'
;; Read next word as a new word into current wordlist, set it
;; to be a doforth word, and set compiling mode.
dq p_literal, doforth
- dq p_stdin
+ dq p_input, p_get
dq p_read_word
dq p_create
dq p_tfa2cfa
dq p_right_bracket
dq p_exit
- WORD p_semicolon,';'
+ WORD p_semicolon,';',,IMMEDIATE
;; ( -- )
;; Lay out p_exit, and set interpreting mode
dq p_left_bracket
dq p_literal, p_exit
dq p_comma
+ dq p_left_bracket
+ dq p_exit
+
+ WORD p_immediate,'IMMEDIATE',fasm,IMMEDIATE
+ ;; ( -- )
+ ;; Set "immediate flag" of the word being defined
+ mov rax,qword [p_wordlist_DFA]
+ mov rax,qword [rax] ; tfa of most recent word
+ mov qword [rax+16],1 ; set the flags field to 1
+ next
+
+ WORD p_open_file_quote,'OPEN-FILE"'
+ ;; ( "name" -- fd )
+ dq p_double_quote
+ dq p_create
+ dq p_tfa2namez
+ dq p_literal,0
+ dq p_literal,0
+ dq sys_open
+ dq p_exit
+
+ WORD p_load_file_quote,'LOAD-FILE"'
+ ;; ( "name" -- )
+ ;; Create a word for the nominated file for a stream to,
+ ;; and store that stream pointer, then invoke evaluate-stream
+ dq p_open_file_quote ; fd
+ dq p_literal, 15000 ; buffer size
+ dq p_stream
+ dq p_dup
+ dq p_comma
+ dq p_evaluate_stream
+ dq p_exit