Focus is the temporary name for a work in progress esoteric programming language made by User:SoundOfScripting. In Focus, memory can only be accessed from the correct program location and with the correct shift.
Focus programs can be hard to follow, as one line of code may do many different things depending on the shift of the instruction pointer. The < and > commands are used to shift the instruction pointer left and right respectively. Understanding a Focus program can be made very difficult if this ability is used too much.
Each line of a focus program starts with a line number that is used as a label for that line. Lines are not, however, executed in order of their line numbers, but instead are executed in the order they appear. This can allow extra confusion.
Programs tend to heavily (ab)use the primitive stack in order to access memory that is "not in focus." Every line of a focus program can only access one memory cell, corresponding to the line number. In order to get memory from a different line, the program will have to jump to that line and use the stack to return to where it was.
Focus has 15 different commands, none of which contain any letters. Most symbols for commands were stolen/copied from Brainfuck, but the language itself operates very differently.
||Increments the current memory cell|
||Decrements the current memory cell|
||Outputs the current memory cell|
||Stores input in the current memory cell|
||Pushes the value of the current memory cell to the stack, preserving the value of the cell|
||Pops a value from the stack and store it in the current memory cell|
||Swaps the first two elements of the stack|
||Skips the next command if the current memory cell is zero|
||Sets the current memory cell to the absolute value of what it previously was|
||Sets the current memory cell to -1 * the absolute value of what it previously was|
||If the current memory cell is zero: NOP|
If the current memory cell is positive: Sets the current memory cell to 1
If the current memory cell is negative: Sets the current memory cell to -1
||See "Program syntax and shifts"|
Comments in Focus are surrounded with square brackets, and any symbol that is not a command is ignored.
Program syntax and shifts
Every line starts with a line number that is followed by a space. The syntax on each line is hard to explain, so here is a disassembly of a simple Focus program.
Note: All memory cells are initialized to zero and can be negative.
0 ++++++3 [Set Cell0 to 6 and jumps to 3] 3 ++++++++=2 [Set C1 to 8, pushes C1 onto the stack and jumps to 2] 2 +++._++.1 [Sets C2 to 3, outputs C2, pops the 8 from the stack and sets C2 to it, adds 2 to C2 resulting in 10, outputs C2 and jumps to 1] 1 1 [Halts the program (Infinite loop)]
The above program will output the following:
Now, a program with shifts will have multiple groups of commands, each with their own jump value. These groups are called semi-functions. The
> will change the global shift value. Only the semi-function overlapping the current shift value will be run.
0 +++=>1 3 [First run: C0 = 3, Push C0, Shift+1, jump to 1] [Second pass: Jump 3] 1 2 _--.0 [_--.0 is executed, not 2. The second semi-function is executed since the shift was incremented] 2 THIS LINE WILL CRASH THE PROGRAM BUT THANKFULLY ISN'T EXECUTED 3 ++++++++++. [Even though line 3 has no second semi-function, the code still runs (shifts can loop from left to right and from right to left)]
The output is:
Now, these explanations are not very good, but the author will put a better one here if needed.
! command is called, it will repeat the rest of the current semi-function x times, where x is the value of the current memory cell. For example, this program:
0 ++++!+++1 .1 1 >0 1
will have this output:
However, if we move the output command to the first semi-function, we'll have this program:
0 ++++!+++.1 1 1
that has this output:
7 10 13 16
This is because the
. command is also repeated.
Common mistakes are:
[Program] 0 >++!++0 .1 1 1 [Output is 6, not 4, since the
!does not reset the cell's value. To fix, add a
-to the repeating part and simplify if possible.]
[Program] 0 ++!>0 -.1 +.1 1 1 [Output is 3, not 1,
>happens twice. To fix, move the
>outside of the repeating part.]
[Program] 0 ++1 --1 !+1 .1 1 >0 >0 >0 1 [Output is 0, repeating something 0 times is the same as skipping it. The jump is not omitted, however]
Also, some interesting effects can happen using
! with a negative cell value. All
\ commands will be flipped to their opposites (Focus is nice enough not to mess with stack calls).
[Program] 0 -!-1 .1 0 1 >0 >0 [Output is 0, 1-1=0]
A simple if-statement can be written like so: (Replace (-y) with y
-'s and set C0's value to some value before calling the statement)
0 (-y)`!>1 1 2 3 4 2 [C0 < y] 3 [C0 = y] 4 [C0 > y]
This example makes use of
! inverting other commands with a negative.
To make working functions, we can make use of the stack. The first step is to make a global return line, usually at line 1, which contains the following code:
Line 0 can jump to our program so we have room to code, and functions can be passed arguments through the stack. It is helpful to use Focus N008M0D3 when creating a program, and then translating this back to actual Focus code.
Focus N008M0D3 is a version of Focus for n00bs that allows lines to be labled with strings and has some other handy features.
Labels in N008M0D3 can be any alpha-numberic string (without spaces in it), and simply replace the line number. For example:
FUNC1 (some code)
is perfectly valid N008M0D3 code. Labels can be jumped to in place of any line number jump.
FUNC1 (some code)PROGRAM FUNC2 (some other code)FUNC1
Above program is also valid.
"" can be used to get the line number of a line with a label. This can be used to push that to the stack, thus making functions and data structures even easier.
0 PROGRAM 1 _~ FUNC1 (some code that pushes a return value before the return call)1 [1 = RETURN] PROGRAM "PROGRAM2"="0"=FUNC1 [PROGRAM2 is return call, "0"=0, N008M0D3 cheats] PROGRAM2 _.HALT [Retrieve value from FUNC1 and output it] HALT HALT [End program, inf loop]
Data structures can be created in both Focus and Focus N008M0D3. For example, one could create a simple register that can increment and decrement itself like so:
[N008M0D3 version] 0 PROGRAM 1 _~ aREG +1 -<1 =$<<1 PROGRAM (code that changes the a reg) PROGRAM2 "PROGRAM3"=>>aREG PROGRAM3 _. [Get value of aREG and output)
0 3 1 _~ 2 +1 -<1 =$<<1 3 (Code that modifies C2 using line 2's semi-functions) 4 +++++=>>2 5 _.
More complex data structures (strings or arrays) could be made if Focus or Focus N008M0D3 were able to modify their own code (might come in Focus 2.0 if that ever happens).
Since Focus's memory cell's are unbounded, it is probably Turing complete.