Matrexp
Matrexp is an esolang by User:BoundedBeans. It focuses on a matrix-based expression system.
Syntax
The program is a single 4x4 matrix.
Matrices are written like this:
(=======) [x|x|x|x] [-------] [x|x|x|x] [-------] [x|x|x|x] [-------] [x|x|x|x] (=======)
If the x's are bigger than one character, the vertical bars can be duplicated vertically or spaced out horizontally. The hyphens and equals signs will duplicate and the brackets will space out as necessary. All elements in a row should be the same height and all elements in a column should be the same width.
Types
Each element of a matrix may be:
V
followed by a positive integer- An unbounded base 10 number (can be negative and have decimal places)
- Another matrix
- A condition of the form:
(expression) ? (expression) : (expression)
(The expressions can extend vertically downwards). Conditionals cannot be nested without something else between the layers. !
O
followed by an expressionI
o
followed by an expressioni
- Anything where the top left corner is
$
is implementation-dependent, allowing custom commands. The characters(=)[-]|
are disallowed in these values (the officially recommended method to encode these is to use:{
,:~
,:}
,:<
,:_
,:>
,:\
to encode matrices in extensions, encode colons as:;
, and encode regular characters as'[character]
which looks like this:Matrices: :{:~:~:~:~:~:~:~:} :<'x:\'x:\'x:\'x:> :<:_:_:_:_:_:_:_:> :<'x:\'x:\'x:\'x:> :<:_:_:_:_:_:_:_:> :<'x:\'x:\'x:\'x:> :<:_:_:_:_:_:_:_:> :<'x:\'x:\'x:\'x:> :{:~:~:~:~:~:~:~:} Conditionals: '5'1' '?' '4' :;' '1
This is only recommended if you actually need to use matrices for your extension; otherwise encode it normally using the allowed characters.)
Semantics
The matrix is evaluated like an expression, with the following steps.
- Any instances of
I
immediately evaluate to the numeric value of a unicode character of input. - Any instances of
i
immediately evaluate to a decimal number of input. - Any conditionals evaluate the left value until it becomes a number. If it is greater than zero, it replaces itself with the middle. Otherwise, it replaces itself with the right.
- Any instances of
O
evaluate the value, then print the result as a unicode character. To determine the character, the absolute value is taken, it is truncated to an integer, and it is taken modulo 65536. The evaluated result (before the previous calculations) replaces this command. - Any instances of
o
evaluate the value, then print it as a number. !
is replaced with the enclosing matrix, beforeV
and!
are evaluated.- Any matrices take in the element to the right of them (or zero if the matrix is in the fourth column), and replace cases of
V1
in themselves with the element (but only in themselves, not any nested matrices). It is then evaluated recursively and the result replaces the matrix. The place directly to the right is replaced with zero so that it isn't subtracted. Matrices on the left have priority, so a matrix can be passed as an argument (a conditional cannot, only the result of one). Further numbers of V are replaced on nested levels of matrices, but only at the level that matches the number following V (relative to the matrix being evaluated.) - For each row made of w x y z in left to right order, it calculates w - x - y - z.
- The results are multiplied.
The final result of the program normally does nothing, but if the compiler or interpreter receives the -o
flag it will be output, and if the compiler or interpreter receives the -x
flag it will be used as the exit code for the program.
Strategies
Passing two arguments
Since you can pass a matrix (although V1
won't be replaced), you can accomplish passing two arguments by passing the matrix:
(================) [V1 ? X : Y|0|0|0] [----------------] [1 |0|0|0] [----------------] [1 |0|0|0] [----------------] [1 |0|0|0] (================)
(Replace X and Y)
You can then access X by passing 1 to this matrix, and Y by passing 0. To dynamically pass this, nest the call inside of two matrix levels, and replace X with V2
and Y with V3
. You can then pass X and Y on two separate levels, and then they will be separately accessible two levels down. You can nest conditionals (with a matrix between) inside of Y to have further parameters and index them separately with 0, 1, 2, 3, etc.
Examples
Hello world!
(=======================) [O 72 |O 101|O 108|O 108] [-----------------------] [O 111|O 32 |O 119|O 111] [-----------------------] [O 114|O 108|O 100|O 33 ] [-----------------------] [0 |0 |0 |0 ] (=======================)
Truth-machine
(======================================) [(========) ? (==========) : O 48|0|0|0] [[I|48|0|0] [O 49|!|0|0] | | | ] [[--------] [----------] | | | ] [[1|0 |0|0] [1 |0|0|0] | | | ] [[--------] [----------] | | | ] [[1|0 |0|0] [1 |0|0|0] | | | ] [[--------] [----------] | | | ] [[1|0 |0|0] [1 |0|0|0] | | | ] [(========) (==========) | | | ] [--------------------------------------] [1 |0|0|0] [--------------------------------------] [1 |0|0|0] [--------------------------------------] [1 |0|0|0] (======================================)
Subtractor
(=================) [o (=======)|0|0|0] [ [i|i|0|0]| | | ] [ [-------]| | | ] [ [1|0|0|0]| | | ] [ [-------]| | | ] [ [1|0|0|0]| | | ] [ [-------]| | | ] [ [1|0|0|0]| | | ] [ (=======)| | | ] [-----------------] [1 |0|0|0] [-----------------] [1 |0|0|0] [-----------------] [1 |0|0|0] (=================)
Adder
(=========================) [o (===============)|0|0|0] [ [i|(=======)|0|0]| | | ] [ [ |[0|i|0|0]| | ]| | | ] [ [ |[-------]| | ]| | | ] [ [ |[1|0|0|0]| | ]| | | ] [ [ |[-------]| | ]| | | ] [ [ |[1|0|0|0]| | ]| | | ] [ [ |[-------]| | ]| | | ] [ [ |[1|0|0|0]| | ]| | | ] [ [ |(=======)| | ]| | | ] [ [---------------]| | | ] [ [1|0 | | ]| | | ] [ [---------------]| | | ] [ [1|0 | | ]| | | ] [ [---------------]| | | ] [ [1|0 | | ]| | | ] [ (===============)| | | ] [-------------------------] [1 |0|0|0] [-------------------------] [1 |0|0|0] [-------------------------] [1 |0|0|0] (=========================)