Pancode

From Esolang
Jump to navigation Jump to search

Pancode is a stack-based esoteric programming language written by User:Mercerenies, with the goal of fully embracing and utilizing the Unicode character set for various commands.

Overview

Pancode is a stack-based esoteric programming language, which takes input as a sequence of commands. With the exception of a handful of special forms, most commands are single characters. For instance, the following Pancode program would add the two numbers 1 and 2

1 2 +

In general, whitespace is optional in Pancode, unless necessary to disambiguate tokens which would otherwise be combined, so in the above example the first space is required but the second is optional.

What follows is a general overview of the Pancode language, while more comprehensive documentation is available on the official website.

The basic syntactic form of Pancode is a command. A program consists of a sequence of commands, which will be executed in order. Comments are delimited by « and » and are ignored by the parser.

The most basic commands are literals, which simply push themselves onto the stack when executed. Literals can be integers (10, 55, -23), strings ("foobar"), or a handful of special constants ( for infinity, -∞ for negative infinity, or 👿 for NaN). The other special form of command is a function, which wraps some sequence of commands and, when called later, executes those commands. Functions can also be used as arguments to while loops and other control constructs to execute a function multiple times. Functions are delimited with square brackets [ and ]. The following program pushes a function onto the stack which, when called, adds two numbers together.

[+]

We can call a function with $

1 2 [+] $ « Result: 3 »

Aside from literals, functions, and a few other uncommon special cases, most commands have single-character names and built-in behavior. Note that many commands can also take numerical modifiers to specify the arity. You've already seen the + command, which adds two numbers together, but it can be extended to add an arbitrary number of values together by suffixing a numerical modifier. Numerical modifiers are the Unicode circled-number characters , , , , etc.

1 2 3 +③ « Result: 6 »

Lists can be constructed by wrapping the requisite values in curly braces { and }. Note that this is not a special syntactic form: { and } are two separate commands whose syntax happens to resemble a composite form.

{1 2 3 4} « A list with four elements »

Since { and } are simple commands, you're free to perform arbitrary computations during list construction.

{10 20 15 15 + 40} « Result: {10 20 30 40} »

Primitive control flow constructs are provided, such as i (if statements), w / W (two variants of a while loop), and (repeat loop). The value 0 is the only falsy value in Pancode; any nonzero number, and any value which is not a number, is always considered truthy. Commands which return Booleans will always return "canonical" Booleans, i.e. they will return 0 for false and -1 for true. Since Booleans are simple numbers, Boolean arithmetic can be done with bitwise operators: for "and", for "or", ¬ for "not".

Recursion can be implemented using the s command, which pushes the currently-executing function onto the stack. The following is a simple infinitely-recursive function. If called, this function will eventually produce a stack overflow.

[s$]

Sample Programs

Hello World

The following program prints "Hello, world!" to the screen and exits.

"Hello, world!" .

Factorial

The following program reads one nonnegative integer from the user and prints out the factorial of that integer.

{,ī⍳} 1+ `×/ .

First, we take a single numerical input from the user (,), then we push all of the values from 0 up to (and excluding) that value onto the stack ī⍳. Next, we wrap all of those values into a list { ... }. After adding one (1+), we have a list of numbers from 1 to the user input value. Finally, we fold the list, multiplying the elements together (`×/) and print the result (.).

Fibonacci Sequence

The following program reads one integer (N > 1) from the user and prints out the first N terms of the Fibonacci sequence.

{0 1 , 2- [ % :② + ] ⍳} .

First, we push the initial conditions onto the stack (0 1). Then we get input from the user and subtract 2 (since we want to produce N-2 additional Fibonacci values, excluding the two initial conditions) (, 2-). Then we run a particular function N-2 times ([ ... ] ⍳). Within that function, we discard (%) the iteration variable (we don't need it for the purposes of this computation). Then we take the top two values on the stack, duplicate them both, and add them, pushing the result onto the stack (:② +). Finally, once we've finished iterating, we wrap the result in a list and print the list ({ ... } .).

Turing-completeness

Pancode is Turing-complete. It is possible to encode any Brainfuck program in Pancode, using the following algorithm.

We'll encode the brainfuck tape using three values: the current value, a list of values to the left, and a list of values to the right. To start with, we prefix our program with

{} {} 0

so that the top element is the current tape value, the second-from-top element is left-of-tape, and the third-from-top element is right-of-tape. With all of this in mind, the following encodings suffice.

Brainfuck Code Equivalent Pancode
. :ℓ💬.
, 📜💬0n
+ 1+
- 1-
< @②∷@:🗋[0][:0n[1⧏]D]i
> @∷@:🗋[0][:0n[1⧏]D]i[@]D
[...] [:][...]w

The official repository contains a Ruby script which performs this conversion, demonstrating Turing-completeness.

Links