Execode
Execode is an esoteric programming language created in 2024 by User:iddi01 carefully designed to be easy to program in, easy to implement, easy to read, and to have ability in code golfing. Those are, of course, only relative, since maximizing one of them means losing the others. Execode is stack-based, although it can be considered as deque-based due to the reversing command.
Paradigm(s) | functional |
---|---|
Designed by | User:iddi01 |
Appeared in | 2024 |
Memory system | stack-based or deque-based |
Dimensions | one-dimensional |
Computational class | Turing complete |
Reference implementation | Original implementation |
File extension(s) | .ec |
Unlike most other languages, Execode focuses on functions for control flow, for the purpose of reusable code, such that, Execode programs will become shorter and shorter compared to other languages of similar complexity as the programs gets more complex.
The character of Execode is controlled minimization: It does not include any unnecessary commands and commands that don't give it more advantage over languages of similar complexity. For example, instead of having a push and pop command for both sides of the stack/deque, it uses a reversing command to reduce it to three commands. And, it has a gt
but no lt
, for < is basically > in reverse! Also, it has no arithmetic commands except for increment/decrement by 1 since they can be implemented easily using rep
eats and functions (see Techniques).
Arbitrary number of stacks, variables, and functions can be defined using the def
command. Variables and functions are essential, and you can do next to nothing without them.
Variable/stack/function names must be numbers, which will be referred to as variable/stack/function IDs.
Execode was a name of a function in the original implementation, standing for "execute code", but then the author thought it was a good name for the language.
Description
Execode commands are case sensitive, separated by newlines, and indentation is not allowed. In each command, the first three characters specify the base action, after that are the parameters, which are separated by spaces unless said otherwise.
Each line can be followed by a rpt x
where x is the number of times the line will repeat.
See Examples for how exactly the commands are used.
Commands
Increment and decrement
inc x
increases the variable with ID x by 1
dec x
decreases the variable with ID x by 1
Defining variables/stacks/functions
def
defines something. This must be used before using the given ID for something. The three types that can be defined uses separate ID, so you can, for example, have both a variable and a stack with ID 135.
def var
defines a variable initially set to 0, can also be used to set an already defined variable to 0
def stk
defines a stack, initially empty
def fnc
begin definition of a function, ends with end
, the code in between are not executed right away, but instead executes when the given function ID is called.
Push and pop
psh x to y
pushes variable ID x to stack y
pop x to y
pops one item from stack ID x to variable y, the to
and after can be skipped
Reversion
rev x
reverts stack ID x, effectively making it a deque
Function call
cll x
calls the function with ID equal to the value of variable ID x
Conditional (if statement)
con x
- if x = 0, skip the next instruction
It can be followed with eq y
, ne y
, or gt y
, which skips the next instruction if x != y, x = y, or x <= y respectively.
Input
inp x
reads one value from input and sets variable ID x to it
Output
out x
and outchr x
prints the variable ID x as number or ASCII
outstr x
and outstk x
prints the stack ID x as a string or individual numbers
Termination
ter
terminates the program, some interpreters force this
Examples
Truth machine
def var 0 inp 0 def var 1 def fnc 0 out 0 con 0 cll 1 end cll 1 ter
Hello, World!
def var 0 inc 0 rpt 72 outchr 0 inc 0 rpt 29 outchr 0 inc 0 rpt 7 outchr 0 rpt 2 inc 0 rpt 3 outchr 0 dec 0 rpt 67 outchr 0 dec 0 rpt 12 outchr 0 inc 0 rpt 55 outchr 0 inc 0 rpt 24 outchr 0 inc 0 rpt 3 outchr 0 dec 0 rpt 6 outchr 0 dec 0 rpt 8 outchr 0 dec 0 rpt 67 outchr 0 ter
A second way using input (input 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33):
def stk 0 def var 0 def fnc 0 inp 0 psh 0 to 0 end def var 1 cll 1 rpt 13 outstr 0 ter
A third way using a stack:
def var 0 def stk 0 inc 0 rpt 72 psh 0 to 0 inc 0 rpt 29 psh 0 to 0 inc 0 rpt 7 psh 0 to 0 psh 0 to 0 inc 0 rpt 3 psh 0 to 0 dec 0 rpt 67 psh 0 to 0 dec 0 rpt 12 psh 0 to 0 inc 0 rpt 55 psh 0 to 0 inc 0 rpt 24 psh 0 to 0 inc 0 rpt 3 psh 0 to 0 dec 0 rpt 6 psh 0 to 0 dec 0 rpt 8 psh 0 to 0 dec 0 rpt 67 psh 0 to 0 outstr 0 ter
Addition-only calculator *
def var 0 inp 0 def var 1 inp 1 def fnc 0 inc 3 con 1 gt 3 cll 5 end def var 5 def fnc 1 inc 4 con 0 ne 4 cll 6 end def var 6 inc 6 def fnc 2 inc 2 dec 0 con 0 cll 7 end def var 7 inc 7 rpt 2 def fnc 3 inc 2 dec 1 con 1 cll 8 end def var 8 inc 8 rpt 3 def var 2 def var 3 def var 4 cll 5 cll 6 cll 7 cll 8 def var 9 inc 9 rpt 43 def var 10 inc 10 rpt 61 out 4 outchr 9 out 3 outchr 10 out 2 ter
Modify it trivially to get a subtraction-only calculator:
def var 0 inp 0 def var 1 inp 1 def fnc 0 inc 3 con 1 gt 3 cll 5 end def var 5 def fnc 1 inc 4 con 0 ne 4 cll 6 end def var 6 inc 6 def fnc 2 inc 2 dec 0 con 0 cll 7 end def var 7 inc 7 rpt 2 def fnc 3 dec 2 dec 1 con 1 cll 8 end def var 8 inc 8 rpt 3 def var 2 def var 3 def var 4 cll 5 cll 6 cll 7 cll 8 def var 9 inc 9 rpt 45 def var 10 inc 10 rpt 61 out 4 outchr 9 out 3 outchr 10 out 2 ter
Fibonacci sequence
def var 0 inc 0 def var 1 inc 1 def var 2 def var 3 def var 4 def fnc 0 inc 2 inc 3 dec 0 con 0 cll 10 end def var 10 def fnc 1 inc 2 inc 4 dec 1 con 1 cll 11 end def var 11 inc 11 def fnc 2 inc 0 dec 4 con 4 cll 12 end def var 12 inc 12 rpt 2 def fnc 3 inc 1 dec 2 con 2 cll 13 end def var 13 inc 13 rpt 3 def fnc 4 cll 10 cll 11 cll 12 cll 13 def var 3 out 1 cll 14 end def var 14 inc 14 rpt 4 out 1 rpt 2 cll 14 ter
Looping counter
def var 0 inc 0 rpt 48 def var 1 inc 1 rpt 10 def var 2 def var 3 inc 3 def fnc 0 outchr 0 dec 5 inc 6 con 5 cll 2 con 5 eq 2 cll 3 end def var 5 inc 5 def var 6 def fnc 1 dec 6 inc 5 con 6 cll 3 end def var 4 inc 4 rpt 2 def fnc 2 cll 2 outchr 1 inc 5 cll 4 end cll 4 ter
99 bottles of beer
def var 0 inc 0 rpt 99 def var 1 inc 1 rpt 57 def var 2 inc 2 rpt 57 def var 3 def var 4 inc 4 def var 5 inc 5 rpt 48 def var 6 inc 6 rpt 10 def var 32 inc 32 rpt 32 def var 98 inc 98 rpt 98 def var 111 inc 111 rpt 111 def var 116 inc 116 rpt 116 def var 108 inc 108 rpt 108 def var 101 inc 101 rpt 101 def var 115 inc 115 rpt 115 def var 102 inc 102 rpt 102 def var 114 inc 114 rpt 114 def var 110 inc 110 rpt 110 def var 104 inc 104 rpt 104 def var 119 inc 119 rpt 119 def var 97 inc 97 rpt 97 def var 44 inc 44 rpt 44 def var 46 inc 46 rpt 46 def var 107 inc 107 rpt 107 def var 100 inc 100 rpt 100 def var 112 inc 112 rpt 112 def var 117 inc 117 rpt 117 def var 84 inc 84 rpt 84 def var 105 inc 105 rpt 105 def var 10 def fnc 0 cll 13 outchr 32 outchr 111 outchr 110 outchr 32 outchr 116 outchr 104 outchr 101 outchr 32 outchr 119 outchr 97 outchr 108 rpt 2 outchr 44 outchr 6 cll 13 outchr 46 outchr 6 cll 11 outchr 84 outchr 97 outchr 107 outchr 101 outchr 32 outchr 111 outchr 110 outchr 101 outchr 32 outchr 100 outchr 111 outchr 119 outchr 110 outchr 44 outchr 32 outchr 112 outchr 97 outchr 115 rpt 2 outchr 32 outchr 105 outchr 116 outchr 32 outchr 97 outchr 114 outchr 111 outchr 117 outchr 110 outchr 100 outchr 44 outchr 6 cll 13 outchr 32 outchr 111 outchr 110 outchr 32 outchr 116 outchr 104 outchr 101 outchr 32 outchr 119 outchr 97 outchr 108 rpt 2 outchr 46 outchr 6 rpt 2 con 0 cll 10 end def var 11 inc 11 def fnc 1 dec 0 con 0 eq 3 cll 12 con 2 eq 5 cll 12 con 2 ne 5 dec 2 end def var 12 inc 12 rpt 2 def fnc 2 con 0 eq 3 inc 2 rpt 63 con 0 eq 3 inc 1 rpt 30 con 0 inc 2 rpt 10 con 0 dec 1 end def var 13 inc 13 rpt 3 def fnc 3 con 1 ne 5 outchr 1 outchr 2 outchr 32 outchr 98 outchr 111 outchr 116 rpt 2 outchr 108 outchr 101 con 0 ne 4 outchr 115 outchr 32 outchr 111 outchr 102 outchr 32 outchr 98 outchr 101 rpt 2 outchr 114 end cll 10 ter
Deadfish interpreter
def var 0 def var 1 def var 2 def stk 0 def fnc 105 inc 0 end def fnc 100 dec 0 end def fnc 111 out 0 end def fnc 115 psh 0 to 0 pop 0 to 2 psh 2 to 0 dec 2 con 2 cll 10 end def var 10 def fnc 0 pop 0 to 1 psh 1 to 0 cll 11 dec 2 con 2 cll 10 end def var 11 inc 11 def fnc 1 inc 0 dec 1 con 1 cll 11 end def var 12 inc 12 rpt 2 def fnc 2 inp 20 cll 20 con 0 eq 256 def var 0 con 0 eq -1 def var 0 cll 12 end def var 20 def var 256 inc 256 rpt 256 def var -1 dec -1 cll 12 ter
Bitwise Cyclic Tag interpreter **
def stk 0 def var 0 def var 1 def var 2 def stk 1 inc 0 psh 0 to 1 def fnc 0 outstk 1 pop 0 to 0 rev 0 psh 0 to 0 rev 0 con 0 eq 2 pop 1 cll 0 end def fnc 1 pop 0 to 1 rev 0 psh 1 to 0 rev 0 pop 1 to 2 psh 2 to 1 con 2 cll 5 def var 2 cll 2 end def var 3 inc 3 rpt 2 def fnc 2 inp 4 psh 4 to 0 end def var 4 def var 5 inc 5 rpt 3 def fnc 3 rev 1 psh 1 to 1 rev 1 end cll 3 rpt 100 rev 0 cll 1 ter
*
Input two numbers, such as 16,35
**
Input the sequence of bits separated by commas as the program, the initial data is always 1
Computational class
The Bitwise Cyclic Tag interpreter above proves Execode Turing-complete, since storage is unbounded. The fixed size reading issue needs to be circumvented somehow.
Techniques
To truly bring out the potential of Execode, you need to know how the commands can be combined to achieve various things.
Functions
If you ran into a seemingly unresolvable problem, usually you just need to create more functions! Execode is designed around functions, and can't do much without them.
Conditional function call
So, you want to write an if statement with more than one command? Easy! Just create a new function:
con x cll x
Switch statement
The main point behind using variables to call functions is to make switch statements easier, such as:
def fnc 1 do something end def fnc 2 do something end def fnc 3 do something end def fnc x inp y cll y
See Deadfish interpreter above as an example.
While loop
To make a loop like those in bf, just do this:
def fnc x do something con y cll x end
Variables
Variables are just as important as functions in Execode, especially since they're used to call functions.
Variable IDing techniques
For longer programs, it's best to ID the variables (actually constants) used to call functions, those set to ASCII values, and those that are actually used (the actual variables) using different schemes. Also, it's best to define function-calling variables right before/after the function definition, since it's hard to predict how many functions you need while coding.
See 99 bottles of beer program above as an example.
Variable duplication
The fastest way to duplicate variables is (surprisingly) through stacks, since variables don't get affected when pushed onto a stack:
def var y def stk z psh x to z pop z to y
Addition and subtraction
See the addition/subtraction-only calculator and Fibonacci sequence programs above.
Multiplication
See Deadfish interpreter above.
Stacks/deques
PEEK
pop x to y psh y to x
DUP
pop x to y psh y to x rpt 2
SWAP
pop x to y pop x to z psh y to x psh z to x
As a queue
To use the stack/deque as a queue, use rev
whenever you're pushing or popping and your previous operation with the stack/deque is the other one:
psh y to x rev x pop x to z rev x ...