X-Git-Url: http://git.subgeniuskitty.com/vvhitespace/.git/blobdiff_plain/fc2c8ac7f0f21c0a93123424b1ef09cc53574b63..83a8624eade3d2b481d4e780357f12a02206a6d7:/rationale.md diff --git a/rationale.md b/rationale.md index b19f462..c847fab 100644 --- a/rationale.md +++ b/rationale.md @@ -1,60 +1,103 @@ -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 + +which can be visually regrouped as + + SSSSNSN NSSSTSTTTSN -TODO: Finish this up based on what I've found below. +and contains the `MARK label0` command (i.e. `NSSSTSTTTSN`) used in the next +set of examples. -It seems that all (most?) WS interpreters locate labels using one of two methods. +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. + + Examples: + + 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. + + Examples: + + 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 - NSSTTTTN | MARK label2 - SSSSN | PUSH +0 + SSSTSSSSTN | Push +33 (ASCII '!') + NSNSTSTTTSN | JMP > 0101110 (label0) + NSSTTTTN | MARK: 1111 (label2) + SSSSN | PUSH 0 SNN | DROP - SSSTSTTTSN | Push +46 (ASCII .) + SSSTSTTTSN | Push +46 (ASCII '.') TNSS | Output character - SSSTSTSN | Push +10 (ASCII newline) + SSSTSTSN | Push +10 (ASCII '\n') TNSS | Output character - NSNTTTTN | JMP>label2 + NSNTTTTN | JMP > 1111 (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: 0101110 (label0) (2nd time) + NSNTTTTN | JMP > 1111 (label2) -WS Interpreter Evaluations: +VVhitespace avoids this ambiguity by marking label definitions with a vertical +tab `[VTab]` immediately before the label. - Method 1: - whitespacers/c: (c) meth0dz + 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? + +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