gur yvsr

From Esolang
Jump to navigation Jump to search
gur yvsr is typically stylized as all lowercase.

gur yvsr is the very first esolang created by User:Placeholding. It is inspired by Brainfuck and (slightly inspired by) Emmental, though it is not as confusing as either of them (still very confusing).

Overview

Syntax

gur yvsr's syntax consists of single-character commands as well as comments. A comment starts and ends with backticks (`), like so:

`I will be ignored.`

In addition, gur yvsr will ignore all whitespace characters.

The Tape & the Pointers

Like Brainfuck, gur yvsr operates on a tape of integers; however, this tape can go in both the positive and negative directions and can hold negative numbers. gur yvsr also has a pointer (called the data pointer) that continues moving down the tape (it moves in the positive direction when the program starts) and can read and write to the tape. Certain commands can stop the data pointer from moving (e.g. #, J, and digits 0 through 9), but it will continue moving after the next command is executed (unless that command also halts the data pointer temporarily). It's important to note that the data pointer will always move AFTER executing a command.

The code pointer is simply the pointer which reads and executes commands. It is only able to move to the right.

The Accumulator

In addition to the tape and data pointer, gur yvsr also has an accumulator which can only hold one signed integer value. All integers that are created first go into the accumulator, where they can then be put onto the tape.

Another thing that can be done with the accumulator is to clear it; this can be accomplished with the C command.

Creating Integers

The # command can be used to signify the creation of an integer. Please note that if the # command is executed twice in a row or if the accumulator is full when executing the # command, gur yvsr will raise an error.

Digits (0-9) can be placed after the # command to start creating the integer. If the accumulator is empty, the digit's value will simply be stored into the accumulator; otherwise, the accumulator's value will be multiplied by 10, and then the digit's value will be added to the accumulator's value. An error will be raised if the digit appears without a previously executed # command or without a previously executed digit.

An example of integer creation:

#134 `this will store the number 134 into the accumulator`

Remember that there's no need to worry about the data pointer moving; both executing the # command and appending digits to the accumulator's value will temporarily halt the data pointer.

Writing to & Reading from the Tape

As stated before, all integers will first go into the accumulator. In order to get data out of the accumulator and onto the tape, you may use the U command. The u command may also be used to write to the tape, but it does not clear the accumulator. An error will be thrown if you use the U or u commands when the accumulator is empty. After executing either the U or u commands, the integer in the accumulator's value will be stored in the current cell (i.e. the cell being pointed to by the data pointer).

The opposites of the U and u commands also exist: R and r, respectively. The R command will store the current cell's value into the accumulator, and then clears the current cell. If the current cell is empty when this command is executed, the program will throw an error. r does the same thing, except that it does not clear the current cell's value.

Like the accumulator, the current cell can be cleared; the command for clearing the current cell is c.

Control Flow

Conditionals

gur yvsr has seven conditional commands: ?, !, T, t, A, a, and @. The first six commands will check if the current cell (? and !), a different cell (T and t), or the accumulator (A and a) are zero or empty. Depending on what these six commands are looking for, they will send the code pointer to the corresponding @ command if they are satisfied. If not, they will not do anything. Below is a table on what these six commands are looking for:

Command Will be satisfied if:
? the current cell is 0 or empty
! the current cell is neither 0 nor empty
T the nth cell is 0 or empty, where n is the accumulator's value
t the nth cell is neither 0 nor empty, where n is the accumulator's value
A the accumulator's value is 0 or empty
a the accumulator's value is neither 0 nor empty

These conditionals MUST be paired with a corresponding @ command if they are satisfied. If no corresponding @ command is found, an error will be thrown.

Bad Examples

The following examples demonstrate uses of conditional commands which lead to an error being thrown:

#8 U ! .

This is not OK because the ? conditional is satisfied, and there is no @ command to send the code pointer to.

? ? @ .

This is not OK because even though there is an @ command present, only one ? conditional has a corresponding @.

@ A .

Even though there is an @ command with the A command, this is not OK because the @ command needs to go after the A command. This applies to all other conditionals as well.

Good Examples

The following examples demonstrate uses of conditional commands which don't cause an error to be thrown:

? #12 U #44 U #2 - K i . @ #33 k .

The ? command is satisfied and has a corresponding @ command.

! #77 .

The ! command is not satisfied, so it does not need a corresponding @ command.

? #0 U #2 - K = A C #77 . @ #100 U @ .

The ? and A commands are satisfied and each have a corresponding @. Conditional structures like these are called nests, where a conditional and @ surround another conditional and @.

The Stop Command & the No-op

gur yvsr programs must contain a stop command (.) in order for them to end properly. If there is no stop command to stop the program, the program will throw an error complaining that the code pointer has been pushed out of bounds.

gur yvsr's no-op command is simply an underscore (_). It simply does nothing, but it could be useful in a few cases since it doesn't halt the data pointer.

Pointer Commands

Both the data pointer and code pointer can be manipulated in similar ways. They can both be moved around, but only the data pointer may change direction. Below is a table of pointer commands:

Command Does this:
J Makes the code pointer jump n commands to the right, where n is the accumulator's value, and clears the accumulator
j Makes the code pointer jump to the command at index n, where n is the accumulator's value, and clears the accumulator (the command at index 0 is the first command)
K Makes the data pointer jump n cells to the right, where n is the accumulator's value, clears the accumulator, and temporarily halts the data pointer
k Makes the data pointer jump to the cell at index n, where n is the accumulator's value, clears the accumulator, and temporarily halts the data pointer (the cell at index 0 is the first cell)
F or f Flips the data pointer's direction

Do note that these commands can be easily used to push the data pointer and code pointer out of bounds. If that happens, an error will be thrown.

Math & Logic

gur yvsr has several math and logical commands which store something into the accumulator. Most of these commands take into account the cell to the left of the current cell and the current cell, meaning that they will cause an error to be thrown if either the cell to the left of the current cell is empty or the current cell is empty. Below is a table of every math and logical command:

Key
c current cell's value (i.e. the value of the cell being pointed to by the data pointer)
l the value of the cell to the left of the current cell
a accumulator's value
Command Stores this to accumulator:
+ l + c
- -a
* l × c
/ ⌊l ÷ c⌋
% l mod c
= 1 if l = c; otherwise 0
N or n 1 if l ≠ c; otherwise 0
> 1 if l > c; otherwise 0
G or g 1 if l ≥ c; otherwise 0
< 1 if l < c; otherwise 0
L or l 1 if l ≤ c; otherwise 0
& l AND c
| l OR c
~ NOT c
^ l XOR c

IO

gur yvsr's IO functionality is super simple: it has 2 commands for input (I and S) and 2 for output (i and s). The I command is very simple: it simply gets integer input and stores that input into the accumulator, overwriting the accumulator's previous value; it also temporarily halts the data pointer. S is more complicated: it takes in string input and then, starting from the current cell, places each byte onto the tape. If that sounds confusing, below is what the tape would look like after inputting "Hello" when the data pointer is at cell 0 (where it starts when the program starts):

Position -4 -3 -2 -1 0 1 2 3 4
Data 72 101 108 108 110

i and s are both very simple: the i command simply prints out the current cell's value, while the s command prints out the current cell's value as a UTF-8 character.

Errors

Below is a table of every error that can be thrown along with why they might be thrown:

Error Why it would be thrown
FileError
  • The file opened does not exist
  • The file contains invalid characters in its name or its contents
  • The file is not a .gur file
UnknownSymbolError

There is an unrecognized symbol that is not commented out

OpError
  • The current cell or the cell to the left of the current cell was empty when executing any one of these commands:
    • +, current and left
    • *, current and left
    • /, current and left
    • %, current and left
    • &, current and left
    • |, current and left
    • ~, current only
    • =, current and left
    • G or g, current and left
    • L or l, current and left
    • N or n, current and left
    • R, current only
    • r, current only
    • i, current only
    • s, current only
  • Division by 0 was attempted
  • The current cell's value could not be represented as a valid UTF-8 character when executing s
AccumulatorError

The accumulator was full when executing any one of these commands:

  • #
  • +
  • *
  • /
  • %
  • >
  • <
  • =
  • G or g
  • L or l
  • N or n
  • &
  • |
  • ^
  • R
  • r

or empty when executing any one of these commands:

  • -
  • T
  • t
  • J
  • j
  • K
  • k
SyntaxError
  • Two # commands have been executed in a row
  • A digit has been executed without a previously executed # command or without a previously executed digit
InputError
  • Non-integer input was enter upon executing I
  • Non-UTF-8 characters were found in string input
OutOfBoundsError
  • The code pointer got pushed or went beyond the boundaries of the program
  • The data pointer is pointing to a value that is greater than the max signed pointer-sized integer value or less than the min signed pointer-sized integer value[1]
OverflowError
  • An integer exceeded the the max signed pointer-sized integer value or went under the min signed pointer-sized integer value
CommandLineArgsError
  • More than 2 or less than 2 command line arguments were supplied

Example Programs

Hello World

#72U   `H`
#101U  `e`
#108uU `ll`
#111U  `o`
#32U   ` `
#87U   `W`
#111U  `o`
#114U  `r`
#108U  `l`
#100U  `d`
#0k    `go to cell 0`
sssssssssss. `print out characters`

Truth-machine

IU `get integer input and put it on the tape`
#2-K! `check if the input is nonzero`
#2-Ki. `if no, print a single 0`
@#0ki#9-J `otherwise, print the input infinitely`

Cat program

S `get in integer from the user`
#2-K? `repeatedly check if current cell is empty`
#2-Ks#2-K#4j `if no: print current cell's value as character and move onto next cell`
@. `if yes: end program`

Calculator

IUIUIU `get the first value, second value, and operator
(1: addition, 2: subtraction, 3: multiplication, 4: division, 5: modulus)`
    #1U#3k=a            `check if operator is addition`
C#3k#2U#3k=a            `check if operator is subtraction`
C#3k#3U#3k=a            `check if operator is multiplication`
C#3k#4U#3k=a            `check if operator is division`
C#3k#5U#3k=a            `check if operator is modulus`
.
@C#1k%U#2-Ki.          `modulus`
@C#1k/U#2-Ki.          `division`
@C#1k*U#2-Ki.          `multiplication`
@C#1kR-F_UF#1k+U#2-Ki. `gur yvsr does not have a basic
                        subtraction operation, so 
                        subtraction is more complicated`
@C#1k+U#2-Ki.          `addition`

Appendix

This section will list extra information that you might want to keep in mind when programming in gur yvsr.

What halts the data pointer? What doesn't?

Only these commands temporarily halt the data pointer:

  • #
  • 0 through 9
  • K
  • k
  • I

Implementations

No implementation yet.

External Resources

The song this esolang was named after

  1. [1] Essentially referring to this.