Flipscript

From Esolang
Jump to navigation Jump to search

Overview

flipscript is an esoteric programming language that centers around conditionally reversing the program execution direction. It is currently unimplemented, with an interpreter in the making. In flipscript, programs are written line by line in a text file with a .flip extension. You cannot have multiple statements on one line, and lines cannot exceed 4000 characters. Program execution can either go upwards or downwards. Programs terminate when either the top or bottom of the file is reached, or when the stop command is encountered. Additionally, programs may terminate due to runtime errors. All error checking in flipscript is done at runtime. Empty lines do nothing in flipscript.

start statement

Every flipscript program starts at the start statement:

start(direction)

Where direction is either 0 or 1. 0 means the program starts executing downwards, 1 means upwards. The start statement can be any line in the program, it doesn’t have to be the first line. If the program contains more than one start statement, the program will start at the one closest to the top. Every flipscript program must contain the start statement. If the start statement is encountered during execution, it doesn’t do anything. It is incompatible with modifiers.

Example usage:

start(0)

up and down modifiers

In flipscript, if a statement has the up or down modifier, that line only executes if the program flow is up or down respectively:

up statement
down statement

Lines cannot have both the up and down modifiers. The up or down modifier precedes the decay modifier.

Example usage:

up flip(1==1) 

decay modifier

You can specify the maximum number of times a statement can be executed with the decay modifier:

decay(num) statement

decay is placed after up or down if the line is using those modifiers. decay takes an argument of type num, where the floor of that num must be equal to itself. That is to say, the argument cannot have a non-zero decimal component. A statement's decay decreases by one each time that statement is encountered, including the first time. Once this value becomes less than 1, that statement is no longer executed. The decay modifier is not compatible with the start statement. Note that the decay is set when the statement is first encountered, and does not track with variables subsequently.

Example usage:

decay(10) jump 20

stop statement

In flipscript, the program stops when it reaches the top or bottom of the file. Additionally, it will stop when it encounters the stop statement:

stop

Example usage:

stop

variables and data types

In flipscript, there are two data types. num and string. num represents a number. It can have a decimal component. string represents text, and is enclosed by double quotes. The size of the data type is dependent on the implementation. Variables are declared and assigned at once, and cannot be used prior to being assigned. You must specify the type every time you assign or reassign the variable:

type NAME = value

Variable names must contain only uppercase letters. Variables of different types cannot have the same name. Variables can be assigned input to collect input from the user.

Example usage:

string USERNAME = input

This causes a runtime error if the user inputs data that doesn’t match the type. Variables can be dynamically created and referenced. By adding parentheses to the end of a variable you can put a num within them to be appended to the end of the name.

type NAME(num) = value

This can be used to replicate the functionality of data structures like arrays found in other languages.

Example usage:

start(0)
num I = 0
up flip(1==1)
down num ARRAY(I) = I
down num I = I+1
flip(I<10)

operators

In flipscript the = operator is used only in variable assignment. Conditional operators can be used only in flip statements. strings only support the $= and $!= operators. strings and nums cannot be compared. Below are all conditional operators:

Conditional Operators
Operator Function
x==y True if x is equal to y. (num)
x>y True if x is greater than y. (num)
x<y True if x is less than y. (num)
x>=y True if x is greater than or equal to y. (num)
x<=y True if x is less than or equal to y. (num)
x!=y True if x is not equal to y. (num)
x$=y True if x is equal to y. (string)
x$!=y True if x is not equal to y. (string)
x||y True if either x or y are true. Inclusive or.
x&&y True if both x and y are true.

Conditional operators are evaluated from left to right. So a||b&&c is evaluated like (a||b)&&c. In flipscript, you can never have spaces when using operators other than the assignment operator =. For doing math on nums, flipscript has the following math operators:

Math Operators
Operator Function
x+y Adds x and y.
x-y Subtracts y from x.
x*y Multiplies x and y.
x/y Divides x by y.
x%y Returns the remainder of x divided by y.

flipscript evaluates expressions from left to right, and doesn’t support parentheses. 8+2*10 is equivalent to 100, not 28.

Example usage:

start(0)
num INPUT = input
num ISEVEN = INPUT%2
up stop
up output("The number is even",new)
flip(ISEVEN==0)
output("The number is odd",new)

flip statement

The flip statement reverses the program flow if the condition is true.

flip(condition)

Example usage:

start(0)
string PASSWORD = input
num SECRETCODE = input
up stop
up output("Access Denied!",new)
down flip("Password123"$!=PASSWORD||SECRETCODE!=123)
output("Secret data!",new)

output statement

The output statement is used to output information:

output(data,data,...)

The statement concatenates the data separated by commas and then prints it. Each piece of data can be a num or a string. Additionally, new outputs a newline.

Example usage:

output("Hello"," World!",new,"6 + 7 is equal to: ",6+7,new)

jump statement

The jump statement jumps the program execution by a specified number of lines in the current execution direction:

jump num

Where the num is whole and positive. The line it jumps to gets executed and program flow continues as normal. If the line is outside the bounds of the file the program terminates.

Example usage:

num JUMP = input
jump JUMP
output("1",new)
output("2",new)

comments

Error checking in flipscript is done line by line at runtime, so any line that the program never encounters is never checked. Because of this, you can place comments on unreachable lines. This behaviour is somewhat implementation defined, and lines with modifiers may additionally not be error checked if they are not being executed.

Example usage:

This program was written by Bob the Builder!
It adds two numbers, and has comments on unreachable lines!
start(0)
num ONE = input
num TWO = input
output(ONE," + ",TWO," = ",ONE+TWO,new)

Example Program

Below is a brainfuck interpreter written in flipscript. This serves as both an example of how to use the language and a proof of Turing completeness.

stop
output("Error",new)
flip(LOOPCOUNT>=0)
down jump 5
num LOOPCOUNT = LOOPCOUNT-1
flip(SOURCE(CODELOC-LOOPCOUNT)$="[")
down CODELOC = CODELOC-LOOPCOUNTER+1
down jump 74
down flip(1==1)
num LOOPCOUNT = 0
stop
output("Error",new)
flip(LOOPCOUNT<=SOURCECOUNT)
down jump 5
num LOOPCOUNT = LOOPCOUNT+1
flip(SOURCE(CODELOC+LOOPCOUNT)$="]")
down CODELOC = CODELOC+LOOPCOUNT+1
down jump 64
down flip(1==1)
num LOOPCOUNT = 0
flip(1==1)
down jump 39
num DATALOC = DATALOC-1
flip(DATALOC==0)
output("Error, invalid tape location",new)
stop
flip(1==1)
down jump 29
num DATALOC = DATALOC+1
flip(DATALOC==29999)
output("Error, invalid tape location",new)
stop
flip(1==1)
down jump 12
start(0)
string INPUTEND = "yes"
num SOURCECOUNT = 0
up jump 5
up flip(INPUTEND$="yes")
down output("Enter a character in your program",new)
down string SOURCE(SOURCECOUNT) = input
down num SOURCECOUNT = SOURCECOUNT+1
down output("Enter yes if you want to continue entering your  program.",new)
down string INPUTEND = input
flip(1==1)
num TAPECOUNT = 0
up flip(1==1)
down num TAPE(TAPECOUNT) = 0
down num TAPECOUNT = TAPECOUNT+1
flip(TAPECOUNT<30000)
num CODELOC = 0
num DATALOC = 0
up flip(1==1)
up jump 24
flip(SOURCE(CODELOC)$=">")
up jump 32
flip(SOURCE(CODELOC)$="<")
up flip(1==1)
down jump 6
num TAPE(DATALOC) = TAPE(DATALOC)+1
flip(SOURCE(CODELOC)$="+")
up flip(1==1)
down jump 8
num TAPE(DATALOC) = TAPE(DATALOC)-1
flip(SOURCE(CODELOC)$="-")
up flip(1==1)
down jump 5
num TAPE(DATALOC) = 0-TAPE(DATALOC)%1+TAPE(DATALOC)
num TAPE(DATALOC) = input
output("Enter a number:",new)
flip(SOURCE(CODELOC)$=",")
up flip(1==1)
down jump 4
output(TAPE(DATALOC),new)
flip(SOURCE(CODELOC)$=".")
up jump 56
flip(SOURCE(CODELOC)$="["&&TAPE(DATALOC)==0)
up jump 68
flip(SOURCE(CODELOC)$="]"&&TAPE(DATALOC)!=0)
num CODELOC = CODELOC+1
up jump 28
flip(CODELOC<=SOURCECOUNT)