We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

乾坤

From Esolang
Jump to navigation Jump to search

乾坤 is a stack-based programming language designed by PSTF.

Architecture

乾坤 consists of two stacks, one is heaven (乾), and another is earth (坤). We'll also call them A and B.

It also includes an implicit return stack (used for function calls and loop jumps), which is invisible to the programmer and not used for data storage.

Elements in the stacks are dynamic types: they support integers (of any precision) and UTF-8 strings.

Instruction Set

Stack Manipulation

入乾

Argument: x.
Meaning: Push x to stack A.

入坤

Argument: x.
Meaning: Push x to stack B.

弃乾

Argument: None.
Meaning: Pop and discard the top element of A.

弃坤

Argument: None.
Meaning: Pop and discard the top element of B.

乾入坤

Argument: None.
Meaning: Pop the top element from stack A and push it onto stack B.

坤入乾

Argument: None.
Meaning: Pop the top element from stack B and push it onto stack A.

复乾

Argument: None.
Meaning: Copy the top element of stack A and push it into stack A again.

复坤

Argument: None.
Meaning: Copy the top element of stack B and push it into stack B again.

换乾

Argument: None.
Meaning: Swap the top and 2nd element of stack A.

换坤

Argument: None.
Meaning: Swap the top and 2nd element of stack B.

深乾

Argument: None.
Meaning: Get the number of elements currently in stack A and push it onto stack A.

深坤

Argument: None.
Meaning: Get the number of elements currently in stack B and push it onto stack B.

Arithmetics

All the following commands are performed on stack A. First, pop the top two elements (the second-to-top is a, the top is b), then perform the operation, and finally push the result back onto stack A.

加 pushes a+b, 减 pushes a-b, 乘 pushes ab, 除 pushes the quotient of a/b, 余 pushes a mod b, and 负 pushes -a (where it only pops one element called a).

Comparison and Logical Operations

All the following commands are performed on stack A. Any non-null value can be treated as true and 0 or "" can be treated as false.

大于 pushes if a>b, 小于 pushes if a<b, 等于 pushes if a=b, 与 pushes a AND b, 或 pushes a OR b, 另 pushes a XOR b, and 非 pushes NOT a.

Control Flow

循环

Mark of infinite loop.

再循环

Mark of infinite loop block end.

跳出

Break.

跳出若

Break if A.top≠0, and pop A.

Do the code below if A.top≠0, otherwise run code block in 否则 instead. If 否则 not found, jump to 结束若.

结束若

Endif.

I/O

读字符

Reads a character in UTF-8 and pushes its Unicode to A. EOF returns 0.

写字符

Prints a character with the code of A.top and pop A.

读行

Reads a line of character and pushes the entire string to A.

Pop and write A.top as string.

写行

but ended with a newline. The newline is treated as volatile by platform, such as on Windows it outputs the content followed by \r\n.

Program Structure

开始

Marks the start of the program.

结束

Halts.

定义 [请输入文本]

Starts to define a subroutine.

结束定义

End of definition.

When calling a custom subroutine, you can just write its name directly (like 阶乘).

Syntax

  • Literals:
    • Integers: -?[0-9] (like -42, 1024)
    • Strings: wrapped in double quotes, like "Hello", supporting escapes \", \\, \n, \t, \r, and \0
    • Character literals: wrapped in single quotes, like 'A', parsed as its Unicode code point (integer)
  • Separators: space, newline, tab.
  • Comments: Everything after # until the end of the line is ignored.

Turing Completeness Proof

乾坤 is Turing complete for it has these features:

  • Infinite storage: Two stacks can dynamically expand to any depth. By alternately popping elements from stack A and pushing them into stack B (and vice versa), you can simulate addressing and moving like a 'tape'.
  • Conditional branching: 若 / 否则 / 结束若 If achieve conditional jumps.
  • Loops and conditional exits: 循环 + 跳出若 If can be used to construct a while(condition) structure (break when the condition is true, equivalent to while(!cond)).
  • Recursive subroutines: Define supports nested calls (return stack maintains return addresses), allowing simulation of any recursive function (like factorial or the Ackermann function).

Based on the above, you can write a Brainfuck interpreter or μ-recursive functions, so this language is Turing complete.

Example Programs

Factorial

定义 阶乘
    复乾                    # 复制 n
    1 入乾                  # 压入 1
    大于                    # 判断 n > 1 ?
    若
        复乾                # 复制 n
        1 入乾 减           # n - 1
        阶乘                # 递归调用 (n-1)!
        乘                  # n * (n-1)!
    否则
        弃乾                # n == 1 时丢弃原 n
        1 入乾              # 压入返回值 1
    结束若
结束定义

开始
    5 入乾
    阶乘                    # 计算 5!
    写行                    # 输出 120
结束

Design Philosphy and Implementation Keys

  • Naming inspiration: Taken from the I Ching "乾为天,坤为地", the two stacks are like heaven and earth supporting each other, carrying all things (data).
  • Type handling: For arithmetic operations, if a string is encountered, it will try int(str, 10) conversion; if it fails, a runtime error occurs. String concatenation isn't provided yet, but you can combine outputs through consecutive commands.
  • UTF-8 guarantee: 读字符/写字符 strictly handle variable-length encoding, ensuring characters like Chinese and Emoji are transmitted without loss.
  • Execution model: The interpreter reads the source code, recognizing Chinese character commands and literals. Control flow instructions directly manipulate the instruction pointer (IP), while subroutine definitions are stored in the symbol table and executed when called.

Summary

乾坤 uses a double-stack as its storage backbone and pure Chinese characters as operation instructions. It keeps the simplicity and efficiency of stack-based languages like Forth while also being readable thanks to Chinese programming. By combining conditional checks with recursive definitions, it fully covers all the capabilities needed for a Turing machine, and its native UTF-8 I/O design makes it super handy for modern text processing.

Categories