Commit | Line | Data |
---|---|---|
3e731818 AT |
1 | While considering methods for further obfuscating Whitespace code, I realized |
2 | that the Whitespace language reference didn't enforce any particular alignment | |
3 | or grouping for code execution. In theory this means one could create a | |
4 | sequence of Whitespace trits which represents different sequences of commands | |
5 | depending on exactly where execution begins. | |
cbbb46ce | 6 | |
3e731818 AT |
7 | One implementation of this idea is the creation of a 'hidden' label. For |
8 | example, the command sequence | |
cbbb46ce | 9 | |
3e731818 AT |
10 | PUSH 0; DROP; PUSH 46 |
11 | ||
12 | assembles as | |
13 | ||
14 | SSSSN SNN SSSTSTTTSN | |
eaba0660 | 15 | |
3e731818 | 16 | which can be visually regrouped as |
eaba0660 | 17 | |
3e731818 AT |
18 | SSSSNSN NSSSTSTTTSN |
19 | ||
20 | and contains the `MARK label0` command used in the next set of examples. | |
21 | ||
22 | Additionally, since `PUSH 0; DROP` is effectively a `NOP`, 'hijacking' the code | |
23 | at this location allows one to insert their own integer on the stack in place | |
24 | of the `PUSH 46` command, sneakily substituting it as an input to any | |
25 | downstream processing. | |
26 | ||
27 | I decided to investigate the behavior of specific Whitespace interpreters, | |
28 | discovering that they broke down into two methods for locating labels. | |
eaba0660 AT |
29 | |
30 | * **Method 1** Scan from the start of the file for the first occurence of the | |
31 | mark-label bytestring and jump. | |
3e731818 AT |
32 | |
33 | Example: whitespacers/c: (c) meth0dz | |
eaba0660 AT |
34 | |
35 | * **Method 2** Scan from the start of the file, looking for a mark-label | |
36 | bytestring, but 'parsing' one bytestring at a time, and jumping to the | |
37 | first 'standalone' mark-label bytestring. Note that this is different than | |
38 | executing the program, particularly when user-input commands are present. | |
3e731818 AT |
39 | |
40 | Example: whitespacers/haskell: (c) 2003 Edwin Brady | |
41 | whitespacers/ruby: (c) 2003 by Wayne E. Conrad | |
42 | whitespacers/perl: (c) 2003 Micheal Koelbl | |
43 | threeifbywhiskey/satan | |
eaba0660 | 44 | |
3e731818 | 45 | Both of these methods can be broken using valid Whitespace code: |
eaba0660 | 46 | |
3e731818 | 47 | * Type A: No 'standalone' label exists. This breaks Method 2. |
eaba0660 | 48 | |
3e731818 | 49 | By programmer's intent, this should print a '!' before infinite '.' lines. |
eaba0660 | 50 | |
3e731818 | 51 | * Type B: Hidden label before 'standalone' label. This breaks Method 1. |
eaba0660 | 52 | |
3e731818 | 53 | By programmer's intent, this should print an infinite chain of '.' lines. |
eaba0660 | 54 | |
3e731818 | 55 | This is the Type A program: |
eaba0660 AT |
56 | |
57 | SSSTSSSSTN | Push +33 (ASCII !) | |
58 | NSNSTSTTTSN | JMP>label0 | |
59 | NSSTTTTN | MARK label2 | |
60 | SSSSN | PUSH +0 | |
61 | SNN | DROP | |
62 | SSSTSTTTSN | Push +46 (ASCII .) | |
63 | TNSS | Output character | |
64 | SSSTSTSN | Push +10 (ASCII newline) | |
65 | TNSS | Output character | |
66 | NSNTTTTN | JMP>label2 | |
67 | ||
3e731818 | 68 | Append this to turn it into the Type B program: |
eaba0660 AT |
69 | |
70 | NSSSTSTTTSN | MARK label0 (2nd time) | |
71 | NSNTTTTN | JMP>label2 | |
72 | ||
3e731818 AT |
73 | VVhitespace avoids this ambiguity by marking label definitions with a vertical |
74 | tab `[VTab]` immediately before the label. | |
75 | ||
76 | Old label: NSS TSTS N | |
77 | New label: NSSV TSTS N | |
78 | ||
79 | Since Whitespace ignores [VTab] as a comment character, and since the | |
80 | Whitespace VM is a superset of the VVhitespace VM, all valid VVhitespace | |
81 | programs are also valid Whitespace programs, though the task of locating a | |
82 | suitable Whitespace interpreter is left for the reader. | |
83 | ||
84 | -------------------------------------------------------------------------------- | |
85 | ||
86 | Quoting from the original Whitespace tutorial which I used as language reference: | |
87 | ||
88 | The programmer is free to push arbitrary width integers onto the stack. | |
89 | ||
90 | I have yet to find a Whitespace interpreter which successfully implements that | |
91 | statement. | |
92 | ||
93 | Since I wanted to implement bitwise logic functions, this broad definition | |
94 | posed a problem. For example, how many `1`s should be in the output of the | |
95 | expression `NOT(0)`? Should the expression `NOT(0) == NOT(0)` always be true? | |
eaba0660 | 96 | |
3e731818 | 97 | VVhitespace sidesteps the problem by declaring all integers to be 64-bits wide. |
eaba0660 | 98 |