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