; jewelforth ;; MACROS {{{ %macro pspush 1 lea r14, [r14-8] mov qword [r14], %1 %endmacro %macro pspop 1 mov %1, qword [r14] lea r14, [r14+8] %endmacro ;;; dictionary macros {{{ %define mac_latest 0 ; updated through defdict %macro defdict 3 ; name asm-label flags %strlen slen %1 global lfa_%2 lfa_%2: dq mac_latest %define mac_latest lfa_%2 ffa_%2: db %3 ; FFA nfa_%2: dw slen ; NFA db 0 db %1 %endmacro %macro defword 3 defdict %1, %2, %3 %2: %endmacro %macro defconst 4 ; ... value defdict %1, %2, %3 %define %2 %4 pspush qword %4 ret %endmacro %macro defvar 4 ; ... default-value %2: dq %4 defdict %1, %2, %3 pspush qword %2 ret %endmacro %assign smudge_mask 0x1 %assign immemdiate_mask 0x2 %assign false 0x0 %assign true 0xffffffffffffffff ;;; }}} ;; syscall %assign __NR_read 0 %assign __NR_write 1 %assign __NR_brk 12 %assign __NR_exit 60 ;; }}} section .bss wstack_b: resq 2047 wstack: resq 1 section .text global _start _start: ; init mov r14, wstack ; point SP to top mov rdi, 0 mov rax, __NR_exit syscall defword "bye", bye, 0 mov rdi, 0 mov rax, __NR_exit syscall ret ; will not be reached defword "@", fetch, 0 pspop r11 mov r12, qword [r11] pspush r12 ret defword "c@", cfetch, 0 pspop r11 xor r12, r12 mov r12b, [r11] pspush r12 ret defword "!", store, 0 pspop r11 pspop r12 mov qword [r11], r12 ret defword "c!", cstore, 0 pspop r11 pspop r12 mov [r11], r12b ret ; stage 1 parser. very rudimentary, does not recognise numbers, ; only recognises newlines and spaces as whitespace. ; since it will only parse a little bit of the init file ; there won't be any error checking either. defword "parse", parse, 0 mov r13, qword [to_in] add r13, initfile mov r12b, byte [r13] .wsloop: ; skip initial ws cmp r12b, 0x20 je .wsloop_cont cmp r12b, 0x0a jne .wordloop_start .wsloop_cont: inc r13 mov r12b, byte [r13] jmp .wsloop .wordloop_start: push r13 ; keep start address of this word for later mov r11, 1 ; W: word length count .wordloop: cmp r12b, 0x20 je .wordloop_end cmp r12b, 0x0a je .wordloop_end inc r11 inc r13 mov r12b, byte [r13] jmp .wordloop .wordloop_end: sub r13, initfile mov qword [to_in], r13 pop r13 pspush r13 ; c-addr pspush r11 ; u ret ; probably fucked up and broken. have not tested any of this yet defword "find", find, 0 pspop r10 ; u pspop r11 ; c-addr mov r12, latest mov r13, qword [r12] mov r12, r13 .check_smudge: add r13, 8 mov r9b, byte [r13] test r9b, smudge_mask jnz .no .no_smudge: inc r13 mov r9w, word [r13] cmp r9w, r10w jne .no mov rsi, r13 add rsi, 2 mov rdi, r11 repz cmpsb jnz .no sub r13, 9 pspush r13 mov r13, true pspush r13 ret .no: mov r13, qword [r12] mov r12, r13 cmp r13, 0 ; end of dictionary? fallthrough to notfound if so jne .check_smudge mov r13, false pspush r13 ret ; stage 1 interpreter, just reads from initfile defword "interpret", interpret, 0 ret defvar ">in", to_in, 0, initfile defvar "latest", latest, 0, lfa_latest initfile: incbin "jefs.fs" initlen equ $ - initfile initfile_end: