X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=main.asm;h=cbf8a139d6e4df42f6cfc6ab17b432b39a0efbe3;hb=623eb650651ba4105e4e91239c52b04ed0e5cd85;hp=edcba0ae9421c712218041e64d4fc0872370f8d9;hpb=2d2c007e5b5e2f9b79271d638863d77338969f38;p=rrq%2Fjonasforth.git diff --git a/main.asm b/main.asm index edcba0a..cbf8a13 100644 --- a/main.asm +++ b/main.asm @@ -242,15 +242,55 @@ forth HELLO, 'HELLO' dq NEWLINE dq EXIT +;; Duplicate a pair of elements. +forth_asm PAIRDUP, '2DUP' + pop rbx + pop rax + push rax + push rbx + push rax + push rbx + next + +;; Swap the top two elements on the stack. +forth_asm SWAP, 'SWAP' + pop rax + pop rbx + push rax + push rbx + next + +;; Remove the top element from the stack. +forth_asm DROP, 'DROP' + add rsp, 8 + next + ;; The INTERPRET word reads and interprets user input. It's behavior depends on ;; the current STATE. It provides special handling for integers. (TODO) forth INTERPRET, 'INTERPRET' + ;; Read word dq READ_WORD - dq FIND + dq PAIRDUP + ;; Stack is (word length word length). + dq FIND ; Try to find word + dq DUP_ + dq ZBRANCH, 8 * 8 ; Check if word is found + + ;; Word is found, execute it dq TCFA + ;; Stack is (word length addr) + dq SWAP, DROP + dq SWAP, DROP + ;; Stack is (addr) dq EXEC dq EXIT + ;; No word is found, assume it is an integer literal + ;; Stack is (word length addr) + dq DROP + dq PARSE_NUMBER + dq EXIT + ;; .U prints the value on the stack as an unsigned integer in hexadecimal. forth_asm DOTU, '.U' mov [.length], 0 @@ -332,6 +372,19 @@ forth STATE, 'STATE' dq LIT, var_STATE dq EXIT +;; Get the location of the LATEST variable. It can be set with '!' and read with +;; '@'. +forth LATEST, 'LATEST' + dq LIT, latest_entry + dq EXIT + +;; Get the location at which compiled words are expected to be added. This +;; pointer is usually modified automatically when calling ',', but we can also +;; read it manually with 'HERE'. +forth HERE, 'HERE' + dq LIT, here + dq EXIT + forth MAIN, 'MAIN' dq HELLO dq INTERPRET @@ -340,6 +393,9 @@ forth MAIN, 'MAIN' segment readable writable +;; The LATEST variable holds a pointer to the word that was last added to the +;; dictionary. This pointer is updated as new words are added, and its value is +;; used by FIND to look up words. latest_entry dq initial_latest_entry ;; The STATE variable is 0 when the interpreter is executing, and non-zero when @@ -357,6 +413,10 @@ DOTU.rbuffer rq 16 DOTU.length dq ? DOTU.printed_length dq ? +;; Reserve space for compiled words, accessed through HERE. +here dq here_top +here_top rq $2000 + ;; Return stack rq $2000 return_stack_top: