summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm48
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 = $ - $$