Updated `rationale.md`, expanding previous notes.
authorAaron Taylor <ataylor@subgeniuskitty.com>
Fri, 13 Mar 2020 09:12:33 +0000 (02:12 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Fri, 13 Mar 2020 09:12:33 +0000 (02:12 -0700)
rationale.md

index b19f462..2499caa 100644 (file)
@@ -1,36 +1,58 @@
-VVhitespace is descended from Whitespace, adding a vertical tab to the language
-along with some restrictions to ease implementation. The name is intended to
-embrace the spirit of Whitespace's visual incomprehensibility.
+While considering methods for further obfuscating Whitespace code, I realized
+that the Whitespace language reference didn't enforce any particular alignment
+or grouping for code execution. In theory this means one could create a
+sequence of Whitespace trits which represents different sequences of commands
+depending on exactly where execution begins.
 
 
-Since Whitespace ignores [VTab] as a comment character, and since the
-Whitespace VM is a superset of the VVhitespace VM, all valid VVhitespace
-programs are also valid Whitespace programs.
+One implementation of this idea is the creation of a 'hidden' label. For
+example, the command sequence
 
 
---------------------------------------------------------------------------------
+    PUSH 0; DROP; PUSH 46
+
+assembles as
+
+    SSSSN SNN SSSTSTTTSN
 
 
-TODO: Finish this up based on what I've found below.
+which can be visually regrouped as
 
 
-It seems that all (most?) WS interpreters locate labels using one of two methods.
+    SSSSNSN NSSSTSTTTSN
+
+and contains the `MARK label0` command used in the next set of examples.
+
+Additionally, since `PUSH 0; DROP` is effectively a `NOP`, 'hijacking' the code
+at this location allows one to insert their own integer on the stack in place
+of the `PUSH 46` command, sneakily substituting it as an input to any
+downstream processing.
+
+I decided to investigate the behavior of specific Whitespace interpreters,
+discovering that they broke down into two methods for locating labels.
 
   * **Method 1** Scan from the start of the file for the first occurence of the
     mark-label bytestring and jump.
 
   * **Method 1** Scan from the start of the file for the first occurence of the
     mark-label bytestring and jump.
+    
+    Example:  whitespacers/c: (c) meth0dz
 
   * **Method 2** Scan from the start of the file, looking for a mark-label
     bytestring, but 'parsing' one bytestring at a time, and jumping to the
     first 'standalone' mark-label bytestring. Note that this is different than
     executing the program, particularly when user-input commands are present.
 
   * **Method 2** Scan from the start of the file, looking for a mark-label
     bytestring, but 'parsing' one bytestring at a time, and jumping to the
     first 'standalone' mark-label bytestring. Note that this is different than
     executing the program, particularly when user-input commands are present.
+    
+    Example: whitespacers/haskell: (c) 2003 Edwin Brady
+             whitespacers/ruby: (c) 2003 by Wayne E. Conrad
+             whitespacers/perl: (c) 2003 Micheal Koelbl
+             threeifbywhiskey/satan
 
 
-Both of these methods can be broken:
+Both of these methods can be broken using valid Whitespace code:
 
 
-  * Type 1: No 'standalone' label exists. This breaks Method 2.
+  * Type A: No 'standalone' label exists. This breaks Method 2.
 
 
-    This should print a '!' before infinite '.' lines.
+    By programmer's intent, this should print a '!' before infinite '.' lines.
 
 
-  * Type 2: Hidden label before 'standalone' label. This breaks Method 1.
+  * Type B: Hidden label before 'standalone' label. This breaks Method 1.
 
 
-    This should print an infinite chain of '.' lines.
+    By programmer's intent, this should print an infinite chain of '.' lines.
 
 
-This is the Type 1 program:
+This is the Type A program:
 
     SSSTSSSSTN  | Push +33 (ASCII !)
     NSNSTSTTTSN | JMP>label0
 
     SSSTSSSSTN  | Push +33 (ASCII !)
     NSNSTSTTTSN | JMP>label0
@@ -43,18 +65,34 @@ This is the Type 1 program:
     TNSS        | Output character
     NSNTTTTN    | JMP>label2
 
     TNSS        | Output character
     NSNTTTTN    | JMP>label2
 
-Append this to turn it into the Type 2 program:
+Append this to turn it into the Type B program:
 
     NSSSTSTTTSN | MARK label0 (2nd time)
     NSNTTTTN    | JMP>label2
 
 
     NSSSTSTTTSN | MARK label0 (2nd time)
     NSNTTTTN    | JMP>label2
 
-WS Interpreter Evaluations:
+VVhitespace avoids this ambiguity by marking label definitions with a vertical
+tab `[VTab]` immediately before the label.
+
+    Old label: NSS  TSTS N
+    New label: NSSV TSTS N
+
+Since Whitespace ignores [VTab] as a comment character, and since the
+Whitespace VM is a superset of the VVhitespace VM, all valid VVhitespace
+programs are also valid Whitespace programs, though the task of locating a
+suitable Whitespace interpreter is left for the reader.
+
+--------------------------------------------------------------------------------
+
+Quoting from the original Whitespace tutorial which I used as language reference:
+
+    The programmer is free to push arbitrary width integers onto the stack.
+
+I have yet to find a Whitespace interpreter which successfully implements that
+statement.
+
+Since I wanted to implement bitwise logic functions, this broad definition
+posed a problem. For example, how many `1`s should be in the output of the
+expression `NOT(0)`? Should the expression `NOT(0) == NOT(0)` always be true?
 
 
-    Method 1:
-        whitespacers/c: (c) meth0dz
+VVhitespace sidesteps the problem by declaring all integers to be 64-bits wide.
 
 
-    Method 2:
-        whitespacers/ruby: (c) 2003 by Wayne E. Conrad
-        whitespacers/perl: (c) 2003 Micheal Koelbl
-        whitespacers/haskell: (c) 2003 Edwin Brady
-        threeifbywhiskey/satan