From Esolang
Jump to navigation Jump to search
Paradigm(s) Imperative
Designed by User:BN
Appeared in Category:2020
Memory system stack-based
Computational class Turing complete
Reference implementation GitHub
File extension(s) .tier

Tier is a stack-based, three-dimensional programming language, created in 2019/2020 by BN.

This language is inspired by the Befunge programming language, in the sense that it is stack based and enables unconventional program flow. However unlike Befunge, Tier allows programs to be developed in three dimensions, by stacking tiers of executable files in the same 3D space as each other. Program flow can be directed up and down through these tiers (this behaviour allows the user to write functions with entry and exit points from certain tiers).


Each program is contained in a single directory (which should be named to identify the program). Program files should be created using the .tier extension, and should be given names composed of numbers (e.g. 0.tier, 1.tier) for use when referenced in programs.


Each program will be with the following items:

Item Description
pc The program counter. This is used to step through the program. Instructions at the current program counter position are executed. pc is updated with current velocity every timestep.
vel Velocity. This is the current velocity of pc (right, left, up, down).
ts Temporary storage. This is a storage element which is common and accessible to all tiers, and can only hold one value at a time. Items which are evicted from stacks (e.g. by popping or inserting another item at current position), are evicted into ts, replacing its previous value.

Programs should begin execution from the 0th tier (i.e. inside 0.tier), with a velocity heading towards the right hand side of the file. If the program counter exceeds the edge of the tier, it will wrap around back to the other side and continue execution. The height and width of all tiers is determined by the largest height and width of all files that make up the program.


Programs are made of 'tiers' which can be thought of as flat, bounded planes containing instructions, aligned directly on top of each other in a 3D space. Each tier maintains its own memory stack, which can store either numbers (float or int) or strings as values at each index. This stack can have indices extending from -infinity to +infinity, and default every index contains the integer value of 0.

Each tier also has its own stack pointer, sp. This stack pointer does not track the top of the stack, and is instead used by the programmer to traverse the stack. Many instructions are executed with respect to the stack pointer, as outlined below


Controlling pc/vel

At every timestep, the pc will first execute the instruction at its current location, and then will take one step in the direction (right, left, up, or down) determined by its velocity.

Instruction Operation
> velocity right
< velocity left
^ velocity up
_ velocity down
@ jump to specified tier
# end program

Jumping from tier to tier can be done by placing the address of the desired tier after an @ sign. For example: @413 will jump pc to the corresponding position of the @ sign in tier 413.

Controlling sp

The stack pointer 'sp' for each tier is initialised with a value of 0, and can be modified with the following commands:

Instruction Operation
[ increment sp
] decrement sp

Handling ts

The temporary storage location 'ts' for the program is initialised with an integer value of 0, and can be modified in a number of ways.

  • ts is used to store any values which are evicted from the stack. Any time a new value is inserted into the stack, the previous value at that index is evicted. (Remember all indices are occupied by an int 0 by default).
  • Values can be directly stored into ts by instruction.

The following instructions will affect ts in some way:

Instruction Operation Effect on ts
~ push the value in ts on top of the stack. ts becomes 0 again, as 0 has been evicted at 'stack top +1' position
( copy value from current position at stack to ts ts = stack[sp]
) copy value from ts to current position at stack stack[sp] = ts
, put the value of sp in ts ts = sp
! replace value at stack[sp] with its boolean NOT the initial value at stack[sp] is evicted to ts
: pop item at current stack pointer. shift any items in stack above sp downwards to fill space the initial value at stack[sp] is evicted to ts
$ pop the item off the top of the stack* the popped value is evicted to ts
'<number>' item will be stored as a number at stack[sp]. stored as either float or int. e.g. '123' the previous value at stack[sp] will be evicted to ts
"<string>" item stored as a string at stack[sp] e.g. "hello" or "123" the previous value at stack[sp] will be evicted to ts

*Note that the top of the stack is found as the max(sp, highest inserted value)

Input received from stdin will also evict the previous value of stack[sp] to ts. (see Input/Output section below)

Artithmetic instructions

All of these instructions operate in virtually the same way. The expression is evaluated in the form of: stack[sp] {operator} stack[sp-1], and the result of this expression is pushed on top of the stack.

Instruction Operation
+ addition. stack[sp] + stack[sp-1]
- subtraction. stack[sp] - stack[sp-1]
* multiplication. stack[sp] * stack[sp-1]
/ division. stack[sp] / stack[sp-1]
\ floor division. stack[sp] // stack[sp-1]
% modulo. stack[sp] % stack[sp-1]
& binary AND. stack[sp] & stack[sp-1]
| binary OR. stack[sp] | stack[sp-1]

Branching/Conditional execution

The following instructions enable conditional execution to occur:

Instruction Operation
= check if stack[sp] == 0, and if so, then skip next the next instruction
` randomly place a 0 or 1 at stack[sp]
? check if stack[sp] > stack[sp-1] and if so, then skip the next instruction


I/O is achieved through the following instructions:

Instruction Operation
{ print stack[sp] to stdout
} read a value from stdin and place this into stack[sp]. evict previous value of stack[sp] to ts

When input is read, the default type of the value will be a string. Therefore, to allow the user to input numerical types, the user should enclose the input with ' characters. e.g. '1234'

Other characters

Character Operation
a-z A-Z 0-9 these are ignored unless enclosed within '', "" or after @
; used to write comments. lines that start with ; should be treated as entirely whitespace by the interpreter/compiler
SPACE NOP (Non Operational). no effect
. NOP (Non Operational). no effect, but useful for outlining/indenting relative positions within files

Example programs

Basic examples

Hello World


"hello, world!"{#

Truth machine

If input is integer 0, output 0 and terminate. If input is integer 1, then output 1 forever.




Copy input to output.




Infinitely generate Fibonacci numbers.





Complex examples

Prime numbers

User inputs a number, program will correctly respond with 'Prime' or 'Not Prime'


}(^          1@           <


"Enter a number to check if prime:\n"{_
@0            >"Not prime\n"{#        >


        >         ^





Approximate e

Infinitely output increasingly accurate approximations of the mathematical constant e (2.71828...)


1@[)]$+]:{"n\"{:{" ~ e":[<


>$[@0    .....>_....@0 ~=_[_..._<
$>_           :]....2@[:]<.@....[
$.]           *].2@.('1'_=<2@([<=
$.]           ^.[~([~:].<...2@[[.<
^$<           .>]'1'[-[[[(:]]])?^^


         .....     >@0>@0>_
             .    _..>...^@_
             .    _^......1<_

Boolean XOR function

Outputs the boolean XOR of stack[sp] and stack[sp-1]


       >   ](@1[(@1~[{#


             ).@0~[_      2@([&<._|]]<
                     >['0'^   >[[['0'^


                  >@0      _

External resources


I've made an interpreter for programs written in this language, which is available on my GitHub account[1] - go and check it out!

The interpreter is a single python file, and features helpful tools such as:

  • A built-in visual debugger tool which allows fast and easy debugging of Tier programs.
  • The option to specify the duration of each timestep when running.
  • The option to print out debug information to console at each timestep.

-BN (talk) 03:17, 2 January 2020 (UTC)