~nch/onward

092023e9fa304510b4f2858ec992406dcbe158fc — nc 4 years ago 443c3d5
ugg - forgot to include the main sorce
2 files changed, 109 insertions(+), 1 deletions(-)

M .gitignore
A onward.s
M .gitignore => .gitignore +1 -1
@@ 1,2 1,2 @@
*.o
forth
onward

A onward.s => onward.s +108 -0
@@ 0,0 1,108 @@
; vi: ft=nasm

; https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

;

global _start
section .text
%define SYS_READ 0
%define SYS_WRITE 1
%define SYS_EXIT 60

%define STDIN 0
%define STDOUT 1

_start:

rep_loop:
        ;; write prompt
        mov rax, SYS_WRITE
        mov rdi, STDOUT
        mov rsi, prompt
        mov rdx, prompt_len
        syscall

        ;; read input string
        mov rax, SYS_READ
        mov rdi, STDIN
        mov rsi, in_buf
        mov rdx, buf_len
        syscall

        mov rdx, rax                ; length in rax

        cmp rdx, 0                  ; exit if empty (user sent Ctrl-D)
        jz exit

        ;; get the first word in the string
        ;; while calculating hash of string

        ; update hash (sdbm hash):
        ;   for c in str:
        ;     new_hash = c + (hash << 6) + (hash << 16) - hash
        ;     hash = new_hash

        mov rbx, word_buf           ; word_ptr:   rbx = (char *) word_buf
        mov rcx, 0                  ; hash:       rcx = 0
                                    ; in_buf_ptr: rsi (set above)

read_next_word_loop:
        mov rax, 0                  ; clear rax
        mov al, [rsi]               ; c = *in_buf_ptr
        cmp al, byte ' '            ; check for whitespace
        je .end
        cmp al, byte `\n`
        je .end
        cmp al, byte `\t`
        je .end
        mov [rbx], al               ; *word_buf = c

        ; rdx = new_hash (copy of hash for iteration)
        ; rax = current character (because of al)

        ; calculate hash
        mov rdx, rcx                ; rdx = hash. copied so we can shift it around
        sal rdx, 6                  ; hash << 6
        add rax, rdx
        sal rdx, 10                 ; hash << 16
        add rax, rdx
        sub rax, rcx                ; - hash
        mov rcx, rax                ; hash = new_hash

        add rsi, 1                  ; in_buf_ptr++
        add rbx, 1                  ; word_ptr++
        jmp read_next_word_loop
.end:
        ; calculate len, store it in rdx
        mov rdx, rbx
        sub rdx, word_buf

        ; TODO: store value into intern table
        ; TODO: push symbol value onto stack
        ; TODO: bootstrap
        ; TODO: jit self

        ;; echo word
        mov rax, SYS_WRITE
        mov rdi, STDOUT
        mov rsi, word_buf
        ; rdx set above
        syscall

        jmp rep_loop

exit:
        mov rax, SYS_EXIT
        mov rdi, 0
        syscall

section .bss
        in_buf: resb 128
        buf_len: equ $ - in_buf

        word_buf: resb 32

section .rodata
        prompt: db "> "
        prompt_len: equ $ - prompt