BF176
BF176 is the smallest full-feature brainf**k interpreter within an html document. The entire file takes up only 176 bytes.Overview & Source
From Wikipedia:
(Brainf**k) is an esoteric programming language created in 1993 by Urban Müller.
Notable for its extreme minimalism, the language consists of only eight simple commands, a data pointer and an instruction pointer. While it is fully Turing complete, it is not intended for practical use, but to challenge and amuse programmers. Brainfuck requires one to break commands into microscopic steps.
Upon loading, the document will take an input for your BF code and interpret it, printing any output in the HTML document.
The BF language accepts the following characters: > < + - , . [ ]
The following is the source of BF176:
<svg/onload="eval((p=prompt)().replace(a=/./g,d=>'c++0c--0x=-~x0x=~-x0document.write(`${x};`)0x=p()0whilex{0}'.split`x`.join`(a[c])`.split(c=0)['><+-.,[]'.indexOf(d)]+';'))">
Explanation
<svg/onload=""> This is a fairly straightforward way to execute JS. It is most often used as an XSS payload, but can also save 2 bytes over a traditional <script> tag. eval() Allows the script to execute the JS code that has been generated as a string. (p=prompt)() Requests an input for the BF code and will use new "p" shorthand (prompt method) later in the code to request user input if called in the BF script. replace(a=/./g,d=>) Replaces each character of BF code according to the code that follows. /./g matches all characters in regex, and d=> will define variable d as the character to be used in the function that follows. 'c++0c--0x=-~x0x=~-x0document.write(`${x};`)0x=p()0whilex{0}' Defines each line of JS that will replace its BF counterpart. 0 is the character which will later be used to split each JS line.
- c++ increments the pointer
- c-- decrements the pointer
- x=-~x uses the bitwise NOT operator to modify the current value. As the value of a cell can only be positive, -~(a[c]) will increment the current cell, and unlike a[c]++ it will work if a[c] is undefined/null
- x=~-x uses similar logic to the previous line to decrement the current cell value: a[c]
- document.write(`{x};`) will write the current cell's value as ASCII to the document page. Allowing the ASCII to be interpreted by the HTML document is 14 bytes shorter than using the more common String.fromCharCode() method.
- x=p() takes user input for the current cell using previously defined prompt shorthand.
- whilex{ later in the code this will be changed to while(a[c]){, which is used to initialize a loop; it will run until the cell value at the pointer is equal to zero.
- } closes the loop explained in the previous line.
.split`x`.join`(a[c])` Replace each 'x' character from the previous code with (a[c]), to save space from repeatedly writing it out. Using backticks can contain a string and, in ES6, remove the need for parentheses. .split(c=0) Splits the JS at each zero, so that a BF character can be assigned with its correlated JS code. c=0 uses the same line to define c (the pointer) as zero, so that it is defined when running the script. '><+-.,[]'.indexOf(d) After the string has been split into different lines, this will convert +';' This is the final part of the code, which adds a semicolon to separate each line before executing