Vitsy

From Esolang
Jump to navigation Jump to search
Vitsy
Paradigm(s) imperative
Designed by User:VTCAKAVSMoACE
Appeared in 2015
Memory system Stack-based
Dimensions one-dimensional
Computational class Turing complete
Reference implementation Vitsy
Influenced by ><>
File extension(s) .vt

Vitsy is an esoteric programming language designed by the PPCG user VTCAKAVSMoACE. It's control structure is largely linear and stores data in a stack of stacks of arbitrarily large decimals, or, more simply, a two-dimensional stack of arbitrarily large decimals. Its most common interpreters are written in Java and may be found in this GitHub repository. The Java interpreters began development in mid-October 2015 and will continue to be developed for probably all of time. More interpreters (specifically in JavaScript) based on the language (but not identical in behavior) are coming to existence thanks to PPCG users Cᴏɴᴏʀ O'Bʀɪᴇɴ, LegionMammal978, Maltysen, and RikerW.

Overview

Vitsy programs are are aware of any of the following things:

Syntax

All Vitsy programs are composed of UTF-8 text files (extension optional, typically .vt) containing commands in the Vitsy language. A Vitsy program is organized into four main components: methods, blocks, commands, and use and ext declarations.

Methods

Methods in Vitsy are separated by newlines and indexed in array format for access. When a Vitsy program is run, the first line (or the main method) is executed. Other methods will not be run unless specified by the method command with that index of the methods. Methods retain the current state of the program stack when called, as well as knowing the current values for the final variable and the temporary variable. Methods in other programs may be called through the class method command, which will call the specified index of the methods in the specified index of the use declarations. Method calling may be recursive.

Blocks

Blocks are sections of code that are surrounded by [ (the begin block command) and ] (the end block command) commands which designate this section of code to act as though it was a single command. All blocks will continue until closed by the end block command, meaning that if the block is not terminated before the end of the method, they will return to the beginning of the current method and continue until finding their close block. Block behavior is largely dependent on what the command previous to the block is.

Conditional Blocks

Conditional blocks are blocks preceded by the if or if not commands. If the condition for the if statement is met, the block will be executed, otherwise, it will not. Conditional blocks may not be broken out of as for loops are broken from; calling the end command inside of a conditional block will cause the previous block layer to be broken out of (or, if there are no higher levels of block, the current method will terminate).

Repeat Blocks

Repeat blocks are preceded by the repeat command and are executed as though it were a single instruction, repeating the contents of the loop as many times as would be repeated for a single command. Repeat blocks may be broken out of with the end command.

Loop Blocks

If none of the previous types of blocks are found, the block is treated as a loop block, which will loop infinitely unless:

  • broken out of with the end command
  • the integer value of the top item of the stack is zero at the end of the block

Commands

Commands are executed one at a time (unthreaded) and may affect the current state of STDIN, STDOUT, the stack, local files (disabled in safe mode), and the system (via shell) (disabled in safe mode). A list of commands is provided below.


Command Name Description Known Bugs
Control Structures
) if not Conditional execution of the next command; if the integer value top item of the stack is not equal to zero, then the next command in the method will be executed. Otherwise, it will not. If the if not command is followed by a opening square bracket, all commands within the that pair of square brackets will be conditionally executed with the same conditions as above.
( if Conditional execution of the next command; if the integer value top item of the stack is equal to zero, then the next command in the method will be executed. Otherwise, it will not. If the if command is followed by a opening square bracket, all commands within the that pair of square brackets will be conditionally executed with the same conditions as above.
[ begin block Begins a block of code. This block of code will be treated differently according to the command previous to the begin block command. If the either the if or if not command is the previous command, it will conditionally execute the block once. If the repeat command is the previous command, it will execute as many times as the top item of the stack specifies (or until broken by the end command). Otherwise, it will be executed until the top item of the stack is zero when the end block command is called (or until broken by the end command).
] end block Ends a block of code. This is treated as a non-operational character if we are not currently in a block of code. If the block is an infinite loop block, it will exit the loop if the integer form of the top item is 0 and pop it. If the top item of the stack is not zero, it will not be popped and the position within the method will be returned to the beginning of the block. On empty stacks, the loop causes an ArrayOutOfBoundsException.
\ repeat Repeats the next command or block as many times as specified by the integer value of the top item of the stack. May be broken out of with the end command.
; end Generic end command. Not to be confused with x (exit). If end is called inside of a recursive block statement, the block is broken out of and execution is continued from the command after the block. If end is called outside of a block, it will end the current method immediately and return to the previous method (or exit, if in the main method).
x exit Generic exit command. The program is halted immediately with an error code as the integer representation of the top item of the stack modulo 256.
# teleport Teleport to the index of commands as specified by the integer value of the top item of the stack. This is mainly unsupported, and likely to be removed in future versions.
< move left Change the direction of the instruction pointer's movement towards the left. Moving left also informs the interpreter to wrap around to the end of the method when reaching the first command in the method.
> move right Change the direction of the instruction pointer's movement towards the right. While moving right, methods will finish and return back to the previous method (or terminate the program if on the main method) when the end of the method is reached.
" or ' toggle quote Toggle capturing of instructions as strings. As each instruction is passed, it's UTF-8 value is pushed to the current decimal stack. The quote does not end until locating another quote, wrapping around the line if it must.
m method Pop the integer value of the top item of the current decimal stack as n, go to index n of the methods and execute it. When it finishes, return to this point in the code and continue execution of this line.
Data
i input Pops the final item of the input stack and pushes it to the top of the current decimal stack as its decimal value. If there are no values to be popped from the input stack, -1 is pushed.
I input length Pushes the current length of the input stack to the top of the current decimal stack as its decimal value.
l length Pushes the current length of the current decimal stack to the top of the current decimal stack as its decimal value.
z get all input Pops all items off the input stack and pushes them in top-access order to the program stack. If there are no values to be popped from the input stack, nothing happens.
Z output the stack Pops all items off of the current decimal stack and pushes them to STDOUT in top-access order with ISO-8859-1 encoding.
O output as char Pops the top item off of the current decimal stack and pushes it to STDOUT in ISO-8859-1 encoding.
N output as number Pops the top item off of the current decimal stack and pushes it to STDOUT as a float value, using the greatest precision available.
W get STDIN Grabs a line from STDIN and evaluates it. If it is parseable as a decimal, it will push the decimal value to them current decimal stack. Otherwise, it will parse it as a string, pushing each character to the current decimal stack in top-access order to the program stack.
$ single switch Switch the top two items of the current decimal stack. If there is only one item on said stack, push a zero to accommodate.
% multi switch Pop the top value off the current decimal stack as n, then rotate the top n items of the stack to the right. If there aren't enough items in the stack, push zeroes to accommodate. Zero-filling for stack accommodation is inaccurate and throws values around wildly. Do not use multi switch on a stack with fewer values than specified with n.
} rotate right Rotate the current decimal stack in a fashion that moves the bottom value to the top without changing the order of the other values. This will change the current decimal stack's location in the stack stack. Avoid using rotate after creating new stacks.
{ rotate left Rotate the current decimal stack in a fashion that moves the top value to the bottom without changing the order of the other values. This will change the current decimal stack's location in the stack stack. Avoid using rotate after creating new stacks.
r reverse Flip the entire current decimal stack. This causes the top item to be on the bottom and vice versa, changing the values in between in the same fashion.
@ part Pop the top value of the current decimal stack as n, then push the value of the nth item of said stack (where the top item is 1, the second to top is two, etc)
D duplicate Duplicate the top value of the current decimal stack and push it to said stack.
X remove Pop the top value of the current decimal stack and discard it.
o object Pop the current decimal stack off of the stack and store it in the next command's string value. Note that the next instruction character should be non-operational, as popping stacks into characters that are defined for other methods is unsupported. This is only necessary to be called the first time you declare the instruction character; after declaration, the character will tell the interpreter to dump the decimal stack to the program stack. If there is no decimal stack to dump being held by the object, then it will capture the current stack for later use.
& new stack Push an empty decimal stack to the program stack and move to it.
Y remove stack Pop and discard the current decimal stack, moving to the stack to the right.
: clone stack Deep clone the current stack, retaining its values, and then push it to the program stack, moving to it in the process.
? right stack Move from the current decimal stack to the decimal stack an index one greater than the current. If moving to a stack that does not exist, the program stack will be set to the 0th index of decimal stacks.
| left stack Move from the current decimal stack to the decimal stack an index one less than the current. If moving to a stack that does not exist, the program stack will be set to the final index of decimal stacks.
u flatten Join the top two stacks together, concatenating the values of the current decimal stack to the end of the stack to the left of the current stack. If there is only one decimal stack, it will eat itself and become nothing, leaving no decimal stacks on the program stack.
y stack count Push the number of stacks to the decimal stack.
v temporary variable If the temporary variable is currently empty, capture the top item of the decimal stack and save it in the temporary variable slot. If the temporary variable slot has already been taken, pop it from the temporary variable slot and push it to the decimal stack. This value transfers over methods and classes.
V final variable If the final variable is currently empty, capture the top item of the decimal stack and save it in the final variable slot. If the final variable slot has already been taken, peek it from the final variable slot and push it to the decimal stack. This value transfers over methods and classes.
Math
S sine Pop the top item of the stack as n, push sine of n (as a radian) to the current decimal stack. Uses 100 point precision approximation for pi, which will cause some rounding error.
s arcsine Pop the top item of the stack as n, push arcsine of n to the current decimal stack (as a radian). Limited to Integer.MAX_VALUE
T tangent Pop the top item of the stack as n, push tangent of n (as a radian) to the current decimal stack. Uses 100 point precision approximation for pi, which will cause some rounding error.
t arctangent Pop the top item of the stack as n, push arctangent of n to the current decimal stack (as a radian). Limited to Integer.MAX_VALUE
C cosine Pop the top item of the stack as n, push cosine of n (as a radian) to the current decimal stack. Uses 100 point precision approximation for pi, which will cause some rounding error.
s arccosine Pop the top item of the stack as n, push arccosine of n to the current decimal stack (as a radian). Limited to Integer.MAX_VALUE
P pi Push a decimal approximation of pi to the current decimal stack.
E e Push a decimal approximation of Euler's constant to the current decimal stack.
L log Pop the second to top item of the current decimal stack as n, pop the top item of said stack as o, push logarithm base o of n. Float point precision problems.
R random Pop the top item of the current decimal stack as n, push a random decimal between 0 and n to the stack. Not uniformly random.
+ add Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push the sum of n and o to the same stack.
- subtract Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push o minus n to the same stack.
* multiply Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push the product of n and o to the same stack.
/ divide Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push n divided by o to the same stack. Float point error problems with infinite repetitions.
^ power Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push o to the power of n to the same stack. Float point error problems, restricted to primitive double precision/size.
= equals Pops the top two items of the current decimal stack and compares them. If they are equal, push 0. Else, push 1. This is mostly unsupported (as the subtract command can do this more efficiently) and may be removed in future versions.
M modulo Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push the remainder of n divided by o to the same stack.
_ truncate Replace the top item of the current decimal stack with its integer value.
h factorize Pop the top item of the current decimal stack as n, push its factors to the same stack.
p prime Replace the top item of the stack with 1 if it is prime, 0 if it is not.
H range Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, push the range between o and n to the same stack, retaining order.
Separate Program Management Please see the next section for more information.
k program method Pop the top item of the current decimal stack as n, pop the second to top item of the same stack as o, load index o of the use declarations and execute its nth index of code. This is disabled in safe mode.
K short program method Pop the top item of the current decimal stack as n and load the program as declared in the ext declaration and execute its nth index of code. This is disabled in safe mode.
g uses count Push the number of valid use declarations to the current decimal stack. This is disabled in safe mode.
G use name Pop the top item of the current decimal stack as n, get the name of index n of the use declarations and push it to the same stack input style, with special cases -2 requesting the name of the ext declared program and -1 getting the name of the current program. This value changes according to the currently executing program.
Miscellaneous
w wait Pop the top item of the current decimal stack as n and wait n seconds before preceding onto the next command.
` file Pop the entire current decimal stack and use its name as though it was a file name. If the file exists, read its entire contents and push them in top-access format to the stack.
. write Pop the entire current decimal stack as n, pop the entire second decimal stack as o. Use n as a file name, then write the contents of o to the file.
, shell Pop the entire current decimal stack as n and execute it as though it was a shell command..
n eval Pop the entire current decimal stack as n and evaluate the string n through Javascript eval.

use and ext Declarations

use and ext declarations exist solely for the purposes of calling methods from other programs from a Vitsy program. These declarations always appear at the end of a file, and an example can be found below.

0K00k
;e program2
;u program3

In this program, I first push 0 to the current decimal stack, then I call K, which executes a method in the declared ext file. The ext file is declared by ;e and, in this situation, references program2. Therefore, in the first two commands, we have executed the main method of program2.

Similarly, we declare use files with ;u. In commands 3 through 5, we push 2 zeroes, then call k, which executes a method in the specified declaration of use files. With 00k, I call the 0th index of use declarations (program3's) 0th index of methods. Therefore, we have executed the main Vitsy method of program3.

Data Structures

Data is stored in various locations, some of which are read-only, some of which are neither readable nor writable until active, and some of which are readable and writeable immediately. Most data structures are stacks, but there are a few data structures aside.

Stacks

Vitsy uses multiple stacks, some of which are multi-layered and contain different values. Details for each stack type are below.

Program Stack

Vitsy is aware of all data contained in the program stack. The program stack is toroidal and consists of multiple decimal stacks. There is only one program stack per instance of Vitsy, and it may not be destroyed, but it may be modified through commands found in the Data section of the commands list. The program stack is originally instantiated with an empty decimal stack on it.

Decimal Stack

Decimal Stacks are stacks of arbitrarily large decimal values. Vitsy interacts mostly with this form of stack, and all mathematical operations are executed with values found on this stack. These stacks are toroidal and there may be many decimal stacks per program stack. Decimal stacks may be destroyed, created, and modified within the program stack through commands found in the Data section of the commands list. Each decimal stack is instantiated empty unless it is a clone of another stack.

Input Stack

String input to any Vitsy program via command line arguments which cannot be parsed as a double are placed onto the input stack. The input stack is top-access only and may only be popped from. Commands which interact with the input stack may be found under the Data section of the commands list.

Method Stack

The method stack is a trace to the currently accessed method via all the previous methods (Java style). The method stack is wholly inaccessible for information access, and is used solely for the purposes of tracing back to the place where each method was called. There is only one method stack per Vitsy instance which cannot be destroyed or modified in any fashion. The method stack is instantiated with the initial value of the main method of the main program file.

Class Stack

The class stack is a trace to the currently access program file and is closely related to the method stack, although they are wholly separate. There is only one class stack per Vitsy instance which cannot be destroyed or modified in any fashion. Current class information may be found through commands found in the Separate Program Management section of the commands list. The method stack is instantiated with the initial value of the main program file.

Variables

There are three different variable types in Vitsy - a temporary variable, a final variable, and objects. These variables are passed over methods and programs and have different behaviors as defined below.

Final Variable

The final variable may be called by the final variable command under the Data section of the commands list. When the final variable is first called, it captures the top value of the current decimal stack and retains it permanently. Any following calls to it will push its value to the current decimal stack. The final variable's value may not be dumped at any point and said final variable is passed through method calls and separate program calls.

Temporary Variable

The temporary variable may be called by the temporary variable command under the Data section of the commands list. When the temporary variable is called, it will follow one of the two following behaviors:

  • If the temporary variable does not currently have a value assigned to it, it will capture the top value of the current decimal stack and save it for later use.
  • If the temporary variable does currently have a value assigned to it, it will dump the value to the current decimal stack and clear its value.

The temporary variable's value may be dumped when the temporary variable command is called and said temporary variable is passed through method calls and separate program calls.

Objects

Objects are decimal stacks that have been captured and assigned to a specific character in the instructions. An object must be declared with the object command, which declares the following character as an object character (if it does not already have a meaning through commands) and promptly captures the current stack and pushes it to the object. When the declared object character is called again, it will follow one of the two following behaviors:

  • If the object does not currently have a stack assigned to it, it will capture the current decimal stack save it for later use.
  • If the object does currently have a stack assigned to it, it will dump the stack to the program stack, move to it, and clear its own value.

An example, as I realize this is difficult to follow:

1234oj jN j

First, we push 1, 2, 3, and 4 to the current decimal stack. Then, we assign the character j (which does not have a command meaning) as an object, grabbing the current decimal stack and assigning the object called j's value to said decimal stack. (There are now no stacks in the program stack.) I now call j again, pushing the decimal stack found in j to the program stack. I then pop the top value and output it as a number, pushing 4 to STDOUT. I now only have 1, 2, and 3 on the stack, which I then capture again by calling j.

The objects's stack may be dumped when its declared character is called and the declared object is passed through method calls and separate program calls.

STDIN

Although not a data structure necessarily owned by the Vitsy instance, STDIN acts similarly to the input stack (but not exactly) in that each line is a separate item and all items of each line are pushed to the stack, evaluating as a decimal when possible. Calling for STDIN while executing through a command line causes the program to halt until a newline is read from the command line.

Input/Output

Input and output is handled in very specific ways in Vitsy. All manners in which input is accepted or output is pushed may be found below.

Command Line Arguments

Command line arguments are accepted as a form of input for Vitsy. If all command line arguments are parseable as decimals, their values are pushed onto the initial decimal stack. Otherwise, all of the command line arguments are joined with a space and pushed onto the input stack.

STDIN

Input through standard input must be explicitly requested by the Vitsy program. When being called via the STDIN command (as found in the Data section of the commands list), a single line is pulled from STDIN, attempted to be parsed as a decimal, and then pushed to the current decimal stack. If using Vitsy through the command line, Vitsy will halt when STDIN is empty and called for new data.

STDOUT

STDOUT is the only form of output used by a given Vitsy instance for normal output types. See the Data section of the commands list for how data is output to STDOUT when calling various commands.

STDERR

STDERR is only output to whenever an error is thrown, showing information about the error and what caused it. Vitsy cannot output to STDERR without throwing an error.

Examples

Hello, World!

"!dlroW ,olleH"Z

Since quotes push items to the stack in the order in which it encounters them, the string must be pushed in reverse to allow the top-access-only outputting Z command to output everything in the right order.

Standard Quine

'rd3*Z

Quotes wrap around a line, meaning that, with this code, we can capture all elements of the code, then reverse the stack (for order) and push the character value for ' and output everything. This is a true quine.

Trivia

  • Vitsy comes from a mispronunciation of the first three characters in VTCAKAVSMoACE.
  • Vitsy is also referred to as "Purse Dog", Flasp, and VTC's Child.
  • Vitsy is also occasionally used throughout VTCAKAVSMoACE's school by Computer Science teachers for quick calculations due to its stack-based nature and simple-to-use polish notation.
  • This wiki page for Vitsy is larger in byte count than the entire compiled Vitsy jar.

External Sources

GitHub repository for Vitsy (Java)

GitHub page for Vitsy (JavaScript)

Try It Online (online execution)