summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--quine.asm296
1 files changed, 291 insertions, 5 deletions
diff --git a/quine.asm b/quine.asm
index 3663dde..d588b1c 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2000,10 +2000,288 @@ cold_start:
   ; store, but the only thing early_variable is doing is returning an
   ; address.)
 
+  ;   Now we define a bunch of ordinary Forth words. Since we'll only ever be
+  ; calling these copies from within Forth, we're no longer limited by
+  ; flatassembler's syntax, so a lot of them have slightly different names
+  ; than they've had up to now. This will be noted below.
+
   dq litstring, "exit", early_create, early_self_codeword, early_here, fetch
   dq rsi, pack_popcontrol, pack_next
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "swap", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "drop", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "drop2".
+  dq litstring, "2drop", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "roll", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; Jonesforth calls this "-roll" and we could do that, but honestly the name
+  ; unroll sounds nicer and it's only a single character longer. You might say
+  ; it rolls off the tongue better.
+  dq litstring, "unroll", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "roll3".
+  dq litstring, "3roll", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "unroll3".
+  dq litstring, "3unroll", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "dup", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "dup2".
+  dq litstring, "2dup", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "add".
+  dq litstring, "+", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "sub".
+  dq litstring, "-", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "mul".
+  dq litstring, "*", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "divmod". Jonesforth calls it "/mod" but % is widely recognized
+  ; and has no special Forth significance.
+  dq litstring, "/%", early_create, early_self_codeword, early_here, fetch
+  ; TODO
   dq lit, 8, packalign, early_here_store
 
+  ; This was "eq". Jonesforth calls it "="; most languages would call it "==".
+  dq litstring, "=", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "ne". Jonesforth calls it "<>", but even most modern SQL dialects
+  ; recognize C's legacy and allow "!=" these days. As someone who learned C
+  ; in childhood, this is not actually a hard call for us.
+  dq litstring, "!=", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "gt".
+  dq litstring, ">", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "lt".
+  dq litstring, "<", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "ge".
+  dq litstring, ">=", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "le".
+  dq litstring, "<=", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "and", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "or", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "xor", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "invert", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "lit", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "litstring", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This is "store", but since we're finally in Forth we're no longer limited
+  ; by flatassembler's syntax, so we call it by its usual Forth name.
+  dq litstring, "!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This is "fetch".
+  dq litstring, "@", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This is "addstore".
+  dq litstring, "+!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This is "substore".
+  dq litstring, "-!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "store8". Jonesforth calls it "c!" but we categorically reject
+  ; the use of letters that are meant to indicate byte sizes. It's unfriendly
+  ; to newcomers. There's some risk that this name will be confused for
+  ; meaning "store a value of 8", but that would not be a useful task, so
+  ; hopefully it'll be okay.
+  dq litstring, "8!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "fetch8".
+  dq litstring, "8@", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "store16".
+  dq litstring, "16!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "fetch16".
+  dq litstring, "16@", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "store32".
+  dq litstring, "32!", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "fetch32".
+  dq litstring, "32@", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "memcopy", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; TODO why does this crash?
+  ;dq litstring, "stringlen", early_create, early_self_codeword, early_here
+  ;dq fetch
+  ; TODO
+  ;dq lit, 8, packalign, early_here_store
+
+  dq litstring, "branch", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; This was "zbranch".
+  dq litstring, "0branch", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; TODO why does this crash?
+  ;dq litstring, "sys_exit", early_create, early_self_codeword, early_here
+  ;dq fetch
+  ; TODO
+  ;dq lit, 8, packalign, early_here_store
+
+  dq litstring, "sys_write", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "emitstring", early_create, early_self_codeword, early_here
+  ; TODO this is actually in Forth
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "crash", early_create, early_self_codeword, early_here, fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; We could in theory call this 64pack, by analogy to 32! and so on, but it's
+  ; kept like this to be more similar to reg64, imm64 etc.
+  ;
+  ; Also, unlike with ! we specify the size even for the 64-bit version,
+  ; because the user of pack64 and its variants is always doing something
+  ; where exact byte sizes are crucial.
+  dq litstring, "pack64", early_create, early_self_codeword, early_here, fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "pack32", early_create, early_self_codeword, early_here, fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "pack16", early_create, early_self_codeword, early_here, fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "pack8", early_create, early_self_codeword, early_here, fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "packstring", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "packalign", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO this is actually in Forth
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "litpack64", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "litpack32", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  dq litstring, "litpack16", early_create, early_self_codeword, early_here
+  dq fetch
+  ; TODO
+  dq lit, 8, packalign, early_here_store
+
+  ; TODO why does this crash?
+  ;dq litstring, "litpack8", early_create, early_self_codeword, early_here
+  ;dq fetch
+  ; TODO
+  ;dq lit, 8, packalign, early_here_store
+
   ;;; For triage's sake, here's an inventory of everything else in the file.
   ;;;
   ;;; Macros:
@@ -2020,7 +2298,7 @@ cold_start:
   ;;;   lit, litstring
   ;;;   store, fetch
   ;;;   addstore, substore, store8, fetch8, store16, fetch16, store32, fetch32
-  ;;;   ccopy, stringlen
+  ;;;   memcopy, stringlen
   ;;;     no dependencies except next for any of these
   ;;;   branch, zbranch
   ;;;     sorta needs a label but might be avoidable
@@ -2688,17 +2966,25 @@ defword fetch32, 0
 ; logic, see roll and unroll. This always copies at byte granularity, for ease
 ; of implementation.
 ;
-;   Jonesforth calls this CMOVE and has a ccopy which is a single byte. POSIX,
+;   Jonesforth calls this CMOVE and has a CCOPY which is a single byte. POSIX,
 ; however, has memcpy() for non-overlapping blocks and memmove() for
 ; overlapping blocks. We follow the latter convention, because it feels like
 ; the more important distinction.
 ;
+;   Also, the "c" was meant to indicate that it works at one-byte granularity,
+; but that isn't, uh... actually an important property here, and as a blanket
+; call we're not using letters to denote data sizes. So we call it "memcopy".
+; Apologies to C programmers but vowels are good, actually.
+;
+;   Jonesforth also offers C@C! as another name for its CCOPY, but neither
+; "@!" nor "mem@mem!" seems particulaly nice.
+;
 ; Stack in:
 ;   destination
 ;   source
 ;   length
 ; (top)
-defword ccopy, 0
+defword memcopy, 0
   dq $ + 8
   ; We need to save and restore rsi; the other registers we can trample.
   mov.qreg.qreg rdx, rsi
@@ -2877,7 +3163,7 @@ defword packstring, 0
   ; destination, source, length, length, base/destination
   dq add, lit, 4, unroll
   ; new base, destination, source, length
-  dq ccopy
+  dq memcopy
   dq exit
 
 ; Stack in:
@@ -4334,7 +4620,7 @@ defword self_raw, 0
   ; destination destination source length
   dq dup, lit, 4, roll, add, lit, 4, unroll
   ; result destination source length
-  dq ccopy
+  dq memcopy
   dq exit