Quick Start
Parse your first .patch file in 5 minutes.
1. Create a .patch file
Save this as my-venue.patch:
template Stagebox {
meta {
manufacturer: "Yamaha"
model: "Rio3224"
category: "Stagebox"
}
ports {
Dante_Pri: io(etherCON) [Dante, primary]
Mic_In[1..32]: in(XLR)
Line_Out[1..16]: out(XLR)
}
bridge Mic_In -> Dante_Pri
}
template Console {
meta {
manufacturer: "Yamaha"
model: "CL5"
category: "Console"
}
ports {
Dante_Pri: io(etherCON) [Dante, primary]
Dante_Ch[1..72]: in [Dante]
Mix_Bus[1..24]: out
}
}
instance Stage_Left is Stagebox {
location: "Stage Left Wing"
ip: "192.168.1.31"
}
instance FOH is Console {
location: "Front of House"
ip: "192.168.1.10"
}
connect Stage_Left.Dante_Pri -> FOH.Dante_Pri {
cable: "Cat6a_SL"
length: "30m"
}
bridge Stage_Left.Mic_In[1..32] -> FOH.Dante_Ch[1..32]
signal Lead_Vocal {
origin: Stage_Left.Mic_In[1]
description: "Worship leader vocal"
}
2. Parse it
CLI
patchlang my-venue.patch
Output is a JSON AST:
{
"statements": [
{ "type": "Template", "name": "Stagebox", ... },
{ "type": "Template", "name": "Console", ... },
{ "type": "Instance", "name": "Stage_Left", "templateName": "Stagebox", ... },
{ "type": "Instance", "name": "FOH", "templateName": "Console", ... },
{ "type": "Connect", ... },
{ "type": "Bridge", ... },
{ "type": "Signal", "name": "Lead_Vocal", ... }
]
}
JavaScript
import { parse } from './pkg-node/patchlang_wasm.js'
import { readFileSync } from 'fs'
const source = readFileSync('my-venue.patch', 'utf-8')
const result = JSON.parse(parse(source))
console.log(`${result.program.statements.length} statements, ${result.errors.length} errors`)
for (const stmt of result.program.statements) {
console.log(` ${stmt.type}: ${stmt.name || ''}`)
}
Python
import json
import patchlang_python
with open('my-venue.patch') as f:
source = f.read()
result = json.loads(patchlang_python.parse(source))
print(f"{len(result['program']['statements'])} statements")
Rust
let source = std::fs::read_to_string("my-venue.patch").unwrap();
let result = patchlang::parse(&source);
if result.is_valid() {
for stmt in &result.program.statements {
println!("{:?}", stmt);
}
} else {
for err in &result.errors {
eprintln!("{}", err);
}
}
3. What’s in the AST?
The parser produces a PatchProgram with a flat list of statements. Each statement has a type field:
| Type | What it represents |
|---|---|
Template |
Reusable device definition (ports, meta, bridges) |
Instance |
Physical device placed from a template |
Connect |
Physical cable between two ports |
Bridge |
Logical signal mapping (no physical cable) |
BridgeGroup |
Sequential channel mapping from multiple sources |
LinkGroup |
Grouped connections (e.g., quad-link 4K SDI) |
Signal |
Named signal path with origin and properties |
Flag |
Status indicator or alert |
Stream |
Dante/AES67 virtual channel group |
Config |
Per-instance channel labels and metadata |
Use |
Library import |
Ring |
Network ring topology (e.g., OptoCore, MADI ring) |
Next Steps
- Read the full Language Specification for all syntax details
- See Examples for real-world
.patchfiles - Check Installation for your platform