diff options
| author | Irene Knapp <ireneista@irenes.space> | 2025-11-28 01:21:59 -0800 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2025-11-28 01:21:59 -0800 |
| commit | ca5b491cc10e6f599598839e33d2235ccc81991c (patch) | |
| tree | 79d92713ebc9092a1a4ad257d402c8a534fb2bb8 | |
| parent | e85b9d90978705054991cfb67c975d9856813a21 (diff) | |
implement looking up words by name (wow!)
also, fix strlen to not include the null byte Force-Push: yes Change-Id: Ifd95da1fc0cf7006df0a25278e03651d6185f037
| -rw-r--r-- | quine.asm | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/quine.asm b/quine.asm index 8b21819..ff2ab50 100644 --- a/quine.asm +++ b/quine.asm @@ -3206,7 +3206,7 @@ defword memcopy, 0 ; Stack in: ; string address ; Stack out: -; string length including null byte +; string length not including null byte defword stringlen, 0 dq $ + 8 pop.qreg rdi @@ -3216,6 +3216,7 @@ defword stringlen, 0 not.qreg rcx repnz scasb sub.qreg.qreg rdi, rbx + sub.qreg.bimm rdi, 1 push.qreg rdi next @@ -3517,7 +3518,7 @@ defword pack8, 0 ; new base address defword packstring, 0 dq docol - dq dup, stringlen, dup + dq dup, stringlen, lit, 1, add, dup ; base/destination, source, length, length dq lit, 4, roll, dup, lit, 5, unroll ; destination, source, length, length, base/destination @@ -4685,6 +4686,47 @@ defword early_latest, 0 defword early_here, 0 dq docol, early_heap, lit, 32, add, exit +; Stack in: +; heap address +; name string to find +; Stack out: +; heap address +; execution token or 0 +defword early_find, 0 + dq docol, swap, early_latest, fetch, swap, unroll3, swap, find_in, exit + +; Stack in: +; dictionary to search within +; name string to find +; Stack out: +; execution token or 0 +defword find_in, 0 + dq docol + ; It will be more convenient to have the dictionary pointer on top. + dq swap + ; If the dictionary pointer is null, exit. + dq dup, lit, 0, eq, zbranch, 4*8, swap, drop, exit + ; Test whether this entry is a match. + dq dup2, lit, 10, add, stringcmp, zbranch, 4*8 + ; If we're here, it's not a match; traverse the pointer and repeat. + dq fetch, branch, -18*8 + ; If we're here, it's a match. Clean up our working state and exit. + dq swap, drop, exit + +; Jonesforth calls this "TFCA" and ">CFA"; its author speculates that the +; original meaning is "code field address". +defword entry_to_execution_token, 0 + dq docol + ; Skip next-entry pointer, flag byte, and start terminator. + dq lit, 10, add + ; Skip string contents. + dq dup, stringlen, add + ; Skip one for the null terminator, seven more for alignment. + dq lit, 8, add + ; Zero the low bits and now it's aligned. + dq lit, 7, invert, and + dq exit + ; Allocate space by incrementing "here", and output a word header in it. ; Also add it to the "latest" linked list. Use zero as the flag values; ; callers that want something else can do that themselves. @@ -5113,7 +5155,7 @@ defword self_raw, 0 dq exit -final_word_name = self_raw +final_word_name = latest_word code_size = $ - code_start file_size = $ - $$ |