-Output

From Esolang
Jump to navigation Jump to search

-Output (pronounced "minus output") is a stack-based, Befunge-styled esolang invented by User:Evylah. Its main feature is that there is no output command, or a standard way to output to a console.

It's file extension is .poutput. A -Output file is technically a +Output file, because they're the same, just -Output doesn't have the output command.

Code execution

Code in -Output is laid out in a 2-dimensional grid. There is an instruction pointer (or IP for short), and it can move right, down, left, and up. The pointer's direction can be changed with >, v, ^ and <.

Memory

Data is stored in two stacks. Commands can push and pop to and from the currently selected stack. "The stack" just means the currently selected stack.

Output

Since there is no standard way to output in -Output, you have to think outside the box. There is one prominent feature that is very useful: self-modification.

So, using this, outputting can be done by modifying the source code.

There is also another way: by reading the memory. It is possible to just read the two stacks and use that as output. If for any reason an implementation cannot modify files, outputting the memory at the end is a valid fallback option.

Instructions

IP movement

These commands will change the instruction pointer's direction, make it jump to places, and more.

op Values popped Description
> < ^ v - Change the IP's direction to the direction of the arrow.
? - Set the IP's direction to a random direction.
# - Jump over the next instruction in the IP's direction.
j x, y Jump to (y, x) in the codebox, retaining the same direction. The top-left corner of the codebox is (0, 0). When this is done, the IP moves one space.
@ x Turn the IP clockwise x many times. Turning a multiple of 4 times would be completely useless, and a multiple of 2 and not 4 would turn 180 degrees.
X - Halt program.

Stack manipulation

These commands push, pop, and modify the two stacks in some way. When the description says "the stack", that means the currently selected stack.

op Values popped Description
( ) - Select first stack with ( and second with ).
0-9, a-f - Push that number onto the stack. Hex digits are in lowercase.
$ - Swap the top 2 items on the stack.
~ - Pop and discard the top item.
: - Duplicate the top item of the stack.
r - Reverse the stack.
m x Pushes x onto the other stack. This does not select the other stack.
M x (from other stack) Moves x from the other stack and pushes it to the selected stack.
" - Reads all characters until the IP hits another " and push it as one string. The IP will not be affected by direction changes.

Arithmetic and logic

op Values popped Description
! x Bitwise NOT. Push 1 if x is 0, otherwise push 0.
n x Push x * -1.
+ x, y Push y + x. If both values are strings, push the strings concatenated. If one is a string and one is a number, then raise an error.
* x, y Push y * x. If both values are strings, raise an error. If one is a string and one is a number, add the string to itself that number of times.
/ x, y Push y / x. Uses float divison. If any value is a string, raise an error.
\ x, y Push y ^ x. If one value is a string, then the string will be pushed onto the stack the number of times. If both values are strings, raise an error.
= x, y Push 1 if y == x, otherwise push 0.
` x, y Push 1 if y > x, otherwise push 0. If any value is a string, its length will be used as the number.
& x (string) Push float(x). If this is not possible (like if x is "6969whoa") then push the string back.
s x Push str(x).
t x Push 0 if x is a number, 1 otherwise.
U x Takes string x and pushes each character's Unicode value from left to right. If x happens to be a number, then instead push the Unicode character associated with x. If used on an empty string, push 0.
. x, y Splits string y into items separated by the first character of string x. Pushes each substring in order from left to right. If x is a number but not 0, split using the Unicode character. If y is an number, throw an error. This is the equivalent of push(y.split(x)) in Python. If x is 0, split at every character.
, x, y Push a random number between y and x inclusive. If any value is a string, throw an error.
l x Push the length of string x. If x is a number, throw an error.

Input

It's not I/O because there's no output.

op Values popped Description
i - Ask the user for input as a string, ended with a newline. The newline will not be part of the string and the input will always be pushed as a string. If an empty string is provided, push an empty string.

Self-modification

op Values popped Description
g (lowercase) x, y Push the character at (y, x) in the code as a string with length 1. Empty cells and spaces will push a space.
G (uppercase) x, y Same as the g command, but instead pushes the Unicode value of the character. Empty cells will push 0, spaces will push 32.
p x, y, z Replaces the character at (y, x) in the source code with the first letter of string z. If z is a number, the character will be replaced with the Unicode character instead.

Control flow

op Values popped Description
[ - Mark the current cell in the source code. This will override any previous marked cell.
] x Jump to the marked cell if x is non-zero. Jumping will keep the IP's current direction.
_ x Go right if x is zero or an empty string, left otherwise.
? - Start moving in a random direction.


Examples

Truth-machine

in1=#v_0m)X
   v)<
   >1^

Read the second stack for output.

Hello, World!

X Output: "Hello, World!"

This is a valid Hello, World! program. The output is in the source code.

Hello, World! 2

"Hello, World!":m X

This also works. Read either stack for output.

+Output

I made a version of this (because I thought -Output was a cool esolang) that has output, so there is no hassle of outputting values.