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.

PyStacky

From Esolang
Jump to navigation Jump to search
PyStacky
Designed by User:NTMDev
Appeared in 2026
Memory system Stack based
Dimensions One Dimensional
Computational class Turing complete
Reference implementation Implementation
Influenced by Python
File extension(s) .txt
This is still a work in progress. It may be changed in the future.

This wiki is consistent with the most recent github commit

Introduction

PyStacky, or Stacky, is an esoteric stack-based language built on Python 3.13. It contains a custom user interface for viewing the global and local stacks during execution, and also local variables.

The github repo, where all download and other more technical information is here

Please report any issues in the issue tracker on github rather in this wiki. This wiki is a documentation for PyStacky, not the issue tracker.

User Interface

After the compiler has successfully parsed and compiled the program, a tkinter widget window will open. The main widget UI has 5 buttons: Run, Step, Reset, Rerun, and Reload.

Run

This button simply runs the program, stepping through the program at 5ms per instruction. Also, this button changes to Pause when the code is running, so you can pause the program while it is running

Step

Step through exactly one instruction per press

Reset

Stop the program and go back to the very start of execution

Rerun

Reruns the program. This feature actually instantly progresses through all instruction steps

Reload

Reload the currently loaded file to apply any changes made to the file. If there were no differences between the refreshes, the console will send out a warning

Loading Code

To load and execute a PyStacky program, you must first create a .txt file in the scripts directory. It should be in the main zip file you downloaded from github. To test that the compiler is working, enter example as the file name upon execution of the compiler (PyStacky.py). It should output a string, namely "Hello, I am a function!".

Comments

To create a comment, use //

Instructions

PyStacky has a fairly small instruction set, with only 14 distinct instructions. Any other functions have been written in Python and directly interact with the internal stack (called native functions), through Natives._push and Natives._pop.

Documentation Structure

Structure: The arguments this instruction takes, and their definition

Functions: What the instruction(s) do

... Additional Information Here ...


Push and PushLocal

Instruction: push, pushlocal

Structure:

Arguments Definition
Value Any valid PyStacky value

Functions:

Function Usage
Push Pushes Value to the global stack
PushLocal Pushes Value to the local stack

Note: The Push function has two different styles, a global and local style.

Pop and PopLocal

Instruction: pop, poplocal

Structure:

Arguments Definition
VariableOptional Predefined variable that can be accessed at the scope the instruction can access. This argument is optional.

Functions:

Function Usage
Pop Pops a value off of the global stack, optionally into a variable. If the VariableOptional argument is not set, discards the value.
PopLocal Pops a value off of the local stack, optionally into a variable. If the VariableOptional argument is not set, discards the value.

Note: The Pop function has two different styles, a global and local style.

Define and DefineGlobal

Instruction: define, defineglobal

Structure:

Arguments Definition
Name Name for the variable
Value Any valid PyStacky value

Functions:

Function Usage
Define Defines a new variable in the local scope, if it does not exist yet
DefineGlobal Defines a new variable in the global scope

Note: The Define function has two different styles, a global and local style.

Set and SetGlobal

Instruction: set, setglobal

Structure:

Arguments Definition
Name Name of the variable
Value Any valid PyStacky value

Functions:

Function Usage
Set Sets the value of the variable Name to Value in the scope, if it exists in the local stack
SetGlobal Sets the value of the variable Name to Value in the scope, if it exists in the global scope

Note: The Set function has two different styles, a global and local style.

Call

Instruction: call

Not to be confused with CallNative and CallLocalNative

Structure:

Arguments Definition
FunctionReference Name or variable of the function to be called
{Arguments...} Many values; as many as you need to be able to fulfill every argument of the FunctionName function

Function:

Function Usage
Call Calls the function. The instruction will immediately step to the function called, and returns back to the caller function when the function reaches the end of the function with End, or is terminated with Exit

End

Instruction: end

Structure:

Arguments Definition
N/A This instruction does not require arguments

Function:

Function Usage
End An instruction to indicate the end of an If-Elif-Else, Loop, or Function statement. This is necessary to avoid a SyntaxError from the compiler

CallNative and CallLocalNative

Instruction: callnative, calllocalnative

Structure:

Arguments Definition
NativeFunctionName Name of the native function
{Arguments...} Many values; as many as you need to be able to fulfill every argument of the NativeFunctionName function

Functions:

Function Usage
CallNative Calls a native function implemented in Python in the global scope, which adds additional functionality to Stacky.
CallLocalNative Calls a native function implemented in Python in the local scope, which adds additional functionality to Stacky.

Note: The CallNative function has two different styles, a global and local style.

Loop

Instruction: loop

Structure:

Arguments Definition
Body Body code

Example:

define x 0
loop
    push x
    callnative print
    callnative inc
    pop x
end

Function:

Function Usage
Loop An instruction to indicate a start of a loop block, which repeats indefinitely and executes code inside of Body until it is terminated by Exit

Exit

Instruction: exit

Structure:

Arguments Definition
Depth How many scopes to terminate

Functions:

Function Usage
Exit Terminates Depth amount of scopes recursively until the desired depth is reached or there are no more scopes left to terminate

Function

Instruction: function

Structure:

Arguments Definition
FunctionDefinitonName Name of the function being defined
{Arguments...} A series of named arguments for the function

Example:

function foo(a, b)
    push a
    push b
    callnative add
end

Function:

Function Usage
Function An instruction to indicate a function definition. See example code above for usage

Note: You can use functions as a value by just referencing the name. See example below for live function usage

define fooAlias foo

Apply and ApplyLocal

Instruction: apply, applylocal

Structure:

Arguments Definition
FunctionReference Name or variable of the function to be used. This may be a native function

Functions:

Function Usage
Apply Applies the container on top of the stack (either a list or tuple) to the function FunctionReference in the global scope
ApplyLocal Applies the container on top of the stack (either a list or tuple) to the function FunctionReference in the local scope

Note: The Apply function has two different styles, a global and local style.

Note: Under the hood, this invokes the call or callnative functions, depending on the actual function. If there is an issue with them, it will affect this instruction too.

Return

Instruction: return

Structure:

Arguments Definition
Value Any valid PyStacky value

Functions:

Function Usage
Return Returns the value Value to the previous function scope

Control Flow

Internal: Condition

Condition is an internal class representing any simple Boolean expression (Boolean expressions with only a comparison operator)

Structure:

Arguments Definition
Left Left node of the condition. Can be a BooleanExpression
Operator Comparison operator
Right Right node of the condition. Can be a BooleanExpression

Valid values for Operator: ==, !=, >, <, >=, <=

Internal: BooleanExpression

BooleanExpression is an internal class representing a Boolean expression

Structure:

Arguments Definition
Left The left Condition of the BooleanExpression
Operator Boolean operator
Right The right Condition of the BooleanExpression

Valid values for Operator: &&, ||

If

Instruction: if

Structure:

Arguments Definition
Condition The Condition or BooleanExpression to be evaluated
Body Body code

Example:

if a > b
    push "Greater"
end

Function:

Function Usage
If Executes the code inside Body if Condition evaluates to True

Elif

Instruction: elif

Structure:

Arguments Definition
Condition The Condition or BooleanExpression to be evaluated
Body Body code

Example:

if a > b
    push "Greater"
elif a < b
    push "Less"
end

Function:

Function Usage
Elif Executes the code inside Body if Condition evaluates to True, and if the header If statement evaluates to False

Else

Instruction: else

Structure:

Arguments Definition
Body Body code

Example:

if a > b
    push "Greater"
elif a < b
    push "Less"
else
    exit 1
end

Function:

Function Usage
Else Executes the code inside Body if the header If statement evaluates to False and all other Elif statements are False

Import

Instruction: import

Structure:

Arguments Definition
PackageName Name of the the package to be imported

Functions:

Function Usage
Import Imports a package inside of the packages directory

Extra information on usage of this instruction:

To create a package, go into the packages directory. You may see some already created built-in packages. To test that the interpreter can import packages successfully, attempt to import the package example and look for the success message in console. A package may only contain other Import instructions and Function instructions (of course, inside of the Function there may be any instruction).

Live Functions

A live function, internally represented as a FunctionInstance is a function that can be pushed, popped, stored, and called. This is useful for more complex programs, as you can manipulate when and what functions are used. Also, instead of pushing every single argument on the stack, you can use the apply instruction to apply a tuple or list of arguments to the function.

WARNING:

Attempting to create a string resembling a FunctionInstance (in other words, creating a string starting with "<FunctionInstance..." will result in a RuntimeError. Unlike creating a function with the name GLOBAL, this is disallowed.

Scopes

GLOBAL scope

Any stack entries or variable entries in this scope can be accessed anywhere, by any function. These variables are not deleted when a function ends. Functions can directly interact with this stack.

WARNING:

Attempting to name a function GLOBAL will succeed, but will corrupt the local scope tracker self.scope of Evaluator (the evaluator assumes that setting the scope to GLOBAL is exiting all functions). This will most likely cause unintended behavior involving scopes, and make scope-dependent functions like PushLocal and CallLocalNative behave incorrectly.

Local scopes

Any stack entries or variable entries in a local scope can only be accessed and modified by the owner of the scope. For example, if I called a function named foo, a local scope named foo will be registered, and only the exact instance of foo can access and modify the contents of it. All local scopes are directly displayed on the secondary tkinter widget popup.

Native Functions

A native function is a PyStacky function that is implemented in Python instead of Stacky, which adds some features that could not be created with just Stacky alone (like simple arithmetic). These functions, instead of being invoked by Call, are invoked by either CallNative or CallLocalNative. They are internally called by InvokeNative.

add, sub, mul, intdiv, div

These 5 arithmetic functions allow you to perform calculations on values on the stack.

Function Before After
add ... a b ... (a + b)
sub ... a b ... (a - b)
mul ... a b ... (a * b)
div ... a b ... (a / b)
intdiv ... a b ... (a // b)

print, printWithPop

These native functions allow you to output text into the available sys.stdout

Function Before After
print ... a ... a
printWithPop ... a b ... a

dup, swap, over, rot

Some stack manipulation functions

Function Before After
dup ... a ... a a
swap ... a b ... b a
over ... a b ... a b a
rot ... a b c ... b c a

nip, tuck, depth, pick, roll

Some more stack manipulation functions

Function Before After
nip ... a b ... b
tuck ... a b ... a b a
depth ... {...} ... {LEN(STACK)}

These functions have more complex behavior

Function Effect
pick Pushes the nth element of the stack to the top, without removing it
roll Pushes the nth element of the stack to the top, and shifting all elements down (removing the value from its original position)

Note: n in this context is the top element of the stack, and is popped off when pick or roll is called

mod, neg, abs, min, max

Some complex arithmetic functions

Function Before After
mod ... a b ... (a % b)
neg ... a ... -a
abs ... a ... (a < 0 ? -a : a)
min ... a b ... (a > b ? b : a)
max ... a b ... (a > b ? a : b)

pow, inc, dec, round

Some more complex arithmetic functions

Function Before After
pow ... a b ... (a ^ b)
inc ... a ... (a + 1)
dec ... a ... (a - 1)
round ... a b ... {ROUND(a, b)}

strconcat, strlen, substr

These functions manipulate a string on the stack

Function Effect
strconcat Joins two string together
strlen Gets the length of the string
substr Gets a substring from a string, from a start value to end, exclusive

Note: start and end in this context are elements in the stack, and is popped off when substr is called

iterlen, getelement, setelement, iterappend, iterclear

These functions manipulate iterables directly on the stack

Function Before After
iterlen ... lst ... {LEN(LST)}
getelement ... lst idx ... {LST[IDX]}
setelement ... lst idx val ... {LST[IDX] = VAL}
iterappend ... lst val ... {LST.APPEND(VAL)}
iterclear ... iter ... {ITER.CLEAR()}

delelement, iterextend, sort, iterpop

Some more functions that manipulate iterables

Function Before After
delemenet ... lst idx ... {DEL LST[IDX])}
iterextend ... lst1 lst2 ... {LST1.EXTEND(LST2)}
sort ... lst reversedOptional ... {SORTED(LST, REVERSE=REVERSEDOPTIONAL)}
iterpop ... lst idxOptional ... {LST.POP(IDXOPTIONAL)}

totuple, tolist

These two functions convert between lists and tuples

Function Before After
totuple ... lst ... tup
tolist ... tup ... lst

dump

Prints the current scope's stack to console

dictgetvalue, dictsetvalue, dictkeys, dictvalues

These native functions manipulate the contents of a map

Function Before After
dictgetvalue ... dct key defaultOptional ... {DCT.GET(KEY, DEFAULTOPTIONAL)
dictsetvalue ... dct key value ... {DCT[KEY] = VALUE}
dictkeys ... dct ... {DCT.KEYS()}
dictvalues ... dct ... {DCT.VALUES()}

Containers

A container, or iterable, is a data type in PyStacky that can hold more than one value. Also, a Map is a unique type of container since it has keys that map to values, hence the name of "map".

All containers are displayed as a string, with a prefix and then a container holding all elements of the iterable.

Lists

A list is a mutable collection of values. A list may contain any value, from a number to another list (a list in lists is called a matrix of some dimension). A PyStacky list is internally represented as a Python list, and displayed as a string:

L{Elements...}

Where the prefix, L, indicates a list.

Tuples

A tuple is an immutable collection of values, meaning its contents cannot be changed after creation in any way. Essentially, a tuple is basically a list, except it can't be modified. A PyStacky tuple is internally represented as a Python tuple, and displayed as a string:

T{Elements...}

Where the prefix, T, indicates a tuple.

Maps

A map (also known as a dictionary in some languages, like Python) is a collection of keys and values, where each unique key maps (corresponds) to a value. A PyStacky map is internally represented as a Python dictionary, and displayed as a string:

M{{keys...} : {values...}}

Where the prefix, M, indicates a map.