Mech Platform Specification 
===============================================================================

1. Introduction
-------------------------------------------------------------------------------

This document defines the default syntax and semantics of the Mech programming platform, which is designed for building reactive systems such as robots, games, and user interfaces. As a platform, Mech can support multiple syntaxes and interfaces; the syntax presented here is just one possible option. However, the semantics of data types, data structures, and other core programming constructs described in this document are fundamental to Mech and must be supported by any system targeting the platform.

This document is for:

- Language designers who want to target Mech as a backend.
- Developers creating tools to interact with Mech code.
- Anyone who wants to understand the syntax and structure of Mech programs.

(1.1) Example Programs

We start by presenting a few example Mech programs to illustrate the syntax and semantics of the language.

(1.1.1) Hello, World!

First, the classic program which prints the string "Hello, World!" to the console:

```mech:hello, world!
"Hello World!"
```

In Mech, the result of the final expression in a program is automatically returned and printed to the console, without needing an explicit print statement. This is an example where Mech reduces incidental complexity.

(1.1.2) FizzBuzz

Next, a simple FizzBuzz program that prints the numbers from 1 to 10, replacing multiples of 2 with "Fizz", multiples of 3 with "Buzz", and multiples of both with "FizzBuzz":

```mech:fizzbuzz
  x := 1..=10               -- A row vector of numbers from {1} to {10}
  ~out<[string]> := x       -- Convert `x` into mutable string vec
  
  ix2 := (x % 2) == 0       -- Indices for multiples of {2}
  ix3 := (x % 3) == 0       -- Indices for multiples of {3}
  
  out[ix2] = "✨"           -- Set multiples of {2} to {"✨"}
  out[ix3] = "🐝"           -- Set multiples of {3} to {"🐝"}
  out[ix2 && ix3] = "✨🐝"  -- Set multiples of both to {"✨🐝"}
```

This example demonstrates several core Mech features:

- **Concise syntax**: Expressive and flexible, with no need for keywords or semicolons; Mech programs are generally shorter than in other languages.
- **Declarative style**: Focus on what to compute, not how to compute it, leading to clearer and more maintainable code.
- **Broadcast operations**: Vector operations apply elementwise automatically, removing loops and enabling efficient vectorization.
- **Static typing**: Types are checked at compile time, catching errors early and improving performance.
- **Type inference**: Variable and expression types are inferred, so explicit type declarations are often unnecessary.
- **Immutable by default**: Variables are immutable unless specified, promoting safer code and easier reasoning.
- **Logical indexing**: Select and manipulate vector elements via conditions, enabling declarative iteration and parallel execution.
- **Rich text formatting**: Comments and code support rich formatting using a Markdown-like syntax called Mechdown, making documentation clear and readable.

(1.1.3) Matrix Multiplication

Here is an example of matrix multiplication in Mech:

```mech:matrix multiplication
  A := [1 2; 3 4]       -- 2x2 Matrix
  B := [1 2 3; 4 5 6]   -- 2x3 Matrix
  C := A ** B           -- Matrix multiplication resulting in a 2x2 Matrix
```

Mech also features robust integrated Linear Algebra capabilities, making it easy to work with matrices and vectors. In this example, we define two matrices `A` and `B`, and then compute their product `C` using the `**` operator. These calculations are checked for dimensional compatibility at compile time, rejecting any program at compiletime which would result in a dimension mismatch.

(1.1.4) Gaussian Elimination

Here is an example of performing Gaussian elimination to solve a system of linear equations:

```mech:gaussian elimination
A := [2  1 -1
     -3 -1  2
     -2  1  2]   -- 3x3 Matrix to represent coefficients

b := [8 -11 -3]' -- 3x1 Column Vector to represent constants

x := A \ b       -- Solves the system Ax = b for x
```

The `\\` operator runs a Gaussian elimination algorithm to solve the system of equations represented by the matrix `A` and vector `b`. The result is stored in vector `x`, which contains the solution to the equations.

(1.1.5) Friends-of-Friends

Mech has a `set` datastructure with support for set comprehensions and relational algebra. Here is an example that finds the friends-of-friends for a given user in a social network:

```mech:friends-of-friends
pairs := {(1, 2), (1, 3), (2, 8), (3, 5), (3, 9)}           
user := 1                                                   
{fof | (u, f) <- pairs, (f, fof) <- pairs, u == user}
```

The solution is `{8, 5, 9}` because user `1` is friends with `2`, who is friends with `8`; and user `1` is also friends with `3`, who is friends with `5` and `9`.

Set comprehensions operate over sets, and support pattern matching and data joining. In this case, because we specifified `f` in two different generators, we defined a natural join over the friend-pairs set, drawing relationships between elements.

2. Source Code Representation
-------------------------------------------------------------------------------

(2.1) File Format

Mech source code must be stored in files with a `.mec` extension.

Source code is ecoded with UTF-8, which allows for Unicode support in identifiers, strings, and comments.

(2.2) Literate Programming and Mechdown

Mech supports literate programming as a first-class language feature. Literate programming is when code and documentation are interwoven in a single source file, allowing developers to write code that is both executable and well-documented.

Mech supports this concept through a format called Mechdown, a Markdown dialect with extensions to support embedded Mech programs. This document is formatted with Mechdown to demonstrate its features.

For more information, see the [Mechdown Section](#24738341931264987).

(2.3) Whitespace

Whitespace includes spaces (` `), tabs (`\\t`), carriage returns (`\\r`) and newlines (`\\n`). Although it is generally ignored, whitespace is be significant in several contexts:

- In lists, whitespace can be used to separate items.
- In matrix and table definitions, whitespace can deliniate columns and rows.
- In formulas, whitespace is required around operators.

Semicolons and commas are treated as whitespace in most cases. Except in these contexts:

- Semicolons can be used to separate statements so they can be written inline.
- Semicolons can be used in a matrix to separate rows, so they can be written inline.

For more information, see the [Syntax Design Document](design/syntax-design.html).

3. Lexical Elements
-------------------------------------------------------------------------------

(3.1) Tokens

Tokens are the smallest units of meaning in Mech. They include letters, digits, punctuation, and special symbols.

Some Unicode characters are reserved for box drawing, and therefore are excluded from valid identifiers.

(3.1.1) Character Classes

```ebnf
alpha := "a".."z" | "A".."Z";
digit := "0".."9";
emoji := +emoji-grapheme ;
bin-digit := "0" | "1" ;
hex-digit := digit | "a" .. "f" | "A" .. "F" ;
oct-digit := "0" .. "7" ;
```

(3.1.2) Alphanumeric Sequences

```ebnf
word := +alpha ;
digit0 := *digit ;
digit1 := +digit ;
number := digit1 ;
alphanumeric := alpha | digit ;
digit-sequence := digit, *((underscore, digit) | digit) ;
```

(3.1.3) Whitespace and Separators

```ebnf
new-line := (carriage-return, new-line) | new-line-char | carriage-return ;
whitespace := space | new-line | tab ;
ws0 := *whitespace ;
ws1 := +whitespace ;
stb := space | tab ;
list-separator := ws0, ",", ws0 ;
enum-separator := ws0, "|", ws0 ;
```

(3.2) Operators and Text

(3.2.1) Operators

| Category     | Operators                                             |
|--------------|-------------------------------------------------------|
| Assign       | `:=` `=` `+=` `-=` `*=` `/=` `^=`                     |
| Arithmetic   | `+` `-` `*` `/` `÷` `^` `%`                           |
| Condition    | `!=` `¬=` `≠` `==` `>` `<` `>=` `≤` `≥`               |
| Matrix       | `**` `·` `⨯` `\\` `'`                                 |
| Logic        | `||` `&&` `^^` `⊕` `⊻` `∧` `∨` `¬` `!`               |
| Set          | `∪` `∩` `∖` `∁` `⊂` `⊃` `⊆` `⊇` `⊊` `⊋` `∈` `∉` `Δ` |
| Table        | `⋈` `⟕` `⟖` `⟗` `⋉` `▷`                           |
| Range        | `..` `..=`                                            |
| Transition   | `=>` `->` `~>`                                        |
| Guard        | `|` `│` `├` `└`                                       |

(3.2.2) Punctutation

```ebnf
punctuation := period 
      | exclamation 
      | question 
      | comma 
      | colon 
      | semicolon 
      | quote 
      | apostrophe ;
```

(3.2.2.1) Examples

```
. ! ? , : ; " ' 
```

(3.2.3) Symbols

```ebnf
symbol := ampersand 
      | dollar
      | bar 
      | percent
      | at 
      | slash 
      | hashtag 
      | equal 
      | backslash 
      | tilde 
      | plus 
      | dash 
      | asterisk 
      | caret 
      | underscore ;
identifier-symbol := ¬(equal | underscore) , symbol ;
```

(3.2.3.1) Examples

```
& $ | % @ / # = \ ~ + - * ^ _
```

(3.2.4) Grouping Symbols

```ebnf
grouping-symbol := left-parenthesis 
      | right-parenthesis 
      | left-angle 
      | right-angle 
      | left-brace 
      | right-brace 
      | left-bracket 
      | right-bracket ;
```

(3.2.4.1) Examples

```
( ) < > { } [ ]
```

(3.2.5) Text

```ebnf
escaped-char := backslash,  symbol | punctuation | alpha ;
text := alpha 
      | digit 
      | space 
      | tab 
      | escaped-char 
      | punctuation 
      | grouping-symbol 
      | symbol ;
```

(3.3) Comments

```ebnf
comment-sigil := "--" | "//" ;
comment :=  ws0
      , comment-sigil
      , paragraph ;
```

There are two options for single line comments in Mech:

- `--` for those familiar with languages like Lua, Haskell, and SQL.
- `//` for those familiar with languages like C, C++, Java, and JavaScript.

There is no difference between the two, and they can be used interchangeably. 

Because Mech has a focus on literate programming, comments have less of an emphasis compared to other programming languages. For example, there is no support for block comments in Mech; instead, programmers are encouraged to use Mechdown to express their comments in a more structured way.

Therefore, comments are primarily used for writing notes inline with code that cannot be broken out into a paragraph.

(3.3.1) Examples

Here are some ways to write a comment in Mech:

```
  -- Comment prefix with --
  // Comment prefixed with // (renders with --)
  -- Supports formatting like **bold**, __underline__, `inline code`, and [links](https://example.com).
  x := 1 -- Comment after an expression
```

When parsed and rendered, these become:

```mech:disabled
  -- Comment prefix with --
  // Comment prefixed with // (renders with --)
  -- Supports formatting like **bold**, __underline__, `inline code`, and [links](https://example.com).
  x := 1 -- Comment after an expression
```

One special ability comments have is they can be used to print out the evaluation of a Mech code statement.

qq := 10 * 20     -- The value of qq is {qq}

(3.4) Keywords

Because Mech is designed to be used by speakers of all languages, Mech has no reserved keywords. Instead, Mech uses symbols and punctuation for all operators and syntax constructs.

See the [Syntax Design Document](design/syntax-design.html) for a discussion on keywords.

(3.5) Identifiers

```ebnf
identifier := (alpha | emoji), *(alpha | digit | identifier-symbol | emoji) ;
```

Identifiers start with letters or most UTF-8 encoded emoji characters, and can contain alphanumeric, most emojis, `/`, `*`, `+`, `-`, and `^` characters.

(3.5.1) Examples

```mech:disabled
  Hello-World
  io/print
  Δx^2
  🤖
  A*
```

Note: Underscores `_` are not allowed in identifiers, as kebab-case is the preferred style in Mech. Underscores are reported as syntax errors.

4. Literals
-------------------------------------------------------------------------------

```ebnf
literal := (number | string | atom | boolean | empty), ?kind-annotation ;
```
Mech supports several types of literals, which are used to represent values in the code. Each literal type has its own syntax and semantics. Each literal has an associated "kind", which describes the data type of the literal. Mech supports the following literal types:

- **[Number](#25538158040124283)** - Represents numeric values, including integers, floating-point numbers, and complex numbers.
  - **Real** - Real numbers, including integers and floats.
    - **[Integer](#346483031942019815)** - Whole numbers, which can be positive, negative, or zero.
      - **Signed** - Can represent both negative and positive values.
        - `i8` - 8-bit signed integer
        - `i16` - 16-bit signed integer
        - `i32` - 32-bit signed integer
        - `i64` - 64-bit signed integer
        - `i128` - 128-bit signed integer
      - **Unsigned** - Can only represent zero and positive values.
        - `u8` - 8-bit unsigned integer
        - `u16` - 16-bit unsigned integer
        - `u32` - 32-bit unsigned integer
        - `u64` - 64-bit unsigned integer
        - `u128` - 128-bit unsigned integer
      - **Floating-point** - Decimal numbers, which can represent fractions.
        - `f32` - 32-bit floating-point number, can represent integers up to `2^24`.
        - `f64` - 64-bit floating-point number, can represent integers up to `2^53`.
    - **[Fractional](#41214582360059684)** - Decimal numbers with fractional components.
      - `f32` - 32-bit floating-point number
      - `f64` - 64-bit floating-point number
      - `r64` - 64-bit rational number, which can be represented as a fraction of two `i64` integers.
  - **[Complex](#43239854015280042)** - Represent imaginary components of complex numbers.
      - `c64` - 64-bit complex number, which can be represented as a pair of `f64` values corresponding to the real and imaginary parts.
- **[String](#35096787880505906)**
      - `string` - A sequence of UTF-8 characters representing text.
- **[Boolean](#21679232488966882)** 
      - `bool` - Represents logical truth values.
- **[Atom](#63154299616713112)** - A symbolic constant, often used for tags or enums.
- **[Empty](#70084660282633489)**
      - `_` - Represents an empty value, placeholder, or the absence of a value.

(4.1) Kinds

```ebnf
kind-annotation := "<", kind, ">" ;
kind := kind-fxn 
      | kind-empty 
      | kind-atom 
      | kind-tuple 
      | kind-scalar 
      | kind-bracket 
      | kind-map 
      | kind-brace ;
kind-empty := +"_" ;
kind-atom := ":", identifier ;
kind-map := "{"
      , kind
      , ":"
      , kind
      , "}" ;
kind-fxn := "("
      , ?[",", kind]
      , ")"
      , "="
      , "("
      , ?[",", kind]
      , ")" ;
kind-brace := "{"
      , [",", kind]
      , "}"
      , ?":"
      , ?[",", literal] ;
kind-bracket := "["
      , [",", kind]
      , "]"
      , ?":"
      , ?[",", literal] ;
kind-tuple := "("
      , [",", kind]
      , ")" ;
kind-scalar := identifier ;
```

Kinds are used to specify the type of a literal or expression in Mech. Kinds are specified with a syntax structure called a "kirby" e.g. `&ltstring&gt`, which indicates a String data type; or `<[u64]:3,1>`, which indicates a 3x1 matrix of 32-bit unsigned integeres.

(4.1.1) Kind

The kind of a kind is itself. For example, the kind `<[u8]:2,3>` has the kind {<[u8]:2,3>}.

(4.1.2) Examples

```mech:disabled
<_>             -- Empty         
<:A>            -- Atom         
<{A:B}>         -- Map          
<{A}>           -- Set              
<[A]>           -- Matrix              
<(A,B,C)>       -- Tuple
<|x<A>, y<B>|>  -- Table
<{x<A>, y<B>}>  -- Record      
```

(4.2) Numbers

(4.2.1) Integer Numbers

```ebnf
number := complex-number | real-number ;
real-number := ?dash, (hexadecimal-literal | decimal-literal | octal-literal | binary-literal | scientific-literal | rational-literal | float-literal | integer-literal) ;
integer-literal := +digit;
decimal-literal := "0d", +digit ;
hexadecimal-literal := "0x", +hex-digit ;
octal-literal := "0o", +oct-digit ;
binary-literal := "0b", +bin-digit ;
```

An integer literal is a sequence of digits representing a whole number. Mech supports decimal, binary, octal, and hexadecimal integer literals, each distinguished by a unique prefix:

- Decimal: A sequence of digits without a prefix (e.g., 42, 123456).
- Hexadecimal: Prefixed with 0x, containing digits 0-9 and a-f or A-F (e.g., 0x1A3F).
- Octal: Prefixed with 0o, containing digits 0-7 (e.g., 0o755).
- Binary: Prefixed with 0b, containing only 0 and 1 (e.g., 0b1010).

(4.2.1.1) Kind

By default, Mech can represent integers in the following data types:

- Signed: `i8`, `i16`, `i32`, `i64`, `i128`
- Unsigned: `u8`, `u16`, `u32`, `u64`, `u128`
- Float: `f32`, `f64`

Unless specified or inferred, the default data type for integer literals is `f64`. You can change the datatype of an integer literal by annotating it with a kind, such as `<i32>` or `<u64>`.
(4.2.1.2) Examples

  42                  -- decimal
  0d42                -- decimal
  0x1234567890ABCDEF  -- hexadecimal
  0x1234567890abcdef  
  0o12345670          -- octal 
  0b100110101         -- binary

Numerical literals annotated with a kind to specify their type:

  1234       -- 1234 as a 64-bit float-point number
  1234<i32>  -- 1234 as a signed 32-bit integer
  1234<u8>   -- Convert 1234 to an unsigned 8-bit integer (will saturate to 255)
  
(4.2.2) Fractional Numbers

```ebnf
scientific-literal :=  (float-literal | integer-literal)
      , ("e" | "E")
      , ?plus
      , ?dash
      , (float-literal | integer-literal) ;
rational-literal := integer-literal
      , slash
      , integer-literal ;
float-literal := float-decimal-start | float-full;
float-full := digit-sequence, ".", digit-sequnce ;
float-decimal-start := ".", digit-sequence ;
```

A floating-point literal represents a real number, potentially with a fractional component. Mech supports several forms of floating-point literals:

- **Decimal floats**: Numbers with a decimal point (e.g., `3.14`, `.123`, `0.0`)
- **Scientific notation**: A number followed by e or E, then an optional sign and exponent (e.g., `2.5e10`, `1e-3`)
- **Rational literals**: A fraction of two integers separated by `/` (e.g., `3/4`, `22/7`) — these may be evaluated as exact values or approximated depending on context.

(4.7.2.1) Kind

Fractional numbers can be represented using various kinds, including:

  <f32>  -- 32-bit floating-point number
  <f64>  -- 64-bit floating-point number
  <r64>  -- 64-bit rational number, which can be represented as a fraction of two `i64` integers.

(4.2.2.2) Examples

  3.14         -- decimal float
  0.001        -- decimal float
  2.5e10       -- scientific notation
  -2.5         -- negative float
  .123         -- leading-dot float
  3/4          -- rational

By default, floating-point literals are inferred to be of type `f64`, unless explicitly annotated or inferred from context.

(4.2.3) Complex Numbers

```ebnf
complex-number := real-number, ?("i"|"j") | (("+"|"-"), real-number, ("i"|"j")) ;
```

A complex number literal represents a number with both real and imaginary parts. To support a wide range of mathematical expressions, Mech allows complex numbers to be expressed with `i` or `j`. The real and imaginary parts can be any real number.

(4.2.3.1) Kind

  <c64> -- 64-bit complex number, which can be represented as a pair of `f64` values (real and imaginary parts).

Complex numbers can be represented using the `c64` kind, which indicates a 64-bit complex number. This kind is typically represented as a pair of `f64` values (real and imaginary parts).

(4.2.3.1) Examples

  5i           -- purely imaginary number
  3+4i         -- complex number with real and imaginary parts
  2-3j         -- complex number with negative imaginary part
  -2+0i        -- complex number with negative real part

(4.3) Strings

```ebnf
string := quote, *(¬quote, (text | new-line)), quote ;
```

Strings are enclosed in double quotes `"` and can contain any character, including whitespace, except for the quote character itself. To include a quote character in a string, it must be escaped with a backslash `\\`.

Strings heap-allocate their contents, so they can be of any length. They are encoded in UTF-8, allowing for Unicode characters.

(4.3.1) Kind

  <string> -- Represents a sequence of UTF-8 characters.

(4.3.2) Examples

  "Hello, World!"
  "characters like \" and \\ are escaped with, \\ e.g. \\\""
  "This string contains emojis: 🤖, 🐦, and 🐍"
  "Multiline 
  strings 
  are supported"

(4.4) Boolean

```ebnf
boolean := true-literal | false-literal ;
true-literal := english-true-literal | true-symbol ;
false-literal := english-false-literal | false-symbol ;
true-symbol := "✓" ;
false-symbol := "✗" ;
english-true-literal := "true" ;
english-false-literal := "false" ;
```
A boolean literal represents a logical truth value, and can be expressed in either textual or symbolic form. Thre reason Mech supports both is tho allow for code that doesn't contain any English keywords, which is useful for non-English speakers.

(4.4.1) Kind

  <bool> -- Represents a boolean value, which can be either true or false.

(4.4.2) Examples

  true
  false
  ✓
  ✗  

(4.5) Atoms

```ebnf
atom := ":", identifier ;
```

An atom is a symbolic constant used to represent a fixed, named value. Atoms are prefixed with a colon and followed by an identifier. They are used to represent tags, enums, or other symbolic values in the code.

(4.5.1) Kind

The kind of an atom is itself. For example, the atom {:A} has the kind {<:A>}.

```mech:disabled
  <:A> -- Represents an atom with the name `:A`.
```

(4.5.2) Examples

```mech:disabled
:A
:MyAtom
:🐦
:Δx^2
```

(4.6) Empty

```ebnf
empty := +underscore ;
```

Empty literals are used to represent the absence of a value or a placeholder. They are represented by one or more underscores `_`. Empty literals can be used in various contexts, such as in tables, to indicate missing values.

(4.6.1) Kind

  <_> -- Represents an empty value.

(4.6.2) Examples

  _
  ___

5. Data Structures
-------------------------------------------------------------------------------

```ebnf
structure := empty-set 
      | empty-table 
      | table 
      | matrix 
      | tuple 
      | tuple-struct 
      | record 
      | map 
      | set ;
```

Data structures in Mech can be broadly classified into two categories: ordered collections that allow duplicated elements, and unordered collections that do now allow duplicated elements.

**Ordered elements, duplicates allowed**
- Vector (Nx1)
- Row Vector (1xN)
- Matrix (N-D)
- Tuple
- Table

**Unordered elements, no duplicates**
- Record
- Set
- Map

Each data structure has its own semantics, which will be described in this section.

(5.1) Matrix

```ebnf
matrix-column := *space-tab 
      , expression 
      , (*space-tab, ?("," | table-separator), *space-tab) ;
matrix-row := ?table-separator
      , *space-tab
      , +matrix-column
      , ?semicolon
      , ?new-line
      , ?(+box-drawing-char, new-line) ;
matrix := matrix-start
      , *(box-drawing-char | whitespace)
      , *matrix-row
      , *box-drawing-char
      , matrix-end ;
```

A Matrix is a structured, numbered sequence of elements of a single kind, arranged in rows and columns, enclosed bt square brackets, `[]`. The number of elements in the matrix is called its length, and the shape of a matrix is defined as a pair of non-negative integers representing the number of rows and columns.

(5.1.1) Kind

The kind of a matrix includes the type of its elements and its shape. For example, a matrix of unsigned 8-bit integers with 2 rows and 3 columns has the kind `<[u8]:2,3>`.

| Description    | Kind           |
|----------------|----------------|
| Dynamic matrix | {<[u8]>}       |
| Col Vector     | {<[u8]:2>}     |
| Row Vector     | {<[u8]:1,2>}   |
| 2D Matrix      | {<[u8]:2,3>}   |
| 3D Matrix      | {<[u8]:2,3,4>} |
| Dynamic cols   | {<[u8]:2,_>}   |
| Dynamic rows   | {<[u8]:_,3>}   |

(5.1.2) Examples

  -- Empty Matrix
  []

  -- 1x1 Matrix
  [1]

  -- 3x3 Matrix
  [1 2 3
   4 5 6
   7 8 9]

  -- 3x2 Matrix
  [1, 2; 3, 4; 5, 6]

  -- 1x3 Row Vector
  [1 2 3]

  -- 3x1 Column Vector
  [1
   2
   3]
  
  -- 4x1 Column Vector
  [1; 2; 3; 4]

(5.1.3) Semantics

- Homogeneous Elements: All elements in a matrix must be of the same kind.
- Fixed Shape: A static matrix's shape (rows, columns) is part of its kind and is always a tuple of non-negative integers.
- One-Based Access: Elements are accessed using 1-based indexing for both rows and columns.
- Column-Major Order: Matrix elements are stored and accessed in column-major order.

Matrix kinds are always two-dimensional, so row vectors and column vectors are also represented as matrices with a single row or column, respectively.

(5.1.4) Indexing

Matrix elements can be accessed using either 1D or 2D indexing:

- 1D Indexing (Column-Major Order): Elements are stored in column-major order, meaning the first element is the top-left element, proceeding down the first column before moving to the next.
- 2D Indexing: Elements can be referenced using `[row, column]` notation, starting from 1 for both indices.
- Negative Indices: Negative indices count from the end of the matrix, with -1 being the last element.

See the [indexing section](#41353925203355102) for more details on syntax and semantics of matrix indexing.

(5.1.5) Operations

By default, basic operations on matrices are broadcast, meaning they are applied element-wise across the matrix. For example:

  [1 2 3] + [4 5 6] -- Results in `[5 7 9]`

This works as long as both matrices have the same shape. If not, the operation will fail with a type error at compile time.

The exception is if either of the operands are scalar, then the scalar is broadcast across the matrix. For example:

  [1 2 3] + 10 -- Results in `[11 12 13]`
  10 + [1 2 3] -- Results in `[11 12 13]`

(5.2) Set

```ebnf
set := "{"
      , ws0
      , ?[expression, list-separator]
      , ws0
      , "}" ;
empty-set := table-start
      , ws0
      , empty
      , ws0
      , table-end ;
```

A Set is defined using curly braces `{}` and contains a comma-separated list of expressions. Sets do not maintain order and contain only unique elements.

(5.2.1) Kind

The kind of a set consists of:

- The kind of the elements
- The number of elements, which can be dynamic or fixed

```mech:disabled
  <{u8}>            -- Generic set of unsigned 8-bit integers
  <{u8}:3>          -- Set of 3 unsigned 8-bit integers
  <{{i8}}>          -- Set of sets of signed 8-bit integers 
```

(5.2.2) Examples

  {}               -- Empty set
  {1}              -- Singleton set with one element
  {1.2, 3.4, 5.6}  -- Set of floats
  {"a", "b", "c"}  -- Set of strings
  {{1,2},{3,4}}    -- Nested set of sets

(5.2.3) Semantics

- Homogeneity: All elements in a set must be of the same type.
- Unordered: The order of elements within a set is not preserved.
- Uniqueness: Duplicate elements are not allowed in a set.

(5.2.4) Operations

- Insertion: Adding an element to a set does not affect its order and only - succeeds if the element is not already present.
- Deletion: Removing an element, if present, maintains the set property.
- Union: Combines two sets, keeping only unique elements.
- Intersection: Produces a set containing elements common to both sets.
- Difference: Returns a set containing elements in the first set but not in the second.

(5.3) Map

```ebnf
map := "{"
      , ws0
      , *mapping
      , ws0
      , "}" ;
mapping :=  ws0
      , expression
      , ws0
      , ":"
      , ws0
      , expression
      , ?comma
      , ws0 ;
```

A Map is defined using curly braces `{}` and contains a set of key-value mappings. Each key is unique and associated with a corresponding value.

(5.3.1) Kind

The kind of a map consists of:

- The kind of the keys
- The kind of the values
- The number of key-value pairs, which can be dynamic or fixed

<{string:u8}>           -- A map of strings to unsigned 8-bit integers
<{string:{string:u8}}>  -- A map of strings to a map of strings to unsigned 8-bit integers


(5.3.2) Examples

{"a": 1}                    -- Map with a single key-value pair
{1: 0xA, 2: 0xB, 3: 0xC}    -- Map with multiple key-value pairs
{"a": {"b": 10}}            -- Nested map
{ "a" : 10                 
  "b" : 20
  "c" : 30 }                -- Multiline map

(5.3.3) Semantics

- Key Uniqueness: Each key in a map must be unique.
- Unordered: The order of key-value pairs within a map is not preserved.
- Key-Value Association: Each key is mapped to exactly one value.

(5.3.4) Operations

- Insertion: Adding a key-value pair updates the map. If the key already exists, its value is updated.
- Deletion: Removing a key-value pair removes the key and its associated value.
- Lookup: Retrieving the value associated with a key.
- Merge: Combining two maps, where duplicate keys take precedence from the second map.

(5.4) Tuple

```ebnf
tuple := "(", ?[expression, ","], ")" ;
tuple-struct := atom, "(", expression, ")" ;
```

A Tuple is defined using parentheses `()` and contains an ordered collection of elements, which can be of different types. 

(5.4.1) Kind

The kind of a tuple consists of the kinds of its elements. For example:

  <(u8,string)>    -- Two-tuple of u8 and string    
  <(u8,u8,u8)>     -- Three-tuple of u8s     
  <(f64,(string,bool))> -- Nested tuple 

(5.4.2) Examples
                
  (1,1,3)                
  (1,(2,3))                
  (1, true, "Hello")
  ([1, 2, 3, 4], 7, false)       

(5.4.3) Semantics

- The order of elements within a tuple is preserved.
- A tuple can contain elements of different types.

(5.5) Table

```ebnf
table := table-start
      , *(box-drawing-char | whitespace)
      , table-header
      , *(box-drawing-char | whitespace)
      , +table-row
      , *box-drawing-char
      , ws0
      , table-end ;
binding := identifier
      , ?kind-annotation
      , colon
      , expression
      , ?"," ;
table-column := *(space | tab)
      , expression
      , *((space | tab)
            , ?("," | table-separator)
            , *(space | tab)) ;
table-row := ?table-separator
      , *(space | tab)
      , +table-column
      , ?semicolon
      , ?new-line
      , ?(+box-drawing-char, new-line) ;
table-header := [field, +space-tab]
      , *(space | tab)
      , (bar| box-vert)
      , ws0 ;
field := identifier, ?kind-annotation ;
empty-table := table-start
      , ws0
      , table-end ;
```

A Table represents a structured collection of records, where each record consists of multiple fields (columns). Tables allow organizing data in a flexible, expressive manner.

(5.5.1) Kind

A table's kind includes the column types and table dimensions. For example:

<|x<u8>, y<string>, z<[u8]:1,3>|:4>

This denotes:

- Columns: `|x<u8>, y<string>, z<[u8]:3>|`
      - `x<u8>`: An unsigned 8-bit integer column.
      - `y<string>`: A string column.
      - `z<[u8]:1,3>`: A column containing row vectors of `u8` with a fixed length of 3 elements.

- Shape: The `4` indicates there are 4 rows in the table. 
      - An underscore `_` can be used to indicate that the number of rows is dynamic,
      - Rows can be omitted if the number of rows is to be inferred from an expression.

The kind of a table row is equivalent to a record with the same column kinds. Each row of the table has kind:

<{x<u8>,y<string>,z<[u8]:1,3>}> -- A table row is a record.

The kind of a table column is equivalent to a vector of the table column kind. For example the kind of the first column in the above table is:

<[u8]:1,3> -- A table column is a vector.


(5.5.2) Examples

A basic table:

```mech:ex 5.5.3.1
| x<u8>  y<string> z<bool> |
| 1      "a"       true    |
| 4      "b"       false   |
| 7      "c"       true    |
```

The `*` is the "any" kind and allows columns to contain data from mixed kinds.

```mech:ex 5.5.3.2
  | x<*>   y<*> |
  | 1.2    true |
  | "Hi"   8<u8>|
```

Here, `x` holds both floats and strings, and y holds both integers and booleans. This can be useful for dealing with data whose type is not known at compiletime.


(5.5.3) Semantics

- Each record consists of ordered fields (columns).
- Fields can have different kinds (types).
- All values in a column must be of the same kind.
- The number of columns is fixed and part of the table's kind.
- Tables allow missing values (denoted by `_`).

(5.6) Record

```ebnf
record := table-start
      , ws0
      , +binding
      , ws0
      , table-end ;
```

A `record` is a collection of named fields. Each field consists of a key-value pair, where the key is an identifier and the value is a Mech value. Records provide a structured way to group related data while allowing heterogeneous types.

(5.6.1) Kind

A record's kind describes the types of its fields:

```mech:disabled
<{field1<kind1>, field2<kind2>,...}>
```

This denotes a record with fields:

- `field1<kind1>`: A field named `field1` of type `kind1`.
- `field2<kind2>`: A field named `field2` of type `kind2`.
- `...`: Additional fields as needed.

(5.6.2) Examples

A simple record with two fields. The kinds of these fields are inferred from the values:

```mech:ex 5.6.3.1
{name: "Alice", age: 30u8}  
```

The kinds of fields can be specified explicitly:

```mech:ex 5.6.3.2
{id<u32>: 12345, name: "Bob"}
```

Records can be nested, allowing fields to contain other records:

```mech:ex 5.6.3.3
{
  title: "Lord of the Rings", 
  author: {
      name: "J.R.R. Tolkien", 
      birth-year: 1892u16
  }
  published: 1954u16
}
```

(5.6.3) Semantics

- Each field is identified by a unique name.
- Fields can have different types.
- Records can contain other records.
- The shape of a record is immutable, meaning fields cannot be added or removed after creation even if the record is declared mutable. A mutable record allows modification of field values but not the structure.

6. Expressions
-------------------------------------------------------------------------------

```ebnf
expression := range-expression | formula ;
```

Expressions define computations in Mech. Most expressions operate elementwise over collections according to the rules of broadcasting.

**Broadcasting Rules:**

- Scalars expand to match the shape of collections.
- Operations between collections are elementwise when shapes are compatible.
- Higher-dimensional collections expand along singleton dimensions when necessary.
- Tables support column-wise elementwise operations but use set-based operations (e.g., unions, joins) for whole-table manipulation.

**Expression Categories:**

- Arithmetic: Addition, subtraction, multiplication, and division over scalars, vectors, and matrices.
- Matrix Operations: Matrix multiplication, transposition, and other matrix-specific operations.
- Comparison: Elementwise relational comparisons (`<`, `>`, `==`, etc.).
- Logical Operations: Boolean elementwise operations (`and`, `or`, `not`).
- Set Operations: Union, intersection, and other set-specific operations.
- Range Expressions: Constructing sequences of values.
- Indexing: Accessing elements within collections using direct and computed indices.

(6.1) Formula 

```ebnf
parenthetical-term := left-parenthesis, formula, right-parenthesis ;
negate-factor := "-", factor ;

formula := l1, *(range-operator, l1) ;
l1 := l2, *(add-sub-operator, l2) ;
l2 := l3, *(mul-div-operator | matrix-operator, l3) ;
l3 := l4, *(power-operator, l4) ;
l4 := l5, *(logic-operator, l5) ;
l5 := l6, *(comparison-operator, l6) ;  
l6 := l7, *(table-operator, l7) ;
l7 := factor, *(set-operator, factor) ;
factor := (parenthetical-term 
      | negate-factor 
      | not-factor
      | structure
      | function-call 
      | literal 
      | slice 
      | var), ?transpose ;
```

A formula is an expression that follows operator precedence rules and consists of arithmetic, logical, comparison, matrix, range, table, and set expressions. Expressions in formulas are evaluated according to their precedence, with higher-precedence operations being evaluated first. Precedence rules are encoded in the structure of the formula grammar.

(6.1.1) Operator Precedence

Operators in formulas are applied according to the following precedence, from highest to lowest:

1. Parentheses - Explicit grouping of expressions.
2. Negation and Logical NOT - Unary operations.
3. Set Operations - Union, intersection, difference, etc.
4. Table Operations - Left join, right join, full join, etc.
5. Comparison - `==`, `!=`, `<`, `>`, `<=`, `>=`
6. Logical Operations - `&&`, `||`, `xor`
7. Power - `^`
8. Matrix Operations - `**`, `·`, `⨯`, `\\`
9. Multiplication, Division, Remainder - `*`, `/`, `%`
10. Add, Subtract - `+`, `-`
11. Range - `..`, `..=`

(6.1.2) Evaluation Order and Associativity

- Left-to-right associativity applies to all operators, including exponentiation.
- Parentheses explicitly override precedence rules.

(6.2) Arithmetic

```ebnf
add       := "+" ;
subtract  := "-" ;
multiply  := "*" ;
divide    := "/" | "÷" ;
exponent  := "^" ;
remainder := "%" ;
```

(6.3) Matrix

```ebnf
solve           := "\" ;
dot-product     := "·" | "•" ;
cross-product   := "⨯" ;
matrix-multiply := "**" ;
transpose       := "'" ;
```

(6.4) Comparison

```ebnf
not-equal        := "!=" | "¬=" | "≠" ;    
equal            := "==" ;  
strict-equal     := "=:=" , "≡" ;          
not-strict-equal := "=!=", "=¬=";           
greater          := ">" ;            
less             := "<" ;            
greater-or-equal := ">=" | "≥"  ;       
less-or-equal    := "<=" | "≤"  ;       
```

(6.5) Logical

```ebnf
or           := "||" ;            
and          := "&&" ;            
not          := "!" | "¬";         
exclusive-or := "xor" | "⊕" | "⊻" ;   
```

(6.6) Table

```ebnf
natural-join := "⋈ " ;
left0-join := "⟕ " ;
right-join := "⟖ " ;
full-join := "⟗ " ;
left-semi-join := "⋉ " ;
right-semi-join := "▷:" ;
```

(6.7) Set

```ebnf
union := "∪";       
intersection := "∩";       
difference := "∖";       
complement := "∁" | "'" ;  
subset := "⊆";       
superset := "⊇";       
proper-subset := "⊊";       
proper-superset := "⊋";       
element-of := "∈";       
not-element-of := "∉";   
symmetric-difference := "Δ";
```

(6.8) Range

```ebnf
range-inclusive := "..=" ;
range-exclusive := ".." ;
```

7. Indexing
-------------------------------------------------------------------------------

```ebnf
subscript := swizzle-subscript 
      | dot-subscript-int 
      | dot-subscript 
      | bracket-subscript 
      | brace-subscript ; 
index := identifier, +subscript ;
```

(7.1) Slicing

```ebnf
bracket-subscript := "["
      , [(select-all | range-subscript | formula-subscript), ","]
      , "]" ;

brace-subscript := "{"
      , [(select-all | formula-subscript), ","]
      , "}" ;
formula-subscript := formula ;
range-subscript := range-expression ;
select-all := ":" ;
```

(7.1.1) Examples

```
    array := [10, 20, 30, 40, 50]
    slice_1 := array[1:]                -- Select all from index 1 to the end (select-all)
    slice_2 := array[1, 3]              -- Range subscript (from index 1 to 3)
    slice_3 := array[2, 4]              -- Another range from index 2 to 4
    slice_4 := array[:4]                -- Select all up to index 4
    slice_formula := array[(x + y), 3]  -- Formula-based subscript, with a calculated index

    matrix := { {1, 2}, {3, 4}, {5, 6} }
    brace_index := matrix{(x * y)}      -- Formula-based indexing within braces
```

(7.2) Dot Index

```ebnf
dot-subscript := ".", identifier ;
dot-subscript-int := ".", integer-literal ;
```
(7.2.1) Examples
```
dot_result_1 := object.field        -- Dot subscript with identifier
dot_result_2 := object.42           -- Dot subscript with integer literal
```
(7.3) Swizzle

```ebnf
swizzle-subscript := "."
      , identifier
      , "," 
      , [identifier, ","] ;
```
(7.3.1) Examples

```
    vector := {x: 1, y: 2, z: 3}
    swizzle_result := vector.x, y      -- Swizzling: selecting x and y
    swizzle_combined := vector.x, y, z -- Swizzling: selecting x, y, z
```

8. Statements
-------------------------------------------------------------------------------

```ebnf
statement := variable-define 
      | variable-assign 
      | enum-define 
      | fsm-declare 
      | kind-define ;
```

(8.1) Variable Define

```ebnf
define-operator := ":=" ;
variable-define := ?tilde, var
      , ¬assign-operator
      , define-operator
      , expression ;
```
(8.1.1) Examples

```
    intVar := 10                                -- Variable definition with initialization
    optionalVar := ~stringVar                   -- Variable definition with optional tilde
    varWithExpression := ~calculatedValue * 5   -- Variable definition with expression
```

(8.2) Variable Assign

```ebnf
assign-operator := "=";
variable-assign := slice-ref
      , ¬define-operator
      , assign-operator
      , expression ;
```
**Examples**

```mech:ex 8.2
~numbers := [1, 2, 3, 4, 5]
numbers[2] = 10             -- Assign value 10 to index 2 of the array
```

(8.3) Op-Assign

```ebnf
add-assign-operator := "+=";
sub-assign-operator := "-=";
mul-assign-operator := "*=";
div-assign-operator := "/=";
exp-assign-operator := "^=";
op-assign-operator := add-assign-operator 
      | sub-assign-operator 
      | mul-assign-operator 
      | div-assign-operator 
      | exp-assign-operator ;
op-assign := slice-ref
      , ¬define-operator
      , op-assign-operator
      , expression ;
```
(8.3.1) Examples


```mech:disabled
    counter := 0
    counter += 5                 -- Add 5 to counter (addition assignment)
    counter -= 3                 -- Subtract 3 from counter (subtraction assignment)
    counter *= 2                 -- Multiply counter by 2 (multiplication assignment)
    counter /= 4                 -- Divide counter by 4 (division assignment)
    counter ^= 2                 -- Exponentiate counter by 2 (exponentiation assignment)
```

(8.4) Enum Define

```ebnf
enum-define := "<"
      , identifier, ">"
      , define-operator
      , [enum-variant, enum-separator];
enum-variant := ?grave
      , identifier
      , ?enum-variant-kind ;
enum-variant-kind := "("
      , kind-annotation
      , ")" ;
```
(8.4.1) Examples

```
    status < Active | Inactive | Pending  -- Enum definition with variants
    priority < High | Medium | Low        -- Enum definition for priority levels
```

(8.5) Kind Define

```ebnf
kind-define := "<"
      , identifier
      , ">"
      , define-operator
      , kind-annotation ;
```
(8.5.1) Examples

```
    userKind < Person > :< string | int -- Kind definition with annotation
```

9. Mech Programs
-------------------------------------------------------------------------------

```ebnf
mech := mechdown-program | statement ;
```

10. Mechdown
-------------------------------------------------------------------------------

Mechdown is a markup language for writing Mech programs. It is designed to maintain vague compatibility with Markdown, it is *not* a superset of Markdown. Rather, Mechdown is a distinct markup language with its own syntax and semantics. For instance, hashtag notation is not supported for titles, which is a departure from Markdown. 

Moreover, Mechdown supports tables and other features that are not present in Markdown, but can be found in extension to Markdown like Github Flavored Markdown (GFM), and Mech-specific features like that ability to query Mech values and print them inline using `{}` syntax.

Mech programs and scripts can be written entirely without Mechdown, but literate programming with Mechdown is idomatic.

(10.1) Document Structure

```ebnf
program := ws0, ?title, body, ws0 ;
body := ws0, +(section, section-elements), ws0 ;
section-element := +mech-code 
      | list 
      | footnote 
      | citation 
      | abstract 
      | img 
      | equation 
      | markdown-table 
      | float 
      | block-quote 
      | block-important
      | block-question
      | code-block 
      | thematic-break 
      | subtitle 
      | paragraph ;
section := ul-subtitle, *section-element ;
section-elements := +(¬ul-subtitle, section-element) ;
```

A Mechdown document consists of an optional title followed by a body containing sections. Each section can contain various elements such as paragraphs, subtitles, code blocks, lists, footnotes, citations, images, equations, tables, and thematic breaks.

(10.2) Titles

```ebnf
title := +text
      , new-line
      , +"="
      , *(space|tab)
      , ws0 ;
paragraph-element := +(¬define-operator, text) ;
paragraph := paragraph-starter, *paragraph-element ;
subtitle := +digit-token
      , "."
      , *space
      , +text
      , new-line
      , +"-"
      , *(space|tab)
      , new-line
      , *(space|tab)
      , ws0 ;
number-subtitle := *(space|tab)
      , "("
      , integer-literal
      , ")"
      , +(space|tab)
      , +text
      , *(space|tab)
      , ws0 ;
alpha-subtitle := *(space|tab)
      , "(", alpha, ")"
      , +(space|tab)
      , +text
      , *(space|tab)
      , ws0 ;
```

There are 6 levels of titles: the document title, section titles, and two levels of sub section titles. 

**Example:**

```
Title
========

1. Section Title
----------------

(1.1) Sub Section Title

(1.1.1) Sub Sub Section Title
```

Section titles and the first level of sub-section titles comprise the table of contents, which is generated automatically.

(10.3) Paragraphs

```ebnf
paragraph := +paragraph-element;
paragraph-element := hyperlink 
      | reference 
      | section-reference
      | raw-hyperlink 
      | highlight 
      | footnote-reference 
      | inline-mech-code 
      | eval-inline-mech-code 
      | inline-equation 
      | paragraph-text 
      | strong 
      | highlight 
      | emphasis 
      | inline-code 
      | strikethrough 
      | underline ;
paragraph-exclude := img-prefix 
      | http-prefix 
      | section-sigil
      | left-bracket 
      | tilde 
      | asterisk 
      | underscore 
      | grave 
      | define-operator 
      | bar ;
paragraph-text := +(¬(paragraph-exclude), text) ;
```

At their base, paragraphs are blocks or raw text that start with a valid paragraph starter and end with a newline character.

(10.3.1) Paragraph Elements

```ebnf
strong := (asterisk, asterisk), +paragraph-element, (asterisk, asterisk) ;
emphasis := asterisk, +paragraph-element, asterisk ;
strikethrough := tilde, +paragraph-element, tilde ;
underline := underscore, +paragraph-element, underscore ;
highlight := "!!", +paragraph-element, "!!" ;
inline-code := grave, +text, grave ;
inline-equation := equation-sigil, +text, equation-sigil ;
hyperlink := "[", +text, "]", "(", +text, ")" ;
raw-hyperlink := http-prefix, +text ;
eval-inline-mech-cdoe := "{", expression, "}" ;
inline-mech-cdoe := "{{", expression, "}}" ;
```

Beyond raw text, paragraphs also can contain various markup which indicates inline elements. Mechdown supports the following inline markup:

```
- Text Markup
  - **Bold Text**
  - *Italic Text*
  - __Underline Text__
  - ~~Strikethough Text~~
  - !!Highlighted Text!!
- Inline Elements
  - `Inline code blocks`
  - {{inline-mech := syntax + "highlighting"}}
  - $$\pm\sqrt{inline^2 + equation^2}$$
- Link Elements
  - [Hyperlinks](#)
  - Autonumbered inline references [MECH]
  - Autonumbered footnote references[^1]
  - Section references §10.3
```

This renders as

- Text Markup
  - **Bold Text**
  - *Italic Text*
  - __Underline Text__
  - ~~Strikethough Text~~
  - !!Highlighted Text!!
- Inline Elements
  - `Inline code blocks`
  - {{inline-mech := syntax + "highlighting"}}
  - $$\pm\sqrt{inline^2 + equation^2}$$
- Link Elements
  - [Hyperlinks](#)
  - Autonumbered inline references [MECH]
  - Autonumbered footnote references[^1]
  - Section references §10.3

(10.3.2) References

```ebnf
footnote := "[^", +text, "]", ":", ws0, paragraph ;
footnote-reference := "[^", +text, "]" ;
citation-reference := "[", +alphanumeric, "]" ;
citation := "[", (identifier | number), "]", ":", ws0, paragraph, ws0, ?("(", +text, ")") ;
section-reference := "§" , +(alphanumeric | period) ;
```

Mechdown supports various references including footnotes, citations, and section references.

Footnotes are used to indicate additional information or references at the bottom of the document. They are referenced inline using a `[^label]` syntax. Footnotes are defined as section elements, and are rendered where they are defined. They are indicated with a `[^label]:` syntax, followed by the footnote text.

Citations are used to reference external sources or documents. They are indicated inline using a `[label]` syntax. Citations are defined as section elements, and are rendered at the bottom of the document, in an auto-generated "Works Cited" section. They are indicated with a `[label]:` syntax, followed by the citation text and optional additional information in parentheses. The label used in reference must match the label used in the citation definition.

Section references are inline references to section titles, and are indicated with a `§` followed by the section number, or a unique section label.

(10.3.2.1) Examples

```
This is a paragraph with a footnote reference.[^1] Here is a citation reference.[MECH] Finally, we have a section reference to §10.4.

[^1]: This is the text of the footnote.
[MECH]: Mech Programming Language. (2024). Retrieved from https://mech-lang.org (Mech Official Website)
```

This renders as:

This is a paragraph with a footnote reference.[^1] Here is a citation reference.[MECH] Finally, we have a section reference to §10.4.

[^1]: This is the text of the footnote.
[MECH]: Mech Programming Language. (2024). Retrieved from https://mech-lang.org (Mech Official Website)

(?)> Although the referenec is defined here in the document, it will be rendered at the bottom of the document in the "Works Cited" section. This is in contrast to footnotes, which are rendered where they are defined.

(10.4) Lists

```ebnf
unordered-list := +list-item, ?new-line, ws0 ;
ordered-list := +ordered-list-item, ?new-line, ws0 ;
ordered-list-item := integer-literal
      , "."
      , *space
      , paragraph
      , *new-line ;
list-item := dash
      , +space
      , paragraph
      , *new-line ;
```

There are two varities of lists, unordered, which are delinated with a `-` or a graphicl and ordered list, which are delinated with a numeral like `1.`, and are numbered in order automatically when formatted.

**Example:**

```
- Item 1
- Item 2
- Item 3

1. Item 1
2. Item 2
3. Item 3
```

When rendered, they look like this:

- Item 1
- Item 2
- Item 3

List items are paragraphs, and can contain any inline elements.

**Example:**

```
- **First**: item 1
- **Second**: item 2
- **Third**: item 3
```

Here's a list of some of the features of lists:

1. Bullet lists
    - One
    - Two
    - Three
2. Custom lists
    -(🦜) Four
    -(🏴‍☠️) Five
    -(🐷) Six
3. Numbered lists
    1. One
    2. Two
    3. Three
4. Custom start number
    7. One
    8. Two
    9. Three
5. Check lists
    -[ ] One
    -[x] Two
    -[ ] Three

(10.6) Thematic Breaks

```ebnf
thematic-break := asterisks, asterisks, +asterisks ;
```

Thematic breaks are horizontal lines that can be used to separate sections of a document. They are created using three or more asterisks.

**Example:**

```
***
***********
```

When rendered, they look like this:

***

(10.5) Code Blocks

```ebnf
code-block :=
    codeblock-sigil, 
    *space-tab,      
    ?code-identifier,
    ?option-map,     
    *space-tab,      
    new-line,        
    code-content,    
    codeblock-sigil, 
    ws0
;
codeblock-sigil := grave-codeblock-sigil | tilde-codeblock-sigil ;
grave-codeblock-sigil := grave, grave, grave ;
tilde-codeblock-sigil := tilde, tilde, tilde ;
code-identifier := +((¬"{", text));
code-content := *(¬codeblock-sigil , any);
```

Mechdown supports code blocks, which are enclosed in triple backticks (graves) and can contain any text. Code blocks are useful for including Mech code snippets or other text that should be displayed verbatim.

Blocks are deliniated by a code fence, whether triple graves or triple tildes. Optionally, a code identifier can be provided after the opening code fence to indicate the programming language of the code block. This enables syntax highlighting when rendered.

When "mech" is specified as the code identifier, the code block is treated as Mech code and syntax highlighting is applied accordingly. See §10.10 for more details specific to Mech code blocks.

When "ebnf" is specified as the code identifier, the code block is treated as EBNF syntax and syntax highlighting is applied accordingly.

Start and end code fences must be of the same type (either graves or tildes). To embed a code fence in another code fence, use the alternate type for the inner fence.


(10.5.1) Examples

~~~
```
This is a code block deliniated with graves.
```
~~~

```
~~~
This is a code block deliniated with tildes.
~~~
```

This one has a label:

~~~
```ebnf
X := A | B, C ;
```
~~~

The label can also have an options map:

~~~
```ebnf{width: "25px}
X := A | B, C ;
```
~~~

(10.6) Equations

```ebnf
equation := (dollar, dollar), +text, new-line;
```

Equations are orefixed with `$$` and can contain any text. They are used to display mathematical expressions or formulas expressed in LaTeX syntax.

For instance,

```
$$ c = \pm\sqrt{a^2 + b^2}
```

when rendered will look like this:

$$ c = \pm\sqrt{a^2 + b^2}

Mechdown also supports inline equations, which begin and conclude with a `$$`. They are expressed with LaTeX syntax, like so: `$$c^2 = a^2 + b^2$$`. This is rendered by a third-party library into $$c^2 = a^2 + b^2$$.

(10.7) Callout Blocks

```ebnf
block-quote := ">", ws0, +paragraph ;
block-info := "(i)>", ws0, +paragraph ;
block-question := "(?)>", ws0, +paragraph ;
block-warning := "(!)>", ws0, +paragraph ;
block-error := "(x)>", ws0, +paragraph ;
block-success := "(+)>", ws0, +paragraph ;
block-idea := "(*)>", ws0, +paragraph ;
```

Callout blocks are used to emphasize a paragraph, and classifies them into one of seven semantic categories:

- *Quotation*: for quotations, indicated with a `>`.
- *Info*: for information the reader should know, indicated with a `(i)>`
- *Question*: for anticipated and frequently asked questions, indicated with a `(?)>`
- *Warning*: for cautions and warnings, indicated with a `(!)>`
- *Error*: for errors and critical issues, indicated with a `(x)>`
- *Success*: for success messages and positive outcomes, indicated with a `(+)>`
- *Idea*: for ideas and suggestions, indicated with a `(*)>`

Multiple paragraphs can be included in the callout block as long as there are no newline characters between them (although a newline is of course required to end a paragraph).

(10.7.1) Examples

```
> This is a quote block.

(x)> This is an error block.

(!)> This is a warning block.

(+)> This is a success block.

(?)> This is a question block.

(i)> This is an info block.

(*)> This is an idea block.

(?)> This is a question block with multiple paragraphs.
This is the second paragraph.
```

When rendered, they look like this:

> This is a quote block.

(x)> This is an error block.

(!)> This is a warning block.

(+)> This is a success block.

(?)> This is a question block.

(i)> This is an info block.

(*)> This is an idea block.

(?)> This is a question block with multiple paragraphs.
This is the second paragraph.

(10.8) Tables

```ebnf
markdown-table := markdown-table-header, *markdown-table-row ;
markdown-table-header := whitespace0
      , +column-header
      , bar
      , new-line
      , whitespace0
      , +column-alignment
      , bar
      , new-line ;
column-header := bar, paragraph ;
column-alignment := bar
      , whitespace0
      , alignment-separator
      , whitespace0;
alignment-separator := center-alignment 
      | left-alignment 
      | right-alignment 
      | no-alignment ;
no-alignment := +dash ;
left-alignment := colon, +dash ;
right-alignment := +dash, colon ;
center-alignment := colon, +dash, colon ;
markdown-table-row := whitespace0
      , +column-cell
      , bar
      , new-line ;
column-cell := bar, paragraph ;
```

Markdown tables consist of a header, and a body. The header is defined using a pipe `|` to separate columns, and a row of dashes `-` to indicate the alignment of each column. The body of the table contains rows of data, also separated by pipes. 

**Table Heading::**

The header of a table is defined using a row of text followed by a row of dashes. The dashes indicate the alignment of each column.

**Column Alignment:**

Columns can be aligned in one of three ways:

- Left-aligned: `:--` or `--`
- Right-aligned: `--:`
- Center-aligned: `:--:`

Any number of dashes can be used to indicate the width of the column, and they can be of different lengths.

**Table Body:**

The body of a table is defined using rows of text separated by pipes. Each row can contain any number of columns, and the number of columns in each row must match the number of columns in the header.

(10.8.1) Example

```
| Align Left  | Align Center | Align Right |
|:------------|:------------:|------------:|
| One         | Four         | {1 * 10}    |
| Two         | Five         | {2 * 20}    |
| Three       | Six          | {3 * 30}    |
```

Renders the following table:

| Align Left  | Align Center | Align Right |
|:------------|:------------:|------------:|
| One         | Four         | {1 * 10}    |
| Two         | Five         | {2 * 20}    |
| Three       | Six          | {3 * 30}    |

(10.9) Images

```ebnf
img := "![", paragraph, "]", "(", +text, ")" , ?option-map ;
option-map := "{", ws0, *mapping, ws0, "}" ;
option-mapping :=  ws0, expression, ws0, ":", ws0, expression, ?comma, ws0 ;
```

Images are added to Mechdown documents using the `![alt-text](image-url)` syntax. An optional options map can be provided within curly braces `{}` to specify additional attributes for the image, such as width, height, or alignment. 

The alt-text is a rich paragraph that can contain any paragraph elements. It is configured to display below the image as a caption by default. The caption is accompanied by a figure number, which is automatically assigned based on the section of the document in which the image appears.

Images can be floated to the left or right by prefixing with `<<` or `>>`, respectively. This allows text to wrap around the image and caption.

(10.9.1) Example

```
![Mika running to get the job done!](https://gitlab.com/mech-lang/assets/-/raw/v0.2-beta/images/mika/running.png?ref_type=heads)
![A smaller version of Mika](https://gitlab.com/mech-lang/assets/-/raw/v0.2-beta/images/mika/running.png?ref_type=heads){width: "200px"}
```

This renders as:

![Mika running to get the job done!](https://gitlab.com/mech-lang/assets/-/raw/v0.2-beta/images/mika/running.png?ref_type=heads)
![A smaller version of Mika](https://gitlab.com/mech-lang/assets/-/raw/v0.2-beta/images/mika/running.png?ref_type=heads){width: "200px"}

(10.10) Mech Extensions 

```ebnf
eval-inline-mech-cdoe := "{", ws0, expression, ws0, "}" ;
inline-mech-cdoe := "{{", ws0, expression, ws0, "}}" ;
mech-code := mech-code-alt, ("\n" | ";" | comment) ;
mech-code-alt := fsm-specification | fsm-implementation | function-define | statement | expression | comment ;
```

Mechdown extends the base markup language to include Mech code block support. These blocks integrate directly with the Mech runtime and are parsed, executed, and rendered as live, reactive code segments.

(10.9.1) Mech Code Blocks

Mech code ban be written directly into any Mechdown document, or within a fence. Each has different semantics.

Subsequent lines of unadorned Mech code are treated as part of the same Mech program, and are executed in sequence. The scope of these blocks is global, so any variable defined in a code block can be referenced from other blocks, or also inline code elements. However, no output is rendered for unadorned Mech code.

Fenced Mech code much be indicated with a triple fence (either `\`` or `~`), followed by the language specifier `mech`. Code within these fences is executed in the same global scope as unadorned Mech code, but any output from the final expression in the block is rendered below the code fence. This allows for live code examples that show both the code and its output.

Mech code blocks can be configured by adding a `:` at the end followed by a string or an option map. This configuration can specify options such as whether to show output, hide code, or other rendering preferences. Current options include:

- mech:interpreter-id - Scope block code to a specific interpreter instance. This is useful for separating examples and tests that should not change the global program state.
- mech:hidden - This will hide the code block from being rendered by Mechdown. Code in this block will still execute in the global scope.
- mech:disabled - This will disable execution of the code block. The code will be rendered as-is, but not executed.

Furthermore, an options map can be provided within curly braces `{}` to specify multiple options in a structured way, where the keys are identifiers and the values are strings. By default, these otions are applied to the style of the code block.

(10.9.1.2) Examples

**Example 1: Unadorned Mech Code**

~~~
my-var := 123     -- This code isn't in a code fence, so there is no output attached.
my-var2 := my-var + 1
~~~

This renders as:

my-var := 123     -- This code isn't in a code fence, so there is no output attached.
my-var2 := my-var + 1

**Example 2: Fenced Mech Code**

~~~
```mech
result := my-var2 * 2   -- This code is in a code fence, so the output will be rendered below.
```
~~~

This renders as:

```mech
result := my-var2 * 2   -- This code is in a code fence, so the output will be rendered below.
```

**Example 3: Fenced Mech Code targeting a sub interpreter**

~~~
```mech:ex1
value := 10 * 5
```
```mech:ex1
result := value + 20
```
~~~

This renders as:

```mech:ex1
value := 10 * 5
```
```mech:ex1
result := value + 20
```

(10.9.2) Inline Mech Code

Mechdown supports inline Mech code, which can be used to embed Mech expressions directly within paragraphs. Inline Mech code comes in two variants:

- `{{expression}}`: This syntax is used for inline Mech code that should be syntax highlighted but not evaluated. It is useful for documentation purposes where you want to show Mech code without executing it.
- `{expression}`: This syntax is used for inline Mech code that should be evaluated and its result displayed within the paragraph. It allows for dynamic content generation based on Mech expressions. If an interpreter is not available, the code will be displayed as-if it were a syntax-highlighted block.

(10.9.2.1) Examples

```
The result of 6 times 7 is {6 * 7}.
The syntax for defining a variable in Mech is {{var-name := value}}.
```

This renders as:

The result of 6 times 7 is {6 * 7}.
The syntax for defining a variable in Mech is {{var-name := value}}.

11. Notation
-------------------------------------------------------------------------------

The grammar is specified using extended Extended Backus-Naur Form (EBNF):

| Symbol   | Meaning    | Semantics                     |
|:--------:|------------|-------------------------------|
|   `p`    | rule       | `p` is a rule in the grammar  |
| `p := q;`| definition | `p` is defined as `q`         |
| `"abc"`  | terminal   | string literal "abc"          |
| `p, q`   | sequence   | `p` followed by `q`           |
| `p | q`  | choice     | `p` or `q`                    |
| `[p, q]` | list       | list of `p` deliniated by `q` |
|   `*p`   | repeat 0   | `p` for 0 or more times       |
|   `+p`   | repeat 1   | `p` for 1 or more times       |
|   `?p`   | optional   | `p` for 0 or 1 time           |
|   `>p`   | peek       | `p`; do not consume input     |
|   `¬p`   | not        | does not match `p`            |
|  `(...)` | group      | increase precedence           |


The grammar grammar:

```ebnf
grammar := +rule ;
identifier := alpha-token, *(alpha-token | digit-token | dash) ;
rule := identifier
      , ":="
      , expression
      , ";" ;
expression := term, *( "|", term ) ;
term := factor, *( ",", factor ) ;
definition := identifier ;
repeat0 := "*", factor ;
repeat1 := "+", factor ;
optional := "?", factor ;
peek := ">", factor ;
not := "¬", factor ;
list := "[", expression, terminal, "]" ;
factor := repeat0 
      | repeat1 
      | optional 
      | peek 
      | not 
      | list
      | group 
      | definition 
      | terminal ;
group := "(", expression, ")" ;
terminal := quote, +any-token, quote ;
```
