MEMORYLEEK

From Esolang
Jump to navigation Jump to search
MEMORYLEEK
Paradigm(s) Procedural, imperative
Designed by User:Aadenboy
Appeared in 2024
Memory system Pointer-based dynamic memory
Computational class Turing complete
Major implementations None
Influenced by None
Influenced None
File extension(s) .ml
Not to be confused with memory leaks.

MEMORYLEEK (also called "MEMLEEK" and "MLEEK") is a pointer-based language designed to maximize memory leakage.

Memory Structure

The memory of MLEEK is split into two arrays: a linear array of integer values and an associative array of pointers to those values.

MLEEK has no garbage collection. Values remain created until explicitly removed with a pointer. All operations and expressions are evaluated eagerly, meaning they are calculated when first encountered. This causes significant bloat in value memory.

Pointers, when first created, are "inactive pointers," meaning they don't point anywhere. They return a value of zero but don't imply any value. Pointers reference a value with an index, which updates automatically if an earlier value is removed or if the referenced value is removed. Dangling pointers and cyclic references are not possible.

The program checks if you have properly managed your memory at certain points:

At the end of the program's execution
The program expects that your memory is fully clean and void of any references or values.
At the end of a function call
The program expects that any values and references created within the call are removed.
Before a loop restarts
The program expects that any values and references created within the loop before the restart are removed.

Handling Expressions

Expressions and operations are evaluated eagerly, meaning they are processed as soon as they are encountered. Values are created when not yet defined, causing significant bloat within value memory.

The steps for performing an equation are as such:

  1. Go through each value within the equation.
    • If the value is a pointer, replace the value with whatever the pointer references.
    • If the value is a value, place the value into memory.
  2. Evaluate operations.
    • After completing an operation, leave the original values alone and create a new value with the result, storing it in memory.
  3. Repeat until no operations are left.

For example, take (a % 5)^2 (where a points to a value of 7):

  1. (a % 5)^2 — Check and replace values.
    • a is replaced with 7. 5 and 2 are stored in memory.
    • Value memory: [7, 5, 2]
  2. (7 % 5)^2 — Compute (7 % 5).
    • The result is 2. Replace the operation with the result and store it in memory.
    • Value memory: [7, 5, 2, 2]
  3. 2^2 — Compute 2^2.
    • The result is 4. Replace the operation with the result and store it in memory.
    • Value memory: [7, 5, 2, 2, 4]
  4. 4 — Finish here.

Instructions

Instructions are separated with semicolons or newlines. An equation on its own will be considered an instruction and computed.

Instruction Name Description
point [n] Make pointer Creates a new pointer under the name [n].
value [v] Make value Creates a new value with the value [v].
[p] = [o] Assign Syntactic sugar for [o]; [p] ~> -1
[p] ~~ [v] Reassign Reassigns the value [p] points to with a new value [v]. This instruction does not create a new value, but also cannot perform operations.
[p] ~> [i] Point to Points pointer [p] to the value with index [i]. If [i] is negative, it instead points to the value with index (total values) - [i]. This instruction does not create a new value, but also cannot perform operations.
#[p] Remove value Removes the value the pointer [p] is pointing to.
:[p] Remove pointer Removes the pointer [p].
}[f] [...] Function call Calls the function [f]. [f] is a value (or pointer pointing to a value) which denotes the line to jump to. [...] are the values to pass.
pass Pass Skips instructions until an exit or back loop instruction is met.
pass [p] Named pass Like the pass instruction, but it also creates a pointer with a value referring to the line it’s at.
exit Exit Exits a function call or condition.
expect [n] Expect values Used by functions. Asserts if the amount of values given to a function call equals [n].
until [c] Until condition Creates a condition that checks if [c] is equal to 0. If it is not equal to 0, it skips instructions until an exit or back loop instruction is met.
back Back loop Loops back to the previous until condition.
![v] Print number Prints the value [v] to the screen as a number. This will create a value if possible.
?[v] Print symbol Prints the value [v] to the screen as it’s corresponding UTF-8 character. This will create a value if possible.
input Take input Asks the user for input. The UTF-8 codes of each character are created.
input [m] Constrained input Like the take input operation, but the characters that are passed are limited to only [m] characters.
vnput [p] Value input Like the take input operation, only it takes in a single number and points the pointer [p] to it.
[v1] + [v2] Addition operation Adds [v1] and [v2] together, creating a new value with the result.
[v1] - [v2] Subtraction operation Subtracts [v1] against [v2], creating a new value with the result.
[v1] * [v2] Multiplication operation Multiplies [v1] with [v2], creating a new value with the result.
[v1] / [v2] Division operation Divides [v1] against [v2], creating a new value with the result.
[v1] % [v2] Modulo operation Performs modulo on [v1] and [v2], creating a new value with the result.
[v1] ^ [v2] Exponentation operation Raises [v1] to the power of [v2], creating a new value with the result.
$[v1] Logical NOT operation Creates a new value 1 (true) or 0 (false) if [v1] is equal to 0.
$$[v1] Bitwise NOT operation Performs bitwise NOT on [v1], creating a new value with the result.
[v1] & [v2] Logical AND operation Creates a new value 1 (true) or 0 (false) if both [v1] and [v2] are not equal to 0.
[v1] && [v2] Bitwise AND operation Performs bitwise AND on [v1] and [v2], creating a new value with the result.
[v2] Logical OR operation Creates a new value 1 (true) or 0 (false) if [v1], [v2] or both are not equal to 0.
​| [v2] Bitwise OR operation Performs bitwise OR on [v1] and [v2], creating a new value with the result.
[v1] @ [v2] Logical XOR operation Creates a new value 1 (true) or 0 (false) if either [v1] or [v2] does not equal 0, but not both.
[v1] @@ [v2] Bitwise XOR operation Performs a bitwise XOR on [v1] and [v2], creating a new value with the result.
[p1] ~= [p2] Pointer location operation Creates a new value 1 (true) or 0 (false) if pointers [p1] and [p2] point to the same location.
[v1] == [v2] Value equality operation Creates a new value 1 (true) or 0 (false) if [v1] and [v2] are equal to each other.
[v1] > [v2] Value greater than operation Creates a new value 1 (true) or 0 (false) if [v1] is greater than [v2].
[v1] < [v2] Value less than operation Creates a new value 1 (true) or 0 (false) if [v1] is less than [v2].
/[p] Inactive pointer operation Creates a new value 1 (true) or 0 (false) if pointer [p] is inactive.
>> Value count operation Creates a new value with the amount of values when this operation was called.
<< Pointer count operation Creates a new value with the amount of pointers when this operation was called.
<> Inactive pointer count operation Creates a new value with the amount of inactive pointers when this operation was called.
~?[p] Pointer index operation Creates a new value with the index of pointer [p].
.[p] Protect Protects a pointer and its value from being checked. Also can be used to remove protection.
[ ... ] Comment A comment.

Example Programs

Hello, World! Program

point print
print =  72;  !print         [H]
print ~~ 101; !print         [e]
print ~~ 108; !print; !print [ll]
print ~~ 111; !print         [o]
print ~~ 44;  !print         [,]
print ~~ 32;  !print         [ ]
print ~~ 87;  !print         [W]
print ~~ 111; !print         [o]
print ~~ 114; !print         [r]
print ~~ 108; !print         [l]
print ~~ 100; !print         [d]
print ~~ 33;  !print         [!]
#print; :print [cleaning up]

Truth Machine

point d; vnput d

until $d
  point remove; remove ~> 2;
  #remove; :remove
  ?d
back
point remove; remove ~> 2;
#remove; :remove
?d; #d; :d

Brainfuck Interpreter

This also serves as a proof for MEMORYLEEK's Turing completeness.

pass remove
    expect 1
    point rem
    rem ~> -1; rem ~> rem; #rem (get index, go to index, remove)
    rem ~> -1; #rem; :rem       (get input, remove input, clean)
exit

input [getting input program]

point start [of tape]
start = >> + 3 [=======> +3 to account for start and end values]
}remove -2; }remove -2

point end [of tape]
end = start + 99 [one less to account for first tape cell]
}remove -2

[creating tape]
point i
until ~?i == end
    }remove -1; }remove -1;
    value 0; i ~> -1
back
}remove -1; }remove -1; :i

[running program]
point symbol
point cell
symbol ~> 2
cell   ~> start

until ~?symbol > (start - 3)
    }remove -1; }remove -1; }remove -1

    until $(symbol == 62) [> instruction]
        cell = ~?cell + 1; cell ~> cell
        }remove -1; }remove -1; }remove -1;
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 60) [< instruction]
        cell = ~?cell - 1; cell ~> cell
        }remove -1; }remove -1; }remove -1;
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 43) [+ instruction]
        point calc; calc = (cell + 1) % 256
        cell ~~ calc; :calc
        }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 45) [- instruction]
        point calc; calc = (cell - 1) % 256
        cell ~~ calc; :calc
        }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 46) [. instruction]
        ?cell
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 44) [, instruction]
        point in; vnput in
        cell ~~ in; :in
        }remove -1;
    exit
    }remove -1; }remove -1; }remove -1;

    until $(symbol == 91) | cell [[ instruction]
        point count [for scope checking]
        count = 1

        until count == 0 | ~?symbol == (start - 3)
            }remove -1; }remove -1; }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
            symbol = ~?symbol + 1; symbol ~> symbol
            }remove -1; }remove -1; }remove -1;
                        
            until $(symbol == 91)
                point calc; calc = count + 1
                count ~~ calc; :calc
                }remove -1; }remove -1;
            exit
            until $(symbol == 93)
                point calc; calc = count - 1
                count ~~ calc; :calc
                }remove -1; }remove -1;
            exit
        back
        }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
        #count; :count
    exit
    }remove -1; }remove -1; }remove -1; }remove -1;

    until $(symbol == 93) | $cell [] instruction]
        point count [for scope checking]
        count = 1

        until count == 0 | ~?symbol == 2
            }remove -1; }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
            symbol = ~?symbol - 1; symbol ~> symbol
            }remove -1; }remove -1; }remove -1;
                        
            until $(symbol == 91)
                point calc; calc = count - 1
                count ~~ calc; :calc
                }remove -1; }remove -1;
            exit
            until $(symbol == 93)
                point calc; calc = count + 1
                count ~~ calc; :calc
                }remove -1; }remove -1;
            exit
        back
        }remove -1; }remove -1; }remove -1; }remove -1; }remove -1;
        #count; :count
    exit
    }remove -1; }remove -1; }remove -1;

    symbol = ~?symbol + 1; symbol ~> symbol;
    }remove -1; }remove -1; }remove -1;

    until ~?cell < start
        cell ~> end
        exit
    }remove -1; }remove -1; }remove -1;

    until ~?cell > end
        cell ~> start
        exit
    }remove -1; }remove -1; }remove -1;
back

[clean up]
:remove; :start; :end; :symbol; :cell

[remove all values]
point i
i ~> 1
until /i
    }remove -1;
    #i; i ~> 1
back
}remove 1; :i