The PMAP System
Creating a Custom PMAP
Write pseudo in any style or language by defining your own .pmap mapping file.
1. Initialize
The easiest way to start is via pseudo init:
bash
pseudo initThis creates a custom.pmap template at the path you specify and a pseudo.config linking to it.
2. The Template File
custom.pmap
@pmap-version 1.0
@pseudo-version >=1.0 <2.0
@language "Custom"
@author ""
@inherit default.pmap
# ─────────────────────────────────────────────────────────────
# Custom mapping file - generated by: pseudo init
#
# This file APPENDS to default.pmap (patterns tried FIRST).
# Remove or change @inherit to fully replace the default.
#
# PLACEHOLDER TYPES:
# {name:name} single identifier word
# {value:expr} full expression
# {n:number} numeric literal only
# {condition:expr} boolean expression
# {type:word} single type keyword
# {collection:expr} iterable expression
# {text:any} everything to end of line
# ─────────────────────────────────────────────────────────────
# Example: add new ways to write a for loop
# [FOR_LOOP]
# go through {var:name} from {start:expr} to {end:expr}
# count {var:name} from {start:expr} until {end:expr}
# Example: completely replace how PRINT works
# [PRINT] @replace
# yell {value:expr}
# scream {value:expr}3. PMAP File Structure
Every .pmap file must contain:
- Metadata headers - at the top
- Section headers -
[CANONICAL_NAME] - Pattern lines - one per line, below the section header
4. Adding New Mappings
To add a new way to write a FOR_LOOP:
text
[FOR_LOOP]
go through {var:name} from {start:expr} to {end:expr}
count {var:name} from {start:expr} until {end:expr}Your patterns are tried before the default patterns (higher priority).
5. Inherit Modes
| Directive | Behavior |
|---|---|
@inherit default.pmap | APPEND (default): your patterns tried first, then default patterns |
@inherit default.pmap REPLACE | Your section completely replaces the parent section |
@inherit default.pmap PREPEND | Default patterns tried first, yours second |
@ignore-default | Ignore ALL default patterns - only your patterns used |
6. Section-level Replace
Use @replace on a single section header to only replace that canonical:
text
@pmap-version 1.0
@language "Kids"
@inherit default.pmap
# Completely replace PRINT with kid-friendly words
[PRINT] @replace
say {value:expr}
yell {value:expr}
whisper {value:expr}
# Add to existing FOR_EACH (doesn't replace)
[FOR_EACH]
go through each {item:name} in {collection:expr}7. Full Example - Tamil Language
tamil.pmap
@pmap-version 1.0
@pseudo-version >=1.0 <2.0
@language "Tamil"
@author "example"
@inherit default.pmap
[PRINT]
sollu {value:expr}
kaatu {value:expr}
[FOR_LOOP]
for {var:name} irundu {start:expr} varai {end:expr}
[IF]
@context TOP_LEVEL FUNCTION_BODY LOOP_BODY IF_BODY
endral {condition:expr}Use it by running:
bash
pseudo run program.pseudo --lang tamil.pmapOr name your file algo.tamil.pseudo to auto-load it.
8. Validate Your PMAP
bash
pseudo validate custom.pmapOutput
Validating custom.pmap...
✓ 8 patterns loaded.
No errors found.
PMAP Security Rules
.pmap files are data onlyThey cannot execute code, access the filesystem, make network calls, or add new canonical structures. Anything outside the whitelist causes the file to be rejected entirely.
Conflict Detection
At load time, if two patterns in the same canonical section can match the same input, Pseudo warns about unreachable patterns:
text
⚠ Conflict in [FOR_LOOP]: pattern "loop {var:name} from {start:expr} to {end:expr}"
is unreachable - "for {var:name} from {start:expr} to {end:expr}" already matches.
The first pattern always wins.