DSL Course · FAF-241 · Technical University of Moldova

Diagrams that
remember themselves

A domain-specific language where layout is source data. Edit text or drag the canvas — the model stays canonical.

library-system.isx

Source

diagram LibrarySystem : class {
package domain {
abstract class Book implements Borrowable {
+ title : string
+ isbn : string
- stock : int = 0
}
class Library {
+ addBook(b : Book) : void
+ search() : List<Book>
}
interface Borrowable {
+ borrow() : void
}
}
Library --* Book [label="contains"]
Book ..|> Borrowable
// Layout — first-class source data
@Book at (120, 140)
@Library at (400, 140)
@Borrowable at (260, 245)
}

Canvas

package domain abstract class Book + title : string + isbn : string - stock : int = 0 Library + addBook(b : Book) + search() : List<Book> interface Borrowable contains @Book at (120, 140) @Library at (400, 140) ⊹
9
Diagram types
4
Competitors compared
55
Grammar rules
66
Token kinds
14
Semantic rules

One tool makes you
choose a side

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 ✗ ✗ ✗ ✓

Reads like English.
Compiles like a type system.

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.

library.isx Isomorph · class
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) }

Nine complete UML diagram types — one language, one canonical model.

class usecase sequence component deployment state activity collaboration flow
--> Association
-|> Generalization
..|> Realization
--* Composition
--o Aggregation
..> Dependency

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.

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.

The only invariant
that matters

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.

One file for code,
layout, and round-trip edits

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.

payments.isx Source of truth
diagram Payments : component { component Gateway component Ledger Gateway --> Ledger @Gateway at (120, 140) @Ledger at (420, 140) }

Handcrafted recursive descent.
No ANTLR, no Chevrotain.

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.

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.

Handwritten lexer + recursive-descent parser
Two-pass analyzer with 14 semantic rules
Custom renderer and editor integration

Errors are values,
not surprises

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.

SS-1 Entity name uniqueness within diagram scope
SS-2 Member name uniqueness within each entity
SS-3 Referential integrity of relation endpoints
SS-4 Enum non-emptiness — at least one value required
SS-5 Interface fields carry no default values
SS-6 Acyclic direct inheritance — no A extends B extends A
SS-7 Style target references a declared entity
SS-8 Enum value uniqueness within each enum body
SS-9 Diagram kind compatibility — entity type matches context
SS-10 Layout annotation references a declared entity
SS-11 Abstract and final are mutually exclusive modifiers
SS-12 Method parameter name uniqueness per signature
SS-13 Extends target must reference a declared entity
SS-14 Implements target must reference a declared entity

A complete IDE,
deployed today

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.

Explore the IDE,
inspect the source

Open the editor, drag the canvas, and verify that the source stays reviewable while the geometry remains stable.

Open Isomorph IDE View on GitHub