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 | ||
2d2ef3fe | 20 | and contains the `MARK label0` command (i.e. `NSSSTSTTTSN`) used in the next |
4dc56bba | 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 | |
4dc56bba | 46 | whitespacers/ruby: (c) 2003 by Wayne E. Conrad |
4dc56bba | 47 | whitespacers/perl: (c) 2003 Micheal Koelbl |
4dc56bba | 48 | threeifbywhiskey/satan |
eaba0660 | 49 | |
3e731818 | 50 | Both of these methods can be broken using valid Whitespace code: |
eaba0660 | 51 | |
2d2ef3fe | 52 | * **Type A**: No 'standalone' label exists. This breaks Method 2. |
eaba0660 | 53 | |
e5ba12f2 | 54 | By programmer's intent, this should print a `!` before infinite `.` lines. |
eaba0660 | 55 | |
2d2ef3fe | 56 | * **Type B**: Hidden label before 'standalone' label. This breaks Method 1. |
eaba0660 | 57 | |
e5ba12f2 | 58 | By programmer's intent, this should print an infinite chain of `.` lines. |
eaba0660 | 59 | |
3e731818 | 60 | This is the Type A program: |
eaba0660 | 61 | |
2d2ef3fe AT |
62 | SSSTSSSSTN | Push +33 (ASCII '!') |
63 | NSNSTSTTTSN | JMP > 0101110 (label0) | |
64 | NSSTTTTN | MARK: 1111 (label2) | |
65 | SSSSN | PUSH 0 | |
eaba0660 | 66 | SNN | DROP |
2d2ef3fe | 67 | SSSTSTTTSN | Push +46 (ASCII '.') |
eaba0660 | 68 | TNSS | Output character |
2d2ef3fe | 69 | SSSTSTSN | Push +10 (ASCII '\n') |
eaba0660 | 70 | TNSS | Output character |
2d2ef3fe | 71 | NSNTTTTN | JMP > 1111 (label2) |
eaba0660 | 72 | |
3e731818 | 73 | Append this to turn it into the Type B program: |
eaba0660 | 74 | |
2d2ef3fe AT |
75 | NSSSTSTTTSN | MARK: 0101110 (label0) (2nd time) |
76 | NSNTTTTN | JMP > 1111 (label2) | |
eaba0660 | 77 | |
3e731818 AT |
78 | VVhitespace avoids this ambiguity by marking label definitions with a vertical |
79 | tab `[VTab]` immediately before the label. | |
80 | ||
81 | Old label: NSS TSTS N | |
82 | New label: NSSV TSTS N | |
83 | ||
84 | Since Whitespace ignores [VTab] as a comment character, and since the | |
85 | Whitespace VM is a superset of the VVhitespace VM, all valid VVhitespace | |
86 | programs are also valid Whitespace programs, though the task of locating a | |
87 | suitable Whitespace interpreter is left for the reader. | |
88 | ||
89 | -------------------------------------------------------------------------------- | |
90 | ||
91 | Quoting from the original Whitespace tutorial which I used as language reference: | |
92 | ||
93 | The programmer is free to push arbitrary width integers onto the stack. | |
94 | ||
95 | I have yet to find a Whitespace interpreter which successfully implements that | |
96 | statement. | |
97 | ||
98 | Since I wanted to implement bitwise logic functions, this broad definition | |
99 | posed a problem. For example, how many `1`s should be in the output of the | |
100 | expression `NOT(0)`? Should the expression `NOT(0) == NOT(0)` always be true? | |
eaba0660 | 101 | |
3e731818 | 102 | VVhitespace sidesteps the problem by declaring all integers to be 64-bits wide. |
eaba0660 | 103 |