# A floor plan DSL

ArchLang is an open-source language for floor plans, created by
[Chan Meng](https://github.com/ChanMeng666): you write `.arch` text and compile it to SVG, DXF or
PDF.

It is a domain-specific language (DSL): it describes buildings and nothing else. A plan is a
`plan "…" { … }` block of statements such as `wall`, `room`, `door`, `window`, `furniture`, `dim`
and `stair`, measured in millimetres from a top-left origin. On top of those statements it has a
small programming layer — variables, functions, loops and conditionals — that runs while the
drawing is built and then disappears.

## Variables and loops in a floor plan

Three studio units in a row, generated by a `for` loop from three constants and an array of names:

```arch
plan "Studio row" {
  units mm
  grid 50
  let W = 4000
  let H = 5000
  let names = ["Studio A", "Studio B", "Studio C"]

  for i in 0..3 {
    let x = i * W
    wall exterior thickness 200 { (x, 0) (x + W, 0) (x + W, H) (x, H) close }
    room at (x, 0) size W x H label "{names[i]}" uses living
    door at (x + W / 2, H) width 900 wall exterior hinge left swing in
    window at (x + W / 2, 0) width 1600 wall exterior
  }
}
```

The loop expands into three walls, three rooms, three doors and three windows before anything is
drawn. Change `W` and every unit, door and window moves. `npx -y @chanmeng666/archlang describe`
on this source reports three rooms of 20 m² each, 60 m² in all, and `lint` reports no warnings.

## What is in the language

- **Elements**: walls (straight or arc), rooms (rectangles, polygons, circles), doors, windows,
  openings, furniture and fixtures with real plan symbols, dimensions, columns, stairs, lifts,
  roofs, voids, outdoor areas, fences, a title block and a room schedule.
- **Placement by relation**: a room `right-of` another, walls derived from rooms, a door
  `between` two rooms, furniture `against` a wall. See [relational placement](/relational).
- **Scripting**: `let` bindings, value functions, arrays and ranges, string interpolation,
  `for`/`if`/`while`, `set` defaults and reusable components. It expands at compile time: there is
  no runtime, no I/O and no clock ([ADR 3](/adr/0003-expand-time-scripting)).
- **Several storeys** with `level` blocks, compiled to one drawing per storey.
- **Checks**: `describe` reads a compiled plan back as facts (rooms, areas, adjacency, what each
  door connects); `lint` gives advisory warnings such as a bedroom with no window or a bathroom
  reached only through a bedroom. See [Analysis](/analysis).

The [language reference](/reference) covers every statement, and the [one-page spec](/spec)
states the whole language in a form short enough for a model's system prompt.

## Bounded and deterministic

Every input compiles within a fixed step budget and a fixed drawing budget, so a runaway loop is
reported as a diagnostic instead of hanging. The compiler takes no input from the environment, so
the same source gives the same SVG byte for byte. Errors come back as diagnostics with a code, a
line and column, and a suggested fix; the [error catalog](/errors) lists them all.

## Tooling for the language

```bash
npx -y @chanmeng666/archlang spec                  # print the whole language on one page
npx -y @chanmeng666/archlang compile plan.arch -o plan.svg
npx -y @chanmeng666/archlang fmt plan.arch         # format the source
npx -y @chanmeng666/archlang manifest --json       # every command and flag, as data
```

- A VS Code extension (`code --install-extension ChanMeng.archlang`) adds highlighting, live
  diagnostics, completion, hover, go to definition and quick fixes.
- A GBNF grammar ([`/archlang.gbnf`](/archlang.gbnf)) constrains a local model to emit parseable
  source, and a JSON schema ([`/plan.schema.json`](/plan.schema.json)) describes the Plan JSON
  input that `compile --from-json` accepts.

## FAQ

### Is there a programming language for floor plans?

ArchLang is one. A `.arch` file declares walls, rooms, doors and windows in millimetres, and the
compiler draws them as an SVG, DXF or PDF floor plan. It also has variables, functions and loops for
generating repeated or parametric layouts.

### Is ArchLang a general-purpose programming language?

No. Its scripting forms (`let`, functions, `for`, `if`, `while`) exist to generate plan
statements. They expand at compile time, cannot read files or the clock, and run within a fixed
step budget.

### How is a floor plan DSL different from drawing in CAD?

A CAD drawing stores lines and shapes; an ArchLang plan stores rooms, walls and doors as named
things with relations. That lets the compiler report areas, adjacency and reachability, and lets a
change to one number move everything that depends on it. ArchLang exports DXF when the drawing has
to continue in CAD.

### Where is the full grammar?

The [language reference](/reference) documents every statement and clause, the
[one-page spec](/spec) summarises it, and [`/archlang.gbnf`](/archlang.gbnf) is the grammar in
GBNF form.

## Next

- [Floor plans as code](/floor-plans-as-code): writing a plan and compiling it.
- [Guide](/guide): the language from the start.
- [JavaScript library](/javascript): generating `.arch` source from your own code.
