Vizh

vizh is a visual esoteric programming language that takes image files as input and is based on a multi-tape Turing machine. It is designed for compatibility with C and was created by User:TartanLlama in 2021.
The "parser" has to use computer vision and OCR to process the user's code. Here is an implementation of memcpy:
Here's how the parser understands the program (produced if you pass --debug-parser when compiling):
More complex programs can be written by splitting the symbols across multiple lines, such as this function which counts nested square braces:
==Abstract Machine==
The vizh abstract machine consists of:
* Some number of tapes which are contiguous groups of 8-bit unsigned integers
* A read/write head with storage for a single 8-bit unsigned integer
The initial state of the abstract machine is:
* A single tape of size 4096 is allocated with all cells initialised to 0
* The read/write head is initialised to the left-most cell of this tape
==Programs and Functions==
A vizh program consists of a number of functions, each in its own image file.
The entry point to a vizh program is a function called main. (Note that the main function gets mangled as vizh_main. For all other functions the symbol name is the same as the vizh name).
A vizh function is an image file containing:
* The name of the function at the top left of the image
* The number of arguments (tapes) it takes at the top right of the image
* A sequence of instructions in a horizontal lines
Function names are alphanumeric: [a-zA-Z][a-zA-Z0-9]*.
The tapes available to a vizh function consist of its tape arguments. A function returns when control flow reaches the end of its instructions. Any tapes allocated by a function are automatically deallocated when the function exits.
When you call a function subsequent pointer arguments are taken from the currently active tape onwards.
For example, given the following state of the abstract machine where ^ is the last position of the r/w head on that tape and $ is the active tape:
 t1 01234
 ^
 $t2 99999
 ^
 t3 00000
 ^
then a call to a function that takes two tapes would supply the arguments t2, t3.
==Instruction Set==
Instruction 	Description
Left arrow 	Move the r/w head left.
Right arrow 	Move the r/w head right.
Up arrow 	Move the r/w head to the tape above the current one.
Down arrow 	Move the r/w head to the tape below the current one.
Function name in a circle 	Call the named function.
Plus 	Increment the value pointed to by the r/w head by 1.
Minus 	Decrement the value pointed to by the r/w head by 1.
Equilateral triangle with the point at the top 	Read the cell pointed to by the r/w head into the r/w head storage.
Equilateral triangle with the point at the bottom	Write the value stored in r/w head storage into the cell pointed to by the r/w head.
[<instructions>] 	Loop over the instructions between the brackets until the value pointed to by the r/w head at the start of the loop is 0.
When you move the r/w head up or down, the position it was last at for the previous tape is saved. E.g. given this state of the abstract where ^ is the last position of the r/w head on that tape and $ is the active tape:
 $t0 01234
 ^ 
 t1 01234
 ^
The sequence of instructions "right right right down" would result in this state:
 t0 01234
 ^ 
 $t1 01234
 ^
Comments in vizh are anything enclosed in a rectangle. Stick what you want in there.
==Standard Library==
The vizh standard library is called libv and the majority of it can be implemented in pure vizh.
Function	Description
readin 	Read an ASCII character from stdin and write its integral representation into the cell pointed to by the r/w head.
print 	Print the value of the cell pointed to by the r/w head to stout, interpreted as an ASCII character.
putstr 	Write the null-terminated ASCII string starting at the position pointed to by the r/w head to stdout.
geta 	Puts the character a at the current position of the r/w head.
getA 	Puts the character A at the current position of the r/w head.
add 	Given tape cells a,b from the r/w head, results in a+b,0.
minus 	Given tape cells a,b from the r/w head, results in a-b,0.
mul 	Given tape cells a,b,c from the r/w head, results in a*b,0,0.
zero 	Given tape cell a from the r/w head, results in 0.
compl 	Given tape cells a,b from the r/w head, results in 1,0 if a==0, otherwise 0,0.
equal 	Given tape cells a,b from the r/w head, results in a==b?1:0,0.
newtape 	Allocate a new tape underneath the last one currently allocated for this function.
freetape	Deallocate the bottom-most secondary tape for this function (no-op if there are not any).
==Computability and Usability==
Since vizh is essentially a multi-tape Turing machine, it is Turing-complete.
The ability to allocate multiple tapes and call functions makes it much more useable than something like Brainfuck. You can find an implementation of a Brainfuck interpreter written in vizh on GitHub.
==Implementation==
An implementation written in Python which uses OpenCV and Tesseract OCR to parse code and outputs C is available on GitHub.
Category:2021 Category: Turing complete Category: Non-textual Category: Implemented Category: Cell-based Category: Languages