# mimium Syntax Specification (EBNF)
This document describes the formal syntax of the mimium programming language using Extended Backus-Naur Form (EBNF).
## Notation Conventions
- `::=` defines a production rule
- `|` denotes alternatives
- `[ ... ]` denotes optional elements (zero or one)
- `{ ... }` denotes repetition (zero or more)
- `( ... )` groups elements
- `"..."` denotes terminal symbols (keywords/operators)
- `'...'` denotes single character terminals
- `/* ... */` denotes comments about the grammar
## Lexical Elements
### Comments
```ebnf
MultiLineComment ::= "/*" { AnyChar } "*/"
```
### Literals
```ebnf
IntLiteral ::= Digit { Digit }
FloatLiteral ::= Digit { Digit } "." Digit { Digit }
StringLiteral ::= '"' { AnyCharExceptQuote } '"'
### Identifiers
```ebnf
```
## Grammar
### Program Structure
```ebnf
Program ::= { Separator } { TopLevelStatement Separator } { Separator }
TopLevelStatement ::= FunctionDefinition
| GlobalStatement
| ImportStatement
| StageDeclaration
### Stage Declaration
```ebnf
StageDeclaration ::= "#" "stage" "(" StageKind ")"
### Import Statement
```ebnf
ImportStatement ::= "include" "(" StringLiteral ")"
```
### Function Definition
```ebnf
FunctionDefinition ::= "fn" Ident FunctionParams [ "->" Type ] Block
FunctionParams ::= "(" [ ParamList ] ")"
ParamList ::= Parameter { "," Parameter } [ "," ]
Parameter ::= TypedIdent [ "=" Expr ]
```
### Statements
```ebnf
Statement ::= LetStatement
| LetRecStatement
| AssignStatement
| SingleStatement
GlobalStatement ::= Statement
LetStatement ::= "let" TypedPattern "=" ExprGroup
LetRecStatement ::= "letrec" TypedIdent "=" ExprGroup
AssignStatement ::= LValue "=" ExprGroup
SingleStatement ::= ExprGroup
LValue ::= Ident
| LValue "." Ident /* field access */
| LValue "[" Expr "]" /* array access */
```
### Expressions
```ebnf
ExprGroup ::= Block
| IfExpr
| Expr
/* Expression with operator precedence (lowest to highest) */
Expr ::= PipeExpr
/* Precedence 0: Pipe (left associative) */
/* Precedence 1: Schedule (left associative) */
ScheduleExpr ::= OrExpr { "@" OrExpr }
/* Precedence 2: Logical OR (left associative) */
/* Precedence 3: Logical AND (left associative) */
AndExpr ::= EqExpr { "&&" EqExpr }
/* Precedence 4: Equality (left associative) */
/* Precedence 5: Relational (left associative) */
RelExpr ::= AddExpr { ("<" | "<=" | ">" | ">=") AddExpr }
/* Precedence 6: Additive (left associative) */
/* Precedence 7: Multiplicative (left associative) */
MultExpr ::= ExponentExpr { ("*" | "/" | "%") ExponentExpr }
/* Precedence 8: Exponentiation (right associative) */
ExponentExpr ::= UnaryExpr [ "^" ExponentExpr ]
/* Precedence 9: Unary operators */
DotExpr ::= ApplyExpr { "." DotField }
DotField ::= Ident | IntLiteral
/* Function application and array indexing */
CallSuffix ::= "(" [ ArgList ] ")"
IndexSuffix ::= "[" Expr "]"
ArgList ::= Expr { "," Expr } [ "," ]
```
### Atomic Expressions
```ebnf
AtomExpr ::= Literal
| Ident
| LambdaExpr
| MacroExpand
| ParenExpr
| TupleExpr
| ArrayLiteral
| RecordExpr
Literal ::= IntLiteral
| FloatLiteral
| StringLiteral
| "self"
| "now"
| "samplerate"
| "_" /* placeholder */
```
### Lambda Expression
```ebnf
LambdaParams ::= TypedIdent { "," TypedIdent }
```
### Macro Expansion
```ebnf
MacroExpand ::= MacroIdent "(" [ ArgList ] ")"
```
### Parenthesized and Tuple Expressions
```ebnf
ParenExpr ::= "(" Expr ")"
TupleExpr ::= "(" Expr { "," Expr } [ "," ] ")"
```
### Array Literal
```ebnf
ArrayLiteral ::= "[" [ ArgList ] "]"
```
### Record Expressions
```ebnf
RecordLiteral ::= "{" [ RecordFields ] "}"
ImcompleteRecord ::= "{" RecordFields ".." "}"
RecordUpdate ::= "{" Expr "<-" RecordFields "}"
RecordFields ::= RecordField { "," RecordField } [ "," ]
RecordField ::= Ident "=" Expr
```
### Block Expression
```ebnf
Block ::= { "`" | "$" } "{" Statements "}"
Statements ::= { Separator } [ Statement { Separator Statement } ] { Separator }
```
Note: Quote (`` ` ``) and Escape (`$`) operators can be applied to:
- Any expression as unary operators (see `UnaryExpr`)
- Block expressions as shown above
### If Expression
```ebnf
IfExpr ::= "if" "(" Expr ")" ExprGroup [ "else" ExprGroup ]
```
## Types
```ebnf
Type ::= PrimitiveType
| TupleType
| RecordType
| ArrayType
| FunctionType
| CodeType
TupleType ::= "(" Type { "," Type } [ "," ] ")"
RecordType ::= "{" [ RecordTypeFields ] "}"
RecordTypeFields ::= RecordTypeField { "," RecordTypeField } [ "," ]
RecordTypeField ::= Ident ":" Type
ArrayType ::= "[" Type "]"
FunctionType ::= "(" [ TypeList ] ")" "->" Type
TypeList ::= Type { "," Type }
CodeType ::= "`" Type
```
### Type Annotations
```ebnf
TypedIdent ::= Ident [ ":" Type ]
TypedPattern ::= Pattern [ ":" Type ]
```
## Patterns
```ebnf
Pattern ::= SinglePattern
| TuplePattern
| RecordPattern
RecordPattern ::= "{" RecordPatternFields "}"
RecordPatternFields ::= RecordPatternField { "," RecordPatternField } [ "," ]
RecordPatternField ::= Ident "=" Pattern
```
## Multi-Stage Programming
mimium supports multi-stage programming with quote and escape operators.
Quote (`` ` ``) creates a code representation (lifts a value to the next stage),
while Escape/Splice (`$`) splices code into a quoted context (drops to the previous stage).
These operators are defined as:
- Unary operators in `UnaryExpr` (applicable to any expression)
- Prefix operators for `Block` expressions
They can be chained, e.g., ``` ``expr ``` or `$$expr`.
## Examples
### Simple Function Definition
```mimium
fn add(x: float, y: float) -> float {
x + y
}
```
Parsed as:
```
FunctionDefinition
├── Ident: "add"
├── FunctionParams
│ ├── Parameter: x: float
│ └── Parameter: y: float
├── ReturnType: float
└── Block
└── BinaryOp(+)
├── Var: x
└── Var: y
```
### Lambda Expression
```mimium
### Record Literal and Update
```mimium
let r = { a = 1, b = 2 }
let r2 = { r <- a = 10 }
```
### Scheduled Expression
```mimium
fn dsp() {
osc(440) @ (now + 1000)
}
```
### Macro Expansion
```mimium
Slider!(freq, 440, 20, 20000)
```
---
*This specification is derived from the parser implementation in mimium-rs.*