added CFA>FLAGS@ helper
[rrq/rrqforth.git] / compile.asm
index 3d5433ef5ff133ae51dfd033492fbe7336ce4f17..2b57cf16cef2a6835af4b47bf086e5126426fbf1 100644 (file)
@@ -89,10 +89,35 @@ p_create_COPY:
        add rsi,8
        next
 
-       WORD p_literal_string,'S"',fasm
-                                     ;; " (fool emacs)
-       ;; ( -- chars* n )
-       ;; Push the value of successor cell onto stack, and skip it
+       WORD p_literal_string,'S"',fasm ;; " (fool emacs)
+       ;; Compilation: ( "..." -- )
+       ;; Interpretation: ( -- char* n )
+       ;; Save string on heap to make available at interpretation
+       cmp qword [p_state_DFA],0
+       je p_literal_string_interpret
+       ;; compilation mode: read stream until \" onto the heap
+       pushr rsi
+       mov rdi,[p_here_DFA]
+       lea rbx,[p_literal_string_CFA]
+       mov qword [rdi],rbx
+       add rdi,8
+       pop rbx
+       mov qword [rdi],rbx
+       add rdi,8
+       cmp rbx,0
+       je p_literal_string_end
+       lea rsi,[p_pad_DFA]
+p_literal_string_copy:
+       lodsb
+       stosb
+       dec rbx
+       jg p_literal_string_copy
+p_literal_string_end:
+       mov qword [p_here_DFA],rdi
+       popr rsi
+       next
+
+p_literal_string_interpret:
        mov rax,qword [rsi]
        add rsi,8
        push rsi
@@ -139,42 +164,56 @@ p_create_COPY:
        pushr rsi
        pop rcx                 ; ( -- chars* )
        pop rsi                 ; ( -- )
-       xor rdi,rdi
+       xor rdi,rdi             ; value
+       mov rbx,1               ; sign (byte 0=0 means negative)
+       cmp qword [p_base_DFA],10
+       jne p_number_LOOP
+       cmp byte [rsi],'-'
+       jne p_number_LOOP
+       mov rbx,0
+       inc rsi
+       dec rcx
+       jle p_number_BAD
 p_number_LOOP:
        dec rcx
        jl p_number_DONE
+       xor rax,rax             ; clearing
        lodsb
-       mov bl,al               ; into bl
-       cmp bl,'0'
+       cmp al,'0'
        jl p_number_BAD
-       cmp bl,'9'
+       cmp al,'9'
        jg p_number_ALPHA
-       sub bl,'0'
+       sub al,'0'
 p_number_CONSUME:
+       mov r8,rax
        mov rax,rdi
-       mul qword [p_base_DFA]
-       add rax,rbx
+       mul qword [p_base_DFA]  ; uses rdx:rax
+       add rax,r8
        mov rdi,rax
        jmp p_number_LOOP
 p_number_ALPHA:
-       cmp bl,'A'
+       cmp al,'A'
        jl p_number_BAD
-       cmp bl,'Z'
+       cmp al,'Z'
        jg p_number_alpha
-       sub bl,'A'-10
+       sub al,'A'-10
        jmp p_number_CONSUME
 p_number_alpha:
-       cmp bl,'a'
+       cmp al,'a'
        jl p_number_BAD
-       cmp bl,'z'
+       cmp al,'z'
        jg p_number_BAD
-       sub bl,'a'-10
+       sub al,'a'-10
        jmp p_number_CONSUME
 p_number_BAD:
        push qword 0
        popr rsi
        next
 p_number_DONE:
+       cmp rbx,0
+       jne p_numper_POSITIVE
+       neg rdi
+p_numper_POSITIVE:
        push rdi
        push qword 1
        popr rsi
@@ -188,31 +227,30 @@ p_number_DONE:
        ;; 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.
+p_evaluate_stream_PROMPT:
+       dq p_depth, p_dot, p_literal_string
+       STRING ' > '
+       dq p_tell, p_Rget, p_clear_stream
 p_evaluate_stream_LOOP:
-       dq p_Rget               ; ( -- stream*
-       dq p_read_word          ; ( -- chars* n )
-       dq p_dup
+       dq p_Rget, p_read_word, p_dup
        BRANCH 0,p_evaluate_stream_END ; branch if 0 on TOP
-       dq p_2dup               ; ( -- chars* n chars* n )
-       dq p_this_word          ; ( -- chars* n chars* n p )
-       dq p_2put               ; ( -- chars* n )
-       dq p_find               ; ( -- [ chars* n 0 ]/[ tfa ] )
-       dq p_dup                ; ( -- [ chars* n 0 0 ]/[ tfa tfa ] )
+       dq p_2dup, p_this_word, p_2put, p_find, p_dup
        BRANCH 0,p_evaluate_stream_NOTWORD ; branch if 0 on TOP
-       dq p_execute            ; consumes tfa
-       BRANCH ,p_evaluate_stream_LOOP
+       dq p_state, p_get
+       BRANCH 0,p_evaluate_stream_INTERPRET
+       dq p_comma
+       BRANCH ,p_evaluate_stream_AFTER
+p_evaluate_stream_INTERPRET:
+       dq p_execute
+       BRANCH ,p_evaluate_stream_AFTER
 p_evaluate_stream_NOTWORD:
-       dq p_drop               ; ( -- chars* n )
-       dq p_number             ; ( -- [ 0 ]/[ v 1 ] )
-       dq p_dup
-       BRANCH 0,p_evaluate_stream_BAD ; branch if 0 on TOP
-       dq p_drop
+       dq p_drop, p_number
+       BRANCH 0,p_evaluate_stream_BAD ; branch if 0
+p_evaluate_stream_AFTER:
+       dq p_Rget,p_stream_nchars
+       BRANCH 0,p_evaluate_stream_PROMPT
        BRANCH ,p_evaluate_stream_LOOP
 p_evaluate_stream_END:
-       dq p_2drop
-       dq p_literal
-       dq 1
+       dq p_2drop, p_literal, 1
 p_evaluate_stream_BAD:
-       dq p_Rgt                ; Discard the stream from the return stack
-       dq p_drop
-       dq p_exit
+       dq p_Rgt, p_drop, p_exit