Fohc

From Esolang
Jump to navigation Jump to search
Fohc
Paradigm(s) imperative
Designed by User:Matthilde
Appeared in 2021
Memory system stack-based and cell-based
Dimensions two-dimensional
Computational class ???
Reference implementation Fohc
Influenced by Befunge and FALSE
File extension(s) .fohc

Fohc is a 2-dimensional stack-based esoteric programming language made by User:Matthilde. It is inspired by Befunge-93 and FALSE. It features Minions (threads), 2-dimensional memory, a stack for each Minion and a read-only program memory.

It's name comes from a typo of the word "Fork", because before the minions concept was thought, it was planned that the program forks when o is called.

Overview

Memory

The memory is limited in the original implementation (96x96). The pointer starts at (0, 0). If the pointer goes outside the available memory, it will be sent to the opposite side (Example: if the x offset of the pointer is higher than 95, set the x offset back to 0). But nothing prevents anyone to implement infinite memory, making it Turing Complete.

Minions

Minions are threads with extra steps. Each minion has its own memory pointer, program counter, stack and snapshot. Snapshots are a 2d array that can be used to keep a copy of the current memory state, allowing to do special manipulations (such as reading the previous state of memory). The minion can switch between manipulating the original memory and the snapshot by using the S instruction and take a snapshot of the memory using the s instruction.

Minions moves through paths like this. (Assume the ! character is where a minion spawn in these schemes)

!********   ( The minion will turn right )
        *
        
        *
!********   ( The minion will pick a random direction )
        *
        
        *
!*******T   ( The minion can however be forced to turn right in this situation if
        *     the programmer uses the T instruction )
!********   ( The minion will continue it's way forward )
     *
!*******x   ( The minion dies at the dead end )
    
        !
!*******o!* ( When the o instruction is used, the minion splits into multiple minions
        !     in all possible directions except the direction the minion originally comes from. The neighborhood mode, the snapshot and memory pointer
              of the new minions are the same as the original one on creation. )
* can be replaced by any instruction that does not affect the minion's direction. Take this instruction
  as a NOP instruction (No Operation)

The program stop when the @ instruction has been called or if all minions has died. When the program starts, one minion is created at 0,0

If a minion overlaps with another minion, it does not have any effect on their behavior.

IO

IO is quite simple, the memory is the screen (output) and the keyboard is the input. There is no way to print characters, the programmer can only alter memory to print out pixels. A memory cell is 8-bit long (basically a byte) and will display a shade of grey between 0 and 255 depending of the value the cell is holding. To stay synchronous with the screen refresh, an instruction has been created to wait until the screen refreshes.

Neighborhood in memory

The language contains instructions to calculate the number of neighbors around the pointer. The programmer can switch the "Neighboorhood Mode".

  • Von Neumann mode will use the Von Neumann neighbor, which means up, down, right and left.
  • Moore mode will use the Moore neighborhood, which also takes in account corners.

When a minion has spawned, it defaults to the Von Neumann mode. There is no global state, the mode is independent to each minion.

Instructions

Instruction set
Instruction Description
* No Operation
o "Forks" the minion into all available directions
0-9 Push a number into the stack
T Force minion to turn right instead of a random direction (see the Minions section)
: Duplicate top stack value
\ Swap two values from the stack
$ Drop top stack value
+ Adds two top stack values
- Substracts two top stack values
x Multiplies two top stack values
/ Divides two top stack values
& Bitwise AND
| Bitwise OR
~ Logic NOT
= Returns 1 if two top stack values are equal else 0
` Pop two values a and b, then push 1 if b>a else 0
? Pop value a, if a>0 then let the minion continue forward else pick another direction. If there are are no other directions, the minion dies.
^ Move the memory pointer to the top
v Move the memory pointer to the bottom
< Move the memory pointer to the left
> Move the memory pointer to the right
. Reads byte from memory pointer and push it in the stack
, Pop a value from the stack and writes it at the memory pointer
P Writes 255 at the memory pointer
p Writes 0 at the memory pointer
# Jump over next command
N Get the sum of neighbors around the memory pointer. A cell holding a value higher than 0 counts as a neighbor
n Switch between Von Neumann and Moore mode (defaults to Von Neumann)
u Gets value from top cell
d Gets value from bottom cell
l Gets value from left cell
r Gets value from right cell
s Save a snapshot of the memory (see Minions section)
S Switch between manipulating the snapshot memory and global memory (defaults to global memory)
@ Kill all minions
k Push to the stack the ascii value of the currently pressed key, push 0 if no key is pressed.
' Pops x and y from the stack and move the memory pointer to (x, y)
" Pushes x and y of the memory pointer position
; Wait until screen refresh

Implementation

At the time these lines are written, User:Matthilde is currently working on a C implementation of the programming language using the SDL library. So the programming language is not implemented yet. This implementation is going to be the reference implementation (unless someone makes a better implementation?).