; sanctuary ; macros {{{ ; TODO: error handling (once i add that) %macro pspush 1 lea r14, [r14-8] mov qword [r14], r15 mov r15, %1 %endmacro %macro pspop 1 mov %1, r15 mov r15, qword [r14] lea r14, [r14+8] %endmacro %macro psdrop 0 lea r14, [r14+8] %endmacro %define s_latest 0 %macro defdict 3 ; name label flags %strlen slen %1 global lfa_%2 lfa_%2: dq s_latest %define s_latest lfa_%2 ffa_%2: db %3 nfa_%2: db slen db %1 %endmacro %macro defcode 3 defdict %1, %2, %3 %2: %endmacro ; this is just taken from jewelforth, and does not correspond ; to how user variables are planned to work in sanctuary ; so todo make better later? i don't know if it really matters ; because it will only apply to builtin variables. %macro defvar 4 %2: dq %4 defdict %1, %2, %3 pspush qword %2 %endmacro ; }}} %assign INTERPRET 0x0 %assign COMPILING (~0x1) %assign __NR_mprotect 10 %assign __NR_brk 12 %assign __NR_exit 60 section .bss resq 4091 wstk: resq 1 section .text global _start _start: lea r14, [wstk + 8] call brk@ mov qword [dp], r15 mov qword [dp0], r15 mov r15, 0x9c400 call grow call bye defcode "brk@", brk@, 0 xor rdi, rdi mov rax, __NR_brk syscall pspush rax ret defcode "grow", grow, 0 call brk@ pspop rdi pspop r13 add rdi, r13 mov rax, __NR_brk syscall mov qword [dp$], rax ret defcode "executable", executable, 0 mov rdx, 0x7 ; PROT_{READ,WRITE,EXEC} pspop rdi ; addr pspop rsi mov rax, __NR_mprotect syscall ret defcode "here", here, 0 pspush qword [dp] ret defcode "bye", bye, 0 mov rdi, 0 mov rax, __NR_exit syscall ret defvar "state", state, 0, INTERPRET defvar "dp", dp, 0, 0 defvar "dp0", dp0, 0, 0 defvar "dp$", dp$, 0, 0 defvar "tib", tib, 0, 0 ; todo set correct initial value defvar "#tib", n_tib, 0, 0 ; todo set correct initial value defvar ">in", to_in, 0, 0 defvar "latest", latest, 0, lfa_latest