DSL Course · FAF-241 · Technical University of Moldova
A domain-specific language where layout is source data. Edit text or drag the canvas — the model stays canonical.
Source
Canvas
The problem
Textual tools like PlantUML give you Git diffs and version control, but any edit can scramble your carefully arranged diagram. Visual editors give you stable layouts, but their binary formats are unreadable in pull requests. No tool has ever satisfied both at once — until now.
| Property | PlantUML | draw.io | Mermaid | Isomorph |
|---|---|---|---|---|
| Text-based source | ✓ | ✗ | ✓ | ✓ |
| Stable layout | ✗ | ✓ | ✗ | ✓ |
| VCS-friendly | ✓ | ✗ | ✓ | ✓ |
| Bidirectional architecture | ✗ | ✗ | ✗ | ✓ |
The language
Every entity keyword is a first-class UML citizen. Visibility modifiers, generics, stereotypes, inheritance — all native syntax. Layout annotations live inline with the semantic body, not in a sidecar file.
diagram LibrarySystem : class {
package domain {
abstract class Book <<Entity>>
implements Borrowable {
+ title : string
+ isbn : string
- stock : int = 0
+ checkOut(user : string) : bool
}
class Library {
+ name : string
+ addBook(book : Book) : void
+ search(query : string) : List<Book>
}
interface Borrowable {
+ borrow(user : string) : void
+ return() : void
}
enum BookStatus {
AVAILABLE
CHECKED_OUT
RESERVED
}
}
// Relation operators — 6 native forms shown
Library --* Book [label="contains", toMult="1..*"]
Book ..|> Borrowable
// Layout — rewritten only on drag, never on edit
@Book at (100, 130)
@Library at (400, 130)
@Borrowable at (100, 360)
@BookStatus at (400, 360)
}
Diagram types
Nine complete UML diagram types — one language, one canonical model.
Relation operators
Structural breadth
Architecture, modules, and deployment.
Class, component, deployment, package, and module views describe what exists and how systems are organized. These are first-class constructs in the grammar, not ad-hoc templates.
Behavioral breadth
Runtime flow, state, and interaction.
Sequence, state, activity, collaboration, and flow diagrams capture what the system does over time. Structure and behavior live in one language and one canonical model.
Bidirectional architecture
parse(serialise(M)) = M
Layout stays in the source, not in a sidecar file
01 · Lex
66 tokens
Longest-match-first scanning. Whitespace and comments discarded. 271 lines, zero dependencies.
02 · Parse
LL(1) hand-written
55 production rules. 22-node typed AST. Errors returned as values, never thrown. 541 lines.
03 · Analyse
14 static rules
Two-pass analysis. Symbol table built first, constraints evaluated second. Catches cyclic inheritance, referential integrity, enum safety.
04 · Render
9 SVG renderers
@Entity at (x,y) coordinates applied from source. ELK fallback for unplaced entities.
ISX file
An `.isx` file stores semantic structure and exact screen coordinates together. Dragging the canvas only rewrites the layout annotations, so visual editing stays deterministic and reviewable in version control.
diagram Payments : component {
component Gateway
component Ledger
Gateway --> Ledger
@Gateway at (120, 140)
@Ledger at (420, 140)
}
Core tech stack
We chose a custom parser and analyzer stack so grammar control, source-mapped errors, round-trip serialization, and invariant preservation all remain under our control. The renderer and editor were built around that same architecture, not bolted on later.
Why custom
Recursive-descent parsing gave us exact control over the language, deterministic edits, and compiler-style diagnostics. That matters when the same source file must drive both text editing and visual geometry.
Semantic safety
14 named static semantic rules validated at compile time, before any rendering occurs. Every violation carries a rule identifier, entity name, and exact source location — not a blank canvas.
What's shipped
CodeMirror 6 IDE
Multi-tab workspace with syntax highlighting, keyboard shortcuts, and a built-in example gallery for real architecture work.
Drag-and-drop canvas
Move any entity on the SVG canvas. Only its @Entity annotation changes. Every other byte in the file stays untouched.
Real-time validation
SS-1 through SS-14 fire on every keystroke. Structured errors with rule ID and source location, never silent failure.
9 diagram renderers
Class, use-case, sequence, component, deployment, state, activity, collaboration, and flow — all producing SVG from one model.
ELK auto-layout
Entities without @annotations are automatically placed using the Eclipse Layout Kernel, stable across re-parses.
Canonical `.isx` source
One file stores the model and the layout. Visual edits remain deterministic text edits instead of hidden binary state.
Structure · behavior · invariants
Open the editor, drag the canvas, and verify that the source stays reviewable while the geometry remains stable.