# 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:

(value) ? (value) : (value)

(The values can extend vertically downwards). Other conditionals cannot be the value

- "!"
- "O" followed by a value
- "I"
- "o" followed by a value
- "i"
- Anything where the top left corner is $ is implementation-dependent, allowing custom commands.

## 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 (matrices containing V in the left value is an error). 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, before V 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] (=========================)