Tea

From Esolang
Jump to navigation Jump to search
Tea
Paradigm(s) Imperative
Designed by waffelz
Appeared in 2025
Memory system Stack-based
Computational class Turing-complete
Reference implementation See [1]
File extension(s) *.tea

Tea is a minimal stack-based esolang invented by waffelz on November 25th, 2025. It is titled "Tea" because he really likes tea.

Language overview

Tea operates on two separate stacks, called the primary and secondary stacks. Operations on the secondary stack are quite limited, and it is mainly intended for temporary storage for important values.

Symbol Function Needed Elements Notes
DDD... Push the number represented by digits DDD... to the stack. 0 N/A
: Duplicate the top element of the stack. 1 N/A
% Swap the top two elements of the stack. 2 N/A
! Pop the top element of the stack. 1 N/A
(...) Defines a codeblock 0 N/A
* Pop the top value of the stack and run the given code block that many times. 1 Will raise an error if there is not a code block immediately after.
+ Increment the top element of the stack. 1 N/A
- Decrement the top element of the stack. 1 Will raise an error if trying to decrement 0.
{ Pop the top element of the primary stack and push it to the secondary stack. 1 N/A
} Pop the top element of the secondary stack and push it to the primary stack. 1 (secondary) N/A
@ Run the given code block until the top of the second stack is zero, without popping it. 1 (secondary) Will raise an error if there is not a code block immediately after.

Any character not in the above table will raise an error.

Tea has a twenty-one-character alphabet (1234567890:%!*()+-{}@) and has ten commands (D:%!*+-{}@).

Errors

Tea will error if any of these conditions is met:

  • The program contains mismatched parentheses.
  • The program contains a symbol not in the alphabet.
  • The program contains a * or @ symbol that is not directly followed by a left parenthesis.
  • The - command is used when the top of the stack is zero.
  • An instruction is executed when the stack does not have enough elements.

Semantics

Because consecutive digits are treated as one number and whitespace is not allowed in any form, pushing multiple numbers in a row is a bit more complex than in other languages. In Tea, you have to include a noop in between each number. Something like :!, +-, or %% can be used, but the last one only works if there is at least 2 elements on the primary stack.

Tea has no input or output commands. The "output," similar to a Turing machine, is the final state of the two stacks. Inputs are gathered via editing the program.

Code snippets

Long code snippets have been split by every 100 characters to improve readability. All linefeeds must be removed to make the program executable.

Numbers

This snippet adds the top two numbers:

*(+)

This snippet subtracts the top two numbers, but errors if the top number is larger than the second:

*(-)

This snippet implements saturated subtraction (max(0, a-b)):

*(::*(!1):{*(-)}1%*(-)!)

This snippet multiplies the top two numbers:

0{*(:*(}+{))!}

This snippet divides the top two numbers:

:{%:{%:{%:{%*(::*(!1):{*(-)}1%*(-)!):*(!1)1%*(-)}}%*(::*(!1):{*(-)}1%*(-)!):*(!1)1%*(-)1%*(-)%1%*(-)
*(+):*(!1)1%*(-)}{0}}:{%:{%*(::*(!1):{*(-)}1%*(-)!):*(!1)}%}%{@(:{*(::*(!1):{*(-)}1%*(-)!){+}}:{%:{*
(::*(!1):{*(-)}1%*(-)!):*(!1)1%*(-):*(!1)}%}%}!{)!!}!%*(+)

Booleans

Booleans can be represented on the stack using 0 for false and 1 for true. All below snippets assume the top two elements on the primary stack are Booleans. A NOT gate can be implemented with this snippet that calculates 1-A:

1%*(-)

Using this, an if-else statement can then be represented using this snippet:

:{*(true)}1%*(-)*(false)

This snippet coerces an integer to a Boolean such that any nonzero number becomes 1, and 0 stays 0:

:*(!1)

An OR gate can be implemented with this snippet that calculates min(1,A+B):

*(+):*(!1)

Using the fact that A AND B is equal to NOT(NOT(A) OR NOT(B)), an AND gate can be implemented using this snippet:

1%*(-)%1%*(-)*(+):*(!1)1%*(-)

Other Boolean operators are easy to derive using the above snippets.

Examples

In the below programs, N represents a number input. It must be replaced with a number literal for it to be executable.

A+B problem

This program calculates the sum of the given numbers. The stack will be left with only the result.

N:!N*(+)

Truth machine

This program leaves the stack with a single 0 if the input is 0, otherwise fills it with an infinite number of 1s.

N:!0%*(!1{@(1))

Factorial

This program calculates the given number's factorial. The stack will be left with only the result.

N::*(!1)1%*(-):{*(!1)}1%*(-)*(::{*(:-)!}-*(0{*(:*(}+{))!}))

Fibonacci Sequence

This program calculates the given number of terms of the Fibonacci sequence. The stack will contain them in order from bottom to top.

N:{:*(!1)*(0)}::*(!1)*(-):::*(!1)*(-){:*(!1)*(1)@(:{%:{%}}*(+)}-{)}!

Computational class

Compilation from brainfuck

Tea is Turing-complete because it can be compiled to from any 3-cell non-wrapping brainfuck program with unbounded cells using the conversion table below. Executing the - command on a cell whose value is 0 leaves the cell unchanged.

Program must start with 0{0{0{
 <: }}%}%{%}%{{{
 >: }}%}%{{{
 +: }+{
 -: }::*(!1)*(-){
 [: @(
 ]: )

Because of these conversions, Tea is Turing-complete.

Cyclic tag system

This program was created by RainbowDash.

It simulates a Cyclic Tag System. The . symbol represents a print symbol, which is a placeholder to represent a print instruction (printing is not needed for Turing-completeness, so these can be removed.). This program also contains linefeeds, which will have to be removed to make the program executable.

0{2{0{}@({
}@(})-*({@({)}2){{@({)}{.
}@(})-*({@({)}2:!1:!2){{@({)}{.
})

There are padding zeros on the left and right, which are to be ignored. As for the memory, the zeros are converted into ones, and the ones are converted into twos. This program implements the ruleset [1, 101] (which becomes [2, 212] after modifications). If you are editing this yourself, each rule also has to be in reverse when input into the program, so 011 would be converted to 122, then, finally, 211.

Below is the executable program.

0{2{0{}@({}@(})-*({@({)}2){{@({)}{}@(})-*({@({)}2:!1:!2){{@({)}{})

This also proves Tea's Turing-completeness.

External resources