evil
evil is a minimal language of the line-noise school. It was devised by Tom Wrensch in about 1999, while he was a graduate student at the University of Colorado.
Model
The evil computation model involves:
- The accumulator (A), a single unsigned byte
- The marking mode (M), a state bit specifying one of two options (standard or alternate)
- A pool of memory storing the source code (S)
- The wheel (W), a variable-sized circular list of unsigned bytes
- The pental (P), a wheel whose size is fixed at five
The source, wheel, and pental all have pointers pointing to an area inside them, called *S, *W, and *P. They wrap as necessary. The source pointer *S is the instruction pointer; program execution works by repeatedly executing the command it points to, and then incrementing it.
Commands in evil are lowercase letters. Uppercase letters are reserved for future library calls. Other characters are ignored. The program ends when the source pointer goes out of memory.
Two commands are marker characters. This means that they do nothing by themselves, but will be jumped to during certain commands, depending on the state of the marking mode. In standard marking mode, the commands b and f will jump to the first m command it finds. In alternate mode, this command is j.
Commands
Letter | Effect |
---|---|
a | Increments A. |
b | Scans backward to the first valid marker character for the mode. Sets *S to the position of that marker character. |
c | Inserts a new wheel cell before the current cell. Changes *W to point to the new cell. |
d | Deletes the currently pointed-to cell on the wheel. |
e | Applies the weave function to A. See below for more info. |
f | Scans forward to the first valid marker character. Sets *S to the position of that marker character. |
g | Sets A to the value inside the current Pental cell. |
h | Increments *P. |
i | Increments *W. |
j | Mark character for alternate marking mode. |
k | Sets the current Pental cell to A. |
l | Swaps A and the current wheel cell. |
m | Mark character for standard marking mode. |
n | Decrements *P. |
o | Decrements *W. |
p | Sets A to the value inside the current wheel cell. |
q | Swaps W and S, and swaps *W and *S. |
r | Reads a character from input and sets A to it. |
s | Skip next command if A is equal to 0. |
t | Skip next command if A is not equal to 0. |
u | Decrements A. |
v | Swaps A and the current Pental cell. |
w | Writes A to output, as a character. |
x | Swaps the mark state between standard and alternate mode. |
y | Sets the current wheel cell to A. |
z | Sets A to 0. |
Weaving
The weave operation is used to lower the amount of commands used to generate constants. It translates the 8 bits of input like so:
- Bit 0 is moved to bit 2
- Bit 1 is moved to bit 0
- Bit 2 is moved to bit 4
- Bit 3 is moved to bit 1
- Bit 4 is moved to bit 6
- Bit 5 is moved to bit 3
- Bit 6 is moved to bit 7
- Bit 7 is moved to bit 5
So, for example, weaving the number 10011101 will produce 01110110. Note that applying weave eight times in a row leaves the value unchanged.
Examples
Hello, world!
This hello world only uses the commands a, e, u, z, and w, and outputs the string "Hello, world!\r\n":
zaeeeaeeew (H) zaeeaeeaeaw (e) zuueeueueaw (l) zuueeueueaw (l) zuueeueew (o) zuueeaeeeaw (,) zaeeeeew ( ) zuueeueeeew (w) zuueeueew (o) zuueeueeaaaw (r) zuueeueueaw (l) zaeeaeeaew (d) zaeeeeeaw (!) zaeeuuuw (\r) zaeaaaaaaw (\n)
It constructs the ASCII values of the characters in the A register and writes them out using the w command. The z command zeros A, the a command increments A, the e command shuffles A's bit order from 76543210 to 64725031, and u decrements A.
Shorter Hello, world
zaeeeaeeew (H) uueeaw (e) aaaaaaaw (l) w (l) aaaw (o) eaaew (,) aeaaw ( ) uueeeeuw (w) ueeeeaw (o) aaaw (r) ueeuew (l) eeaw (d) uueueuw (!) eaw (\r) uuuw (\n)
Both programs are generated by the Python program here.
Quine
zuueeueeuuyk (store m to wheel and pental) ueeucy (b -> wheel) guuuucy (i -> wheel) gaaacy (p -> wheel) ueecy (w -> wheel) gaeeucy (f -> wheel) geeacy (t -> wheel) uuuucy (p -> wheel) gcy (m -> wheel) uuuucy (i -> wheel) gueecy (c -> wheel) guuuucy (i -> wheel) q (swap wheel and source)
The above quine writes the code to output all code in the wheel to the wheel, and then swaps the wheel and source code. The source code is now in the wheel, and the code to write the wheel is now the source code.
Constructing Constants
These snippets construct constants in A, using only the commands a, e, u, and z.
Generated by the Python program accessible here.
000 : z 001 : za 002 : zaa 003 : zaaa 004 : zae 005 : zaea 006 : zaeaa 007 : zaeaaa 008 : zaeaaaa 009 : zaeaaaaa 010 : zaeaaaaaa 011 : zaeeuuuuu 012 : zaeeuuuu 013 : zaeeuuu 014 : zaeeuu 015 : zaeeu 016 : zaee 017 : zaeea 018 : zaeeaa 019 : zaeaeu 020 : zaeae 021 : zaeaea 022 : zaeaeaa 023 : zaeeue 024 : zaeeuea 025 : zaeeueaa 026 : zaeeueaaa 027 : zaeeueaaaa 028 : zaeeeeaeae 029 : zaeeeeeuuu 030 : zaeeeeeuu 031 : zaeeeeeu 032 : zaeeeee 033 : zaeeeeea 034 : zaeeeeeaa 035 : zaeeeeaeu 036 : zaeeeeae 037 : zaeeeeaea 038 : zaeeeeaeaa 039 : zaeaeeeeeu 040 : zaeaeeeee 041 : zaeaeeeeea 042 : zuueeaeeeu 043 : zuueeaeee 044 : zuueeaeeea 045 : zuueeaeeeaa 046 : zaeeeaeeuu 047 : zaeeeaeeu 048 : zaeeeaee 049 : zaeeeaeea 050 : zaeeeaeeaa 051 : zaeeaeueeu 052 : zaeeaeuee 053 : zaeeaeueea 054 : zaeeaeeueu 055 : zaeeaeeue 056 : zaeeaeeuea 057 : zaeeaeeueaa 058 : zuueueeueu 059 : zuueueeue 060 : zaeeeuuuu 061 : zaeeeuuu 062 : zaeeeuu 063 : zaeeeu 064 : zaeee 065 : zaeeea 066 : zaeeeaa 067 : zaeeaeu 068 : zaeeae 069 : zaeaeue 070 : zaeaeuea 071 : zaeaeueaa 072 : zaeeeaeee 073 : zaeeeaeeea 074 : zaeeaeeueae 075 : zuueueeueue 076 : zaeeeaeeae 077 : zaeaeeuuu 078 : zaeaeeuu 079 : zaeaeeu 080 : zaeaee 081 : zaeaeea 082 : zaeaeeaa 083 : zaeaeaeu 084 : zaeaeae 085 : zaeeuee 086 : zaeeueea 087 : zaeeeeeue 088 : zaeeaeueee 089 : zaeeeuueuu 090 : zaeeeuueu 091 : zaeeeuue 092 : zaeeeuuea 093 : zaeeeueuu 094 : zaeeeueu 095 : zaeeeue 096 : zaeeeuea 097 : zaeeeueaa 098 : zaeeeueaaa 099 : zaeeaeeaeu 100 : zaeeaeeae 101 : zaeeaeeaea 102 : zaeeaeeaeaa 103 : zuueueeaeu 104 : zuueueeae 105 : zuueueeaea 106 : zuueeueueu 107 : zuueeueue 108 : zuueeueuea 109 : zuueeueeuu 110 : zuueeueeu 111 : zuueeuee 112 : zuueeueea 113 : zuueeueeaa 114 : zuueeueeaaa 115 : zaeaeeueeuu 116 : zaeaeeueeu 117 : zaeaeeuee 118 : zaeaeeueea 119 : zuueeueeee 120 : zuueeueeeea 121 : zuueeeueuu 122 : zuueeeueu 123 : zuueeeue 124 : zuueeeuea 125 : zaeeeeuuu 126 : zaeeeeuu 127 : zaeeeeu 128 : zaeeee 129 : zaeeeea 130 : zaeeeeaa 131 : zaeeeaeu 132 : zaeeeae 133 : zaeeaeue 134 : zaeeaeuea 135 : zaeeaeueaa 136 : zaeeeueae 137 : zaeeeueaea 138 : zuueueeaee 139 : zuueeueueue 140 : zaeeeueaae 141 : zaeeaeeuuu 142 : zaeeaeeuu 143 : zaeeaeeu 144 : zaeeaee 145 : zaeeaeea 146 : zaeeaeeaa 147 : zaeaeeuue 148 : zaeaeuee 149 : zaeaeueea 150 : zaeaeeueu 151 : zaeaeeue 152 : zaeaeeuea 153 : zaeaeeueaa 154 : zuueeueueae 155 : zuueeueeue 156 : zaeeaeeaeae 157 : zuueueeaeue 158 : zuueeueeeu 159 : zuueeueee 160 : zaeaeeee 161 : zaeaeeeea 162 : zaeaeeeeaa 163 : zaeaeeeaeu 164 : zaeaeeeae 165 : zaeaeeeaea 166 : zaeaeeeaeaa 167 : zuueeaeeuuu 168 : zuueeaeeuu 169 : zuueeaeeu 170 : zuueeaee 171 : zuueueue 172 : zuueueuea 173 : zuueueeuu 174 : zuueueeu 175 : zuueuee 176 : zuueueea 177 : zuueueeaa 178 : zuueueeaaa 179 : zuueueeaaaa 180 : zaeaeaeuee 181 : zaeeeuueee 182 : zaeeeuueeea 183 : zuueeeueee 184 : zuueeueuuu 185 : zuueeueuu 186 : zuueeueu 187 : zuueeue 188 : zuueeuea 189 : zuueeeuu 190 : zuueeeu 191 : zuueee 192 : zaeaeee 193 : zaeaeeea 194 : zaeaeeeaa 195 : zaeaeeaeu 196 : zaeaeeae 197 : zaeaeaeue 198 : zaeaeaeuea 199 : zaeeeuuee 200 : zuueeueeae 201 : zuueeueeaea 202 : zuueeeueueu 203 : zuueeeueue 204 : zuueeueeaae 205 : zuueeeueeuu 206 : zuueeeueeu 207 : zuueeeuee 208 : zaeaeaee 209 : zaeeueeae 210 : zaeeeuueae 211 : zaeeeueue 212 : zaeeueee 213 : zaeeueeea 214 : zaeeeueeu 215 : zaeeeuee 216 : zaeeeueea 217 : zaeeeueeaa 218 : zuueeeueae 219 : zaeeeeuue 220 : zaeaeeueee 221 : zaeeeeueuu 222 : zaeeeeueu 223 : zaeeeeue 224 : zaeaeaeee 225 : zaeaeaeeea 226 : zaeeeueeae 227 : zuueeeueaee 228 : zaeeueeaee 229 : zaeeeueuee 230 : zuueeaeuu 231 : zuueeaeu 232 : zuueeae 233 : zuueeaea 234 : zuueueu 235 : zuueue 236 : zuueuea 237 : zuueeuu 238 : zuueeu 239 : zuuee 240 : zuueea 241 : zuueeaa 242 : zuueeaaa 243 : zuueeaaaa 244 : zaeeueeeae 245 : zaeeeueee 246 : zuueuuuuu 247 : zuueuuuu 248 : zuueuuu 249 : zuueuu 250 : zuueu 251 : zuue 252 : zuuea 253 : zuuu 254 : zuu 255 : zu
External resources
- The GitHub repository for a collection of esoteric interpreters, including evil. (dead link)
- The evil home page (from the Wayback Machine; retrieved on 3 January 2007)
- Version 0.2 evil interpreter (from the Wayback Machine; retrieved on 6 September 2007)
- The evil programming language specification (from the Wayback Machine; retrieved on 28 November 2006)