Execode

From Esolang
Jump to navigation Jump to search

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.

Execode
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 repeats 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
...

See also

External resources