@chanmeng666/archlang 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +175 -169
- package/dist/{chunk-DHNWMOP7.js → chunk-PABYLU6Z.js} +530 -53
- package/dist/chunk-PABYLU6Z.js.map +1 -0
- package/dist/cli.js +52 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +164 -1
- package/dist/index.js +9 -3
- package/examples/themed.arch +40 -0
- package/package.json +9 -2
- package/dist/chunk-DHNWMOP7.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,37 @@ type Expr = {
|
|
|
70
70
|
r: Expr;
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Theme: colours, line-weight, and font for the rendered drawing.
|
|
75
|
+
*
|
|
76
|
+
* Resolution order (later wins): {@link DEFAULT_THEME} → the plan's `theme { … }`
|
|
77
|
+
* directive → `CompileOptions.theme`. Merging is a shallow override, so any
|
|
78
|
+
* subset of keys may be supplied at either layer.
|
|
79
|
+
*/
|
|
80
|
+
interface Theme {
|
|
81
|
+
bg: string;
|
|
82
|
+
pocheBase: string;
|
|
83
|
+
pocheHatch: string;
|
|
84
|
+
wallStroke: string;
|
|
85
|
+
roomFill: string;
|
|
86
|
+
roomLabel: string;
|
|
87
|
+
areaLabel: string;
|
|
88
|
+
furnitureStroke: string;
|
|
89
|
+
furnitureFill: string;
|
|
90
|
+
furnitureLabel: string;
|
|
91
|
+
opening: string;
|
|
92
|
+
doorLeaf: string;
|
|
93
|
+
windowPane: string;
|
|
94
|
+
dim: string;
|
|
95
|
+
annotation: string;
|
|
96
|
+
annotationMuted: string;
|
|
97
|
+
column: string;
|
|
98
|
+
/** Multiplier on all stroke widths (1 = default). */
|
|
99
|
+
lineWeight: number;
|
|
100
|
+
/** SVG `font-family`. */
|
|
101
|
+
font: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
73
104
|
/** Abstract syntax tree for an ArchLang `plan`. All distances are in millimetres.
|
|
74
105
|
*
|
|
75
106
|
* The AST is the raw, immutable output of parsing: `resolve()` (see ir.ts) reads
|
|
@@ -104,6 +135,8 @@ interface WallNode extends NodeBase {
|
|
|
104
135
|
category: string;
|
|
105
136
|
/** Wall thickness in mm. */
|
|
106
137
|
thickness: Expr;
|
|
138
|
+
/** Optional hatch material (e.g. "brick"); defaults to the poché hatch. */
|
|
139
|
+
material?: string;
|
|
107
140
|
/** Polyline vertices in order. */
|
|
108
141
|
points: ExprPoint[];
|
|
109
142
|
/** Whether the polyline closes back to its first vertex. */
|
|
@@ -202,6 +235,8 @@ interface PlanNode {
|
|
|
202
235
|
scale?: string;
|
|
203
236
|
north: NorthDir;
|
|
204
237
|
title?: TitleNode;
|
|
238
|
+
/** Theme overrides from the `theme { … }` directive. */
|
|
239
|
+
theme?: Partial<Theme>;
|
|
205
240
|
/** Component definitions, by name. */
|
|
206
241
|
components: Map<string, ComponentDef>;
|
|
207
242
|
/** All statements (elements, `let`s, instances), in source order. */
|
|
@@ -225,6 +260,11 @@ interface CompileOptions {
|
|
|
225
260
|
width?: number;
|
|
226
261
|
/** Bypass the internal memoization cache (mostly for benchmarks/tests). */
|
|
227
262
|
noCache?: boolean;
|
|
263
|
+
/**
|
|
264
|
+
* Theme overrides applied on top of the plan's `theme { … }` directive and
|
|
265
|
+
* the built-in defaults (these win). Any subset of keys may be supplied.
|
|
266
|
+
*/
|
|
267
|
+
theme?: Partial<Theme>;
|
|
228
268
|
}
|
|
229
269
|
interface CompileResult {
|
|
230
270
|
/** The rendered SVG document, or `""` when there were fatal errors. */
|
|
@@ -242,6 +282,129 @@ interface CompileResult {
|
|
|
242
282
|
ast?: PlanNode;
|
|
243
283
|
}
|
|
244
284
|
|
|
285
|
+
/** Pure geometry helpers. All coordinates in millimetres. Deterministic. */
|
|
286
|
+
|
|
287
|
+
interface WallSegment {
|
|
288
|
+
a: Point;
|
|
289
|
+
b: Point;
|
|
290
|
+
thickness: number;
|
|
291
|
+
category: string;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Intermediate representation + `resolve(ast)`.
|
|
296
|
+
*
|
|
297
|
+
* `resolve` is the single place semantics live: it grid-snaps coordinates,
|
|
298
|
+
* assigns ids, hosts openings, and runs semantic checks — producing a NEW
|
|
299
|
+
* immutable IR (the input AST is never mutated). `render` consumes IR only.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
interface RBase {
|
|
303
|
+
kind: ElementKind;
|
|
304
|
+
id: string;
|
|
305
|
+
span?: Span;
|
|
306
|
+
}
|
|
307
|
+
interface RWall extends RBase {
|
|
308
|
+
kind: "wall";
|
|
309
|
+
category: string;
|
|
310
|
+
thickness: number;
|
|
311
|
+
/** Resolved hatch material (always a known material; defaults to "poche"). */
|
|
312
|
+
material: string;
|
|
313
|
+
points: Point[];
|
|
314
|
+
closed: boolean;
|
|
315
|
+
}
|
|
316
|
+
interface RRoom extends RBase {
|
|
317
|
+
kind: "room";
|
|
318
|
+
at: Point;
|
|
319
|
+
size: {
|
|
320
|
+
w: number;
|
|
321
|
+
h: number;
|
|
322
|
+
};
|
|
323
|
+
label?: string;
|
|
324
|
+
}
|
|
325
|
+
interface RDoor extends RBase {
|
|
326
|
+
kind: "door";
|
|
327
|
+
at: Point;
|
|
328
|
+
width: number;
|
|
329
|
+
hinge: "left" | "right";
|
|
330
|
+
swing: "in" | "out";
|
|
331
|
+
host: WallSegment | null;
|
|
332
|
+
}
|
|
333
|
+
interface RWindow extends RBase {
|
|
334
|
+
kind: "window";
|
|
335
|
+
at: Point;
|
|
336
|
+
width: number;
|
|
337
|
+
host: WallSegment | null;
|
|
338
|
+
}
|
|
339
|
+
interface RFurniture extends RBase {
|
|
340
|
+
kind: "furniture";
|
|
341
|
+
category: string;
|
|
342
|
+
at: Point;
|
|
343
|
+
size: {
|
|
344
|
+
w: number;
|
|
345
|
+
h: number;
|
|
346
|
+
};
|
|
347
|
+
label?: string;
|
|
348
|
+
}
|
|
349
|
+
interface RDim extends RBase {
|
|
350
|
+
kind: "dim";
|
|
351
|
+
from: Point;
|
|
352
|
+
to: Point;
|
|
353
|
+
offset: number;
|
|
354
|
+
text?: string;
|
|
355
|
+
}
|
|
356
|
+
interface RColumn extends RBase {
|
|
357
|
+
kind: "column";
|
|
358
|
+
at: Point;
|
|
359
|
+
size: {
|
|
360
|
+
w: number;
|
|
361
|
+
h: number;
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
type ResolvedElement = RWall | RRoom | RDoor | RWindow | RFurniture | RDim | RColumn;
|
|
365
|
+
interface ResolvedPlan {
|
|
366
|
+
name: string;
|
|
367
|
+
units: "mm";
|
|
368
|
+
grid: number;
|
|
369
|
+
scale?: string;
|
|
370
|
+
north: NorthDir;
|
|
371
|
+
title?: TitleNode;
|
|
372
|
+
theme?: Partial<Theme>;
|
|
373
|
+
/** Resolved elements, in source order (for rendering). */
|
|
374
|
+
elements: ResolvedElement[];
|
|
375
|
+
/** Resolved walls (for bounds/hosting), in source order. */
|
|
376
|
+
walls: RWall[];
|
|
377
|
+
}
|
|
378
|
+
declare function resolve(ast: PlanNode): {
|
|
379
|
+
ir: ResolvedPlan;
|
|
380
|
+
diagnostics: Diagnostic[];
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* DXF export backend — consumes the resolved IR and emits ASCII DXF (R12 /
|
|
385
|
+
* AC1009, the most broadly importable flavor). Pure, synchronous, zero-dep:
|
|
386
|
+
* DXF is plain text, so this needs no external library and is safe to ship in
|
|
387
|
+
* the core. It is NOT part of `compile()` — call it on the IR from `resolve()`.
|
|
388
|
+
*
|
|
389
|
+
* DXF's Y axis points up, while ArchLang's Y points down (SVG convention), so
|
|
390
|
+
* every coordinate's Y is negated here to keep plans right-side-up in CAD.
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
/** Render a resolved plan as an ASCII DXF document string. */
|
|
394
|
+
declare function toDxf(ir: ResolvedPlan): string;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* PDF export backend — consumes the produced SVG and renders it into a PDF via
|
|
398
|
+
* pdfkit + svg-to-pdfkit. These are OPTIONAL dependencies, lazy-`import()`ed so
|
|
399
|
+
* the zero-dep core never hard-requires them; a clear error is thrown if they
|
|
400
|
+
* are absent. This is async and Node-oriented — NOT part of `compile()`.
|
|
401
|
+
*/
|
|
402
|
+
/**
|
|
403
|
+
* Convert an ArchLang SVG string to a PDF (returned as a Uint8Array).
|
|
404
|
+
* Requires the optional `pdfkit` and `svg-to-pdfkit` packages.
|
|
405
|
+
*/
|
|
406
|
+
declare function toPdf(svg: string): Promise<Uint8Array>;
|
|
407
|
+
|
|
245
408
|
/**
|
|
246
409
|
* ArchLang — compile declarative floor-plan source to a professional SVG.
|
|
247
410
|
*
|
|
@@ -254,4 +417,4 @@ declare function compile(source: string, opts?: CompileOptions): CompileResult;
|
|
|
254
417
|
/** Clear the internal compile cache (useful in long-lived processes/tests). */
|
|
255
418
|
declare function clearCache(): void;
|
|
256
419
|
|
|
257
|
-
export { type AstElement, type ColumnNode, type CompileError, type CompileOptions, type CompileResult, type CompileWarning, type ComponentDef, type Diagnostic, type DimNode, type DoorNode, type ElementKind, type ExprPoint, type FurnitureNode, type InstanceNode, type LetNode, type NodeBase, type NorthDir, type PlanNode, type Point, type RoomNode, type Severity, type Span, type Statement, type TitleNode, type WallNode, type WindowNode, clearCache, compile, formatDiagnostic, offsetToLineCol };
|
|
420
|
+
export { type AstElement, type ColumnNode, type CompileError, type CompileOptions, type CompileResult, type CompileWarning, type ComponentDef, type Diagnostic, type DimNode, type DoorNode, type ElementKind, type ExprPoint, type FurnitureNode, type InstanceNode, type LetNode, type NodeBase, type NorthDir, type PlanNode, type Point, type RColumn, type RDim, type RDoor, type RFurniture, type RRoom, type RWall, type RWindow, type ResolvedElement, type ResolvedPlan, type RoomNode, type Severity, type Span, type Statement, type TitleNode, type WallNode, type WindowNode, clearCache, compile, formatDiagnostic, offsetToLineCol, resolve, toDxf, toPdf };
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,18 @@ import {
|
|
|
2
2
|
clearCache,
|
|
3
3
|
compile,
|
|
4
4
|
formatDiagnostic,
|
|
5
|
-
offsetToLineCol
|
|
6
|
-
|
|
5
|
+
offsetToLineCol,
|
|
6
|
+
resolve,
|
|
7
|
+
toDxf,
|
|
8
|
+
toPdf
|
|
9
|
+
} from "./chunk-PABYLU6Z.js";
|
|
7
10
|
export {
|
|
8
11
|
clearCache,
|
|
9
12
|
compile,
|
|
10
13
|
formatDiagnostic,
|
|
11
|
-
offsetToLineCol
|
|
14
|
+
offsetToLineCol,
|
|
15
|
+
resolve,
|
|
16
|
+
toDxf,
|
|
17
|
+
toPdf
|
|
12
18
|
};
|
|
13
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Theming + materials: a two-room plan with a brick exterior, a partition,
|
|
2
|
+
# and a dark "blueprint" theme. Try CompileOptions.theme to override at runtime.
|
|
3
|
+
plan "Themed Duplex" {
|
|
4
|
+
units mm
|
|
5
|
+
grid 50
|
|
6
|
+
scale 1:100
|
|
7
|
+
north up
|
|
8
|
+
|
|
9
|
+
theme {
|
|
10
|
+
background: "#1e2127"
|
|
11
|
+
wall: "#e8e8e8"
|
|
12
|
+
wallFill: "#3a3f4b"
|
|
13
|
+
wallHatch: "#5a6172"
|
|
14
|
+
room: "#272b33"
|
|
15
|
+
roomLabel: "#f0f0f0"
|
|
16
|
+
areaLabel: "#9aa0aa"
|
|
17
|
+
furniture: "#2f343d"
|
|
18
|
+
dim: "#6cb6ff"
|
|
19
|
+
annotation: "#cfd3da"
|
|
20
|
+
font: "Georgia, serif"
|
|
21
|
+
lineWeight: 1.3
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let W = 6000
|
|
25
|
+
let H = 4000
|
|
26
|
+
|
|
27
|
+
wall exterior thickness 250 material brick { (0,0) (W,0) (W,H) (0,H) close }
|
|
28
|
+
wall partition thickness 100 { (3000,0) (3000,H) }
|
|
29
|
+
|
|
30
|
+
room id=a at (0,0) size 3000x4000 label "Living"
|
|
31
|
+
room id=b at (3000,0) size 3000x4000 label "Bedroom"
|
|
32
|
+
|
|
33
|
+
furniture bed at (3300,300) size 1500x2000 label "Bed"
|
|
34
|
+
|
|
35
|
+
door at (3000,2000) width 900 wall partition hinge left swing in
|
|
36
|
+
window at (1500,0) width 1600 wall exterior
|
|
37
|
+
window at (4500,0) width 1200 wall exterior
|
|
38
|
+
|
|
39
|
+
dim (0,H)->(W,H) offset 600 text "6000"
|
|
40
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chanmeng666/archlang",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A small declarative language that compiles to professional SVG floor plans — like Typst/LaTeX, but for architecture.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"architecture",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"test": "vitest run",
|
|
53
53
|
"test:watch": "vitest",
|
|
54
54
|
"cli": "tsx src/cli.ts",
|
|
55
|
+
"bench": "tsx bench/run.ts",
|
|
55
56
|
"prepublishOnly": "npm run build && npm run test"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
@@ -60,6 +61,12 @@
|
|
|
60
61
|
"tsup": "^8.3.5",
|
|
61
62
|
"tsx": "^4.19.2",
|
|
62
63
|
"typescript": "^5.7.2",
|
|
63
|
-
"vitest": "^2.1.8"
|
|
64
|
+
"vitest": "^2.1.8",
|
|
65
|
+
"vscode-oniguruma": "^2.0.1",
|
|
66
|
+
"vscode-textmate": "^9.3.2"
|
|
67
|
+
},
|
|
68
|
+
"optionalDependencies": {
|
|
69
|
+
"pdfkit": "^0.15.2",
|
|
70
|
+
"svg-to-pdfkit": "^0.1.8"
|
|
64
71
|
}
|
|
65
72
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lexer.ts","../src/expr.ts","../src/geometry.ts","../src/elements/wall.ts","../src/elements/room.ts","../src/elements/door.ts","../src/elements/window.ts","../src/elements/furniture.ts","../src/elements/dim.ts","../src/elements/column.ts","../src/elements/index.ts","../src/parser.ts","../src/ir.ts","../src/registry.ts","../src/render.ts","../src/diagnostics.ts","../src/index.ts"],"sourcesContent":["/** Hand-written lexer for ArchLang. Zero dependencies; tracks line/col. */\r\n\r\nexport type TokenType =\r\n | \"ident\"\r\n | \"number\"\r\n | \"string\"\r\n | \"dimension\" // e.g. 4000x3000\r\n | \"lparen\"\r\n | \"rparen\"\r\n | \"lcurly\"\r\n | \"rcurly\"\r\n | \"comma\"\r\n | \"equals\"\r\n | \"colon\"\r\n | \"arrow\" // ->\r\n | \"plus\" // +\r\n | \"minus\" // - (binary or unary; arrow -> is separate)\r\n | \"star\" // *\r\n | \"slash\" // /\r\n | \"percent\" // %\r\n | \"eof\";\r\n\r\nexport interface Token {\r\n type: TokenType;\r\n value: string;\r\n /** For \"number\": the parsed value. For \"dimension\": w. */\r\n num?: number;\r\n /** For \"dimension\": h. */\r\n num2?: number;\r\n line: number;\r\n col: number;\r\n /** Byte offset of the token's first character into the source. */\r\n start: number;\r\n /** Byte offset just past the token's last character. */\r\n end: number;\r\n}\r\n\r\nexport interface LexResult {\r\n tokens: Token[];\r\n errors: { message: string; span: { start: number; end: number } }[];\r\n}\r\n\r\nconst isDigit = (c: string) => c >= \"0\" && c <= \"9\";\r\nconst isIdentStart = (c: string) =>\r\n (c >= \"a\" && c <= \"z\") || (c >= \"A\" && c <= \"Z\") || c === \"_\";\r\nconst isIdentPart = (c: string) => isIdentStart(c) || isDigit(c);\r\n\r\nexport function lex(src: string): LexResult {\r\n const tokens: Token[] = [];\r\n const errors: { message: string; span: { start: number; end: number } }[] = [];\r\n let i = 0;\r\n let line = 1;\r\n let col = 1;\r\n\r\n const peek = (o = 0) => src[i + o] ?? \"\";\r\n const advance = () => {\r\n const c = src[i++];\r\n if (c === \"\\n\") {\r\n line++;\r\n col = 1;\r\n } else {\r\n col++;\r\n }\r\n return c;\r\n };\r\n const push = (\r\n type: TokenType,\r\n value: string,\r\n startLine: number,\r\n startCol: number,\r\n startIdx: number,\r\n extra?: Partial<Token>,\r\n ) => tokens.push({ type, value, line: startLine, col: startCol, ...extra, start: startIdx, end: i });\r\n\r\n while (i < src.length) {\r\n const c = peek();\r\n const startLine = line;\r\n const startCol = col;\r\n const startIdx = i;\r\n\r\n // Whitespace\r\n if (c === \" \" || c === \"\\t\" || c === \"\\r\" || c === \"\\n\") {\r\n advance();\r\n continue;\r\n }\r\n\r\n // Comment to end of line\r\n if (c === \"#\") {\r\n while (i < src.length && peek() !== \"\\n\") advance();\r\n continue;\r\n }\r\n\r\n // String literal with \\\" and \\\\ escapes\r\n if (c === '\"') {\r\n advance();\r\n let value = \"\";\r\n let terminated = false;\r\n while (i < src.length) {\r\n const ch = peek();\r\n if (ch === \"\\\\\") {\r\n advance();\r\n const esc = advance();\r\n value += esc === \"n\" ? \"\\n\" : esc;\r\n continue;\r\n }\r\n if (ch === '\"') {\r\n advance();\r\n terminated = true;\r\n break;\r\n }\r\n if (ch === \"\\n\") break; // strings don't span lines\r\n value += advance();\r\n }\r\n if (!terminated) {\r\n errors.push({ message: \"Unterminated string literal\", span: { start: startIdx, end: i } });\r\n }\r\n push(\"string\", value, startLine, startCol, startIdx);\r\n continue;\r\n }\r\n\r\n // Punctuation & operators\r\n if (c === \"(\") { advance(); push(\"lparen\", \"(\", startLine, startCol, startIdx); continue; }\r\n if (c === \")\") { advance(); push(\"rparen\", \")\", startLine, startCol, startIdx); continue; }\r\n if (c === \"{\") { advance(); push(\"lcurly\", \"{\", startLine, startCol, startIdx); continue; }\r\n if (c === \"}\") { advance(); push(\"rcurly\", \"}\", startLine, startCol, startIdx); continue; }\r\n if (c === \",\") { advance(); push(\"comma\", \",\", startLine, startCol, startIdx); continue; }\r\n if (c === \"=\") { advance(); push(\"equals\", \"=\", startLine, startCol, startIdx); continue; }\r\n if (c === \":\") { advance(); push(\"colon\", \":\", startLine, startCol, startIdx); continue; }\r\n if (c === \"-\" && peek(1) === \">\") { advance(); advance(); push(\"arrow\", \"->\", startLine, startCol, startIdx); continue; }\r\n\r\n // Arithmetic operators (unary minus is handled by the expression parser).\r\n if (c === \"+\") { advance(); push(\"plus\", \"+\", startLine, startCol, startIdx); continue; }\r\n if (c === \"-\") { advance(); push(\"minus\", \"-\", startLine, startCol, startIdx); continue; }\r\n if (c === \"*\") { advance(); push(\"star\", \"*\", startLine, startCol, startIdx); continue; }\r\n if (c === \"/\") { advance(); push(\"slash\", \"/\", startLine, startCol, startIdx); continue; }\r\n if (c === \"%\") { advance(); push(\"percent\", \"%\", startLine, startCol, startIdx); continue; }\r\n\r\n // Number (optionally part of a literal dimension WxH). Numbers are\r\n // non-negative; negation is a unary operator in expressions.\r\n if (isDigit(c) || (c === \".\" && isDigit(peek(1)))) {\r\n let raw = \"\";\r\n while (isDigit(peek())) raw += advance();\r\n if (peek() === \".\") {\r\n raw += advance();\r\n while (isDigit(peek())) raw += advance();\r\n }\r\n const first = parseFloat(raw);\r\n // Dimension: <num>x<num>\r\n if (peek() === \"x\" && (isDigit(peek(1)) || (peek(1) === \".\" && isDigit(peek(2))))) {\r\n advance(); // consume 'x'\r\n let raw2 = \"\";\r\n while (isDigit(peek())) raw2 += advance();\r\n if (peek() === \".\") {\r\n raw2 += advance();\r\n while (isDigit(peek())) raw2 += advance();\r\n }\r\n const second = parseFloat(raw2);\r\n push(\"dimension\", `${raw}x${raw2}`, startLine, startCol, startIdx, { num: first, num2: second });\r\n continue;\r\n }\r\n push(\"number\", raw, startLine, startCol, startIdx, { num: first });\r\n continue;\r\n }\r\n\r\n // Identifier / keyword\r\n if (isIdentStart(c)) {\r\n let value = \"\";\r\n while (i < src.length && isIdentPart(peek())) value += advance();\r\n push(\"ident\", value, startLine, startCol, startIdx);\r\n continue;\r\n }\r\n\r\n // Unknown character\r\n errors.push({ message: `Unexpected character ${JSON.stringify(c)}`, span: { start: startIdx, end: startIdx + 1 } });\r\n advance();\r\n }\r\n\r\n push(\"eof\", \"\", line, col, i);\r\n return { tokens, errors };\r\n}\r\n","/**\r\n * Arithmetic expressions: a small Pratt parser + a pure evaluator.\r\n *\r\n * Expressions appear anywhere a number does (coordinates, sizes, widths,\r\n * thickness, offsets). They are parsed into an {@link Expr} AST and evaluated\r\n * during `resolve` against an {@link Env} of `let`/parameter bindings.\r\n */\r\n\r\nimport type { Token, TokenType } from \"./lexer.js\";\r\nimport type { Diagnostic, Span } from \"./diagnostics.js\";\r\n\r\nexport type Expr =\r\n | { t: \"num\"; value: number }\r\n | { t: \"ref\"; name: string; span?: Span }\r\n | { t: \"unary\"; op: \"-\" | \"+\"; e: Expr }\r\n | { t: \"bin\"; op: \"+\" | \"-\" | \"*\" | \"/\" | \"%\"; l: Expr; r: Expr };\r\n\r\nexport type Env = Map<string, number>;\r\n\r\n/** Minimal token-stream the expression parser needs (satisfied by ParseCtx). */\r\nexport interface ExprTokens {\r\n peek(o?: number): Token;\r\n next(): Token;\r\n fail(msg: string, t?: Token): never;\r\n}\r\n\r\nconst BIN_PREC: Partial<Record<TokenType, number>> = {\r\n plus: 1,\r\n minus: 1,\r\n star: 2,\r\n slash: 2,\r\n percent: 2,\r\n};\r\nconst BIN_OP: Partial<Record<TokenType, \"+\" | \"-\" | \"*\" | \"/\" | \"%\">> = {\r\n plus: \"+\",\r\n minus: \"-\",\r\n star: \"*\",\r\n slash: \"/\",\r\n percent: \"%\",\r\n};\r\n\r\n/** Parse an expression (Pratt / precedence-climbing). */\r\nexport function parseExpr(ts: ExprTokens): Expr {\r\n return parseBin(ts, 1);\r\n}\r\n\r\nfunction parseBin(ts: ExprTokens, minPrec: number): Expr {\r\n let left = parseUnary(ts);\r\n for (;;) {\r\n const t = ts.peek();\r\n const prec = BIN_PREC[t.type];\r\n if (prec === undefined || prec < minPrec) break;\r\n ts.next();\r\n const right = parseBin(ts, prec + 1);\r\n left = { t: \"bin\", op: BIN_OP[t.type]!, l: left, r: right };\r\n }\r\n return left;\r\n}\r\n\r\nfunction parseUnary(ts: ExprTokens): Expr {\r\n const t = ts.peek();\r\n if (t.type === \"minus\" || t.type === \"plus\") {\r\n ts.next();\r\n return { t: \"unary\", op: t.type === \"minus\" ? \"-\" : \"+\", e: parseUnary(ts) };\r\n }\r\n return parseAtom(ts);\r\n}\r\n\r\nfunction parseAtom(ts: ExprTokens): Expr {\r\n const t = ts.peek();\r\n if (t.type === \"number\") {\r\n ts.next();\r\n return { t: \"num\", value: t.num! };\r\n }\r\n if (t.type === \"ident\") {\r\n ts.next();\r\n return { t: \"ref\", name: t.value, span: { start: t.start, end: t.end } };\r\n }\r\n if (t.type === \"lparen\") {\r\n ts.next();\r\n const e = parseExpr(ts);\r\n const close = ts.peek();\r\n if (close.type !== \"rparen\") ts.fail(`Expected \")\" but found ${describe(close)}`);\r\n ts.next();\r\n return e;\r\n }\r\n return ts.fail(`Expected a number, name, or \"(\" but found ${describe(t)}`);\r\n}\r\n\r\n/** Evaluate an expression. Errors (unknown ref, division by zero) emit a\r\n * diagnostic and yield 0 so resolution can continue and report everything. */\r\nexport function evalExpr(e: Expr, env: Env, onError: (d: Diagnostic) => void): number {\r\n switch (e.t) {\r\n case \"num\":\r\n return e.value;\r\n case \"ref\": {\r\n const v = env.get(e.name);\r\n if (v === undefined) {\r\n const hint = closest(e.name, [...env.keys()]);\r\n onError({\r\n severity: \"error\",\r\n message: `Unknown name \"${e.name}\"`,\r\n code: \"E_UNKNOWN_REF\",\r\n span: e.span,\r\n hints: hint ? [`did you mean \"${hint}\"?`] : undefined,\r\n });\r\n return 0;\r\n }\r\n return v;\r\n }\r\n case \"unary\": {\r\n const v = evalExpr(e.e, env, onError);\r\n return e.op === \"-\" ? -v : v;\r\n }\r\n case \"bin\": {\r\n const l = evalExpr(e.l, env, onError);\r\n const r = evalExpr(e.r, env, onError);\r\n switch (e.op) {\r\n case \"+\": return l + r;\r\n case \"-\": return l - r;\r\n case \"*\": return l * r;\r\n case \"/\":\r\n case \"%\":\r\n if (r === 0) {\r\n onError({ severity: \"error\", message: `${e.op === \"/\" ? \"Division\" : \"Modulo\"} by zero`, code: \"E_DIV_ZERO\" });\r\n return 0;\r\n }\r\n return e.op === \"/\" ? l / r : l % r;\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction describe(t: Token): string {\r\n if (t.type === \"eof\") return \"end of input\";\r\n if (t.type === \"string\") return `string ${JSON.stringify(t.value)}`;\r\n return `\"${t.value}\"`;\r\n}\r\n\r\n/** Nearest candidate within a small edit distance, for \"did you mean\" hints. */\r\nexport function closest(name: string, candidates: string[]): string | null {\r\n let best: string | null = null;\r\n let bestDist = Infinity;\r\n for (const c of candidates) {\r\n const d = levenshtein(name, c);\r\n if (d < bestDist) {\r\n bestDist = d;\r\n best = c;\r\n }\r\n }\r\n // Only suggest when reasonably close (≤ 2 edits, or ≤ a third of the length).\r\n const limit = Math.max(2, Math.floor(name.length / 3));\r\n return best !== null && bestDist <= limit ? best : null;\r\n}\r\n\r\nfunction levenshtein(a: string, b: string): number {\r\n const m = a.length;\r\n const n = b.length;\r\n const dp = Array.from({ length: m + 1 }, (_, i) => i);\r\n for (let j = 1; j <= n; j++) {\r\n let prev = dp[0];\r\n dp[0] = j;\r\n for (let i = 1; i <= m; i++) {\r\n const tmp = dp[i];\r\n dp[i] = Math.min(\r\n dp[i] + 1,\r\n dp[i - 1] + 1,\r\n prev + (a[i - 1] === b[j - 1] ? 0 : 1),\r\n );\r\n prev = tmp;\r\n }\r\n }\r\n return dp[m];\r\n}\r\n","/** Pure geometry helpers. All coordinates in millimetres. Deterministic. */\r\n\r\nimport type { Point } from \"./ast.js\";\r\n\r\nexport interface Vec {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport const sub = (a: Point, b: Point): Vec => ({ x: a.x - b.x, y: a.y - b.y });\r\nexport const add = (a: Point, b: Vec): Point => ({ x: a.x + b.x, y: a.y + b.y });\r\nexport const mul = (v: Vec, s: number): Vec => ({ x: v.x * s, y: v.y * s });\r\nexport const length = (v: Vec): number => Math.hypot(v.x, v.y);\r\nexport function unit(v: Vec): Vec {\r\n const l = length(v);\r\n return l === 0 ? { x: 0, y: 0 } : { x: v.x / l, y: v.y / l };\r\n}\r\n/** Left normal (rotate +90°). */\r\nexport const normal = (v: Vec): Vec => ({ x: -v.y, y: v.x });\r\n\r\nexport interface Bounds {\r\n minX: number;\r\n minY: number;\r\n maxX: number;\r\n maxY: number;\r\n}\r\n\r\nexport const emptyBounds = (): Bounds => ({\r\n minX: Infinity,\r\n minY: Infinity,\r\n maxX: -Infinity,\r\n maxY: -Infinity,\r\n});\r\n\r\nexport function extendBounds(b: Bounds, x: number, y: number): void {\r\n if (x < b.minX) b.minX = x;\r\n if (y < b.minY) b.minY = y;\r\n if (x > b.maxX) b.maxX = x;\r\n if (y > b.maxY) b.maxY = y;\r\n}\r\n\r\n/** Distance from point p to segment ab. */\r\nexport function distPointToSegment(p: Point, a: Point, b: Point): number {\r\n const abx = b.x - a.x;\r\n const aby = b.y - a.y;\r\n const apx = p.x - a.x;\r\n const apy = p.y - a.y;\r\n const len2 = abx * abx + aby * aby;\r\n let t = len2 === 0 ? 0 : (apx * abx + apy * aby) / len2;\r\n t = Math.max(0, Math.min(1, t));\r\n const cx = a.x + t * abx;\r\n const cy = a.y + t * aby;\r\n return Math.hypot(p.x - cx, p.y - cy);\r\n}\r\n\r\n/** Axis-aligned rectangle corners (clockwise) from origin + size. */\r\nexport function rectCorners(x: number, y: number, w: number, h: number): Point[] {\r\n return [\r\n { x, y },\r\n { x: x + w, y },\r\n { x: x + w, y: y + h },\r\n { x, y: y + h },\r\n ];\r\n}\r\n\r\n/**\r\n * Square-capped offset rectangle for a wall segment: the segment is widened by\r\n * `thickness` and extended by `thickness/2` at each end so orthogonal corners\r\n * fill cleanly when adjacent segments are drawn.\r\n */\r\nexport function segmentRectangle(a: Point, b: Point, thickness: number): Point[] {\r\n const d = unit(sub(b, a));\r\n const n = normal(d);\r\n const half = thickness / 2;\r\n const a2 = add(a, mul(d, -half));\r\n const b2 = add(b, mul(d, half));\r\n return [\r\n add(a2, mul(n, half)),\r\n add(b2, mul(n, half)),\r\n add(b2, mul(n, -half)),\r\n add(a2, mul(n, -half)),\r\n ];\r\n}\r\n\r\nexport interface WallSegment {\r\n a: Point;\r\n b: Point;\r\n thickness: number;\r\n category: string;\r\n}\r\n\r\n/** Minimal wall shape needed by the segment/hosting helpers (a resolved wall). */\r\nexport interface WallLike {\r\n id: string;\r\n category: string;\r\n thickness: number;\r\n points: Point[];\r\n closed: boolean;\r\n}\r\n\r\n/** Flatten a single wall into its individual segments. */\r\nexport function segmentsOfWall(w: WallLike): WallSegment[] {\r\n const segs: WallSegment[] = [];\r\n for (let k = 0; k < w.points.length - 1; k++) {\r\n segs.push({ a: w.points[k], b: w.points[k + 1], thickness: w.thickness, category: w.category });\r\n }\r\n if (w.closed && w.points.length > 2) {\r\n segs.push({ a: w.points[w.points.length - 1], b: w.points[0], thickness: w.thickness, category: w.category });\r\n }\r\n return segs;\r\n}\r\n\r\n/** The wall segment hosting an opening point (nearest), filtered by ref if given. */\r\nexport function hostSegmentForWalls(walls: WallLike[], at: Point, ref?: string): WallSegment | null {\r\n const candidates = ref ? walls.filter((w) => w.id === ref || w.category === ref) : walls;\r\n let best: WallSegment | null = null;\r\n let bestDist = Infinity;\r\n for (const w of candidates) {\r\n for (const s of segmentsOfWall(w)) {\r\n const dist = distPointToSegment(at, s.a, s.b);\r\n if (dist < bestDist) {\r\n bestDist = dist;\r\n best = s;\r\n }\r\n }\r\n }\r\n return best;\r\n}\r\n\r\n/** Whether a point lies within tolerance of some wall (filtered by ref if given). */\r\nexport function isOnSomeWall(walls: WallLike[], at: Point, ref?: string): boolean {\r\n const candidates = ref ? walls.filter((w) => w.id === ref || w.category === ref) : walls;\r\n for (const w of candidates) {\r\n const tol = w.thickness / 2 + Math.max(w.thickness, 1);\r\n for (const s of segmentsOfWall(w)) {\r\n if (distPointToSegment(at, s.a, s.b) <= tol) return true;\r\n }\r\n }\r\n return false;\r\n}\r\n","/** `wall <category> thickness N { (x,y)… [close] }` — poché fill + crisp faces. */\r\n\r\nimport type { ExprPoint, Point, WallNode } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RWall } from \"../ir.js\";\r\nimport { add, mul, normal, segmentRectangle, segmentsOfWall, sub, unit } from \"../geometry.js\";\r\n\r\nexport const wall: ElementDef = {\r\n kind: \"wall\",\r\n keyword: \"wall\",\r\n\r\n parse(ctx: ParseCtx): WallNode {\r\n const kw = ctx.eatKeyword(\"wall\");\r\n const id = ctx.parseIdOpt();\r\n const category = ctx.eatIdent().value;\r\n ctx.eatKeyword(\"thickness\");\r\n const thickness = ctx.parseExpr();\r\n ctx.eat(\"lcurly\");\r\n const points: ExprPoint[] = [];\r\n let closed = false;\r\n while (!ctx.isType(\"rcurly\") && !ctx.isType(\"eof\")) {\r\n if (ctx.isKeyword(\"close\")) {\r\n ctx.next();\r\n closed = true;\r\n break;\r\n }\r\n if (ctx.isType(\"lparen\")) {\r\n points.push(ctx.parsePoint());\r\n continue;\r\n }\r\n ctx.fail(`Expected a point \"(x,y)\" or \"close\" in wall body but found ${describe(ctx)}`);\r\n }\r\n ctx.eat(\"rcurly\");\r\n if (points.length < 2) ctx.fail(\"A wall needs at least two points\", kw);\r\n return { kind: \"wall\", id, category, thickness, points, closed, line: kw.line };\r\n },\r\n\r\n idPrefix: (node) => (node as WallNode).category || \"wall\",\r\n\r\n resolve(node, ctx: ResolveCtx): RWall {\r\n const n = node as WallNode;\r\n const id = ctx.id;\r\n const points = n.points.map((p) => ctx.snapPt(ctx.evalPt(p)));\r\n const tv = ctx.eval(n.thickness);\r\n const thickness = ctx.snap(tv) || tv;\r\n if (thickness <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Wall \"${id}\" must have a positive thickness`, code: \"E_WALL_THICKNESS\", span: n.span });\r\n }\r\n return { kind: \"wall\", id, category: n.category, thickness, points, closed: n.closed, span: n.span };\r\n },\r\n\r\n bounds(resolved): Point[] {\r\n const w = resolved as RWall;\r\n return segmentsOfWall(w).flatMap((s) => segmentRectangle(s.a, s.b, s.thickness));\r\n },\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const w = resolved as RWall;\r\n const { fmt, pt, theme, sizes } = ctx;\r\n const segs = segmentsOfWall(w);\r\n const ops: RenderOp[] = [];\r\n for (const s of segs) {\r\n const poly = segmentRectangle(s.a, s.b, s.thickness);\r\n ops.push({ pass: \"wallFill\", svg: `<polygon points=\"${poly.map(pt).join(\" \")}\" fill=\"url(#poche)\"/>` });\r\n }\r\n for (const s of segs) {\r\n const d = unit(sub(s.b, s.a));\r\n const n = normal(d);\r\n const h = s.thickness / 2;\r\n const fa1 = add(s.a, mul(n, h));\r\n const fb1 = add(s.b, mul(n, h));\r\n const fa2 = add(s.a, mul(n, -h));\r\n const fb2 = add(s.b, mul(n, -h));\r\n ops.push({\r\n pass: \"wallFace\",\r\n svg: `<line x1=\"${fmt(fa1.x)}\" y1=\"${fmt(fa1.y)}\" x2=\"${fmt(fb1.x)}\" y2=\"${fmt(fb1.y)}\" stroke=\"${theme.wallStroke}\" stroke-width=\"${fmt(sizes.wallStroke)}\" stroke-linecap=\"square\"/>`,\r\n });\r\n ops.push({\r\n pass: \"wallFace\",\r\n svg: `<line x1=\"${fmt(fa2.x)}\" y1=\"${fmt(fa2.y)}\" x2=\"${fmt(fb2.x)}\" y2=\"${fmt(fb2.y)}\" stroke=\"${theme.wallStroke}\" stroke-width=\"${fmt(sizes.wallStroke)}\" stroke-linecap=\"square\"/>`,\r\n });\r\n }\r\n return ops;\r\n },\r\n};\r\n\r\nfunction describe(ctx: ParseCtx): string {\r\n const t = ctx.peek();\r\n if (t.type === \"eof\") return \"end of input\";\r\n if (t.type === \"string\") return `string ${JSON.stringify(t.value)}`;\r\n return `\"${t.value}\"`;\r\n}\r\n","/** `room [id=] at (x,y) size WxH [label \"…\"]` — floor fill + label + computed area. */\r\n\r\nimport type { Point, RoomNode } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RRoom } from \"../ir.js\";\r\nimport { rectCorners } from \"../geometry.js\";\r\n\r\nexport const room: ElementDef = {\r\n kind: \"room\",\r\n keyword: \"room\",\r\n\r\n parse(ctx: ParseCtx): RoomNode {\r\n const kw = ctx.eatKeyword(\"room\");\r\n const id = ctx.parseIdOpt();\r\n ctx.eatKeyword(\"at\");\r\n const at = ctx.parsePoint();\r\n ctx.eatKeyword(\"size\");\r\n const size = ctx.parseDimensions();\r\n const node: RoomNode = { kind: \"room\", id, at, size, line: kw.line };\r\n if (ctx.isKeyword(\"label\")) {\r\n ctx.next();\r\n node.label = ctx.eatString();\r\n }\r\n return node;\r\n },\r\n\r\n idPrefix: () => \"room\",\r\n\r\n resolve(node, ctx: ResolveCtx): RRoom {\r\n const n = node as RoomNode;\r\n const id = ctx.id;\r\n const at = ctx.snapPt(ctx.evalPt(n.at));\r\n const size = { w: ctx.snap(ctx.eval(n.size.w)), h: ctx.snap(ctx.eval(n.size.h)) };\r\n if (size.w <= 0 || size.h <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Room \"${id}\" must have a positive size`, code: \"E_ROOM_SIZE\", span: n.span });\r\n }\r\n return { kind: \"room\", id, at, size, label: n.label, span: n.span };\r\n },\r\n\r\n bounds(resolved): Point[] {\r\n const r = resolved as RRoom;\r\n return rectCorners(r.at.x, r.at.y, r.size.w, r.size.h);\r\n },\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const r = resolved as RRoom;\r\n const { fmt, pt, xml, theme, sizes } = ctx;\r\n const ops: RenderOp[] = [];\r\n const c = rectCorners(r.at.x, r.at.y, r.size.w, r.size.h);\r\n ops.push({ pass: \"floor\", svg: `<polygon points=\"${c.map(pt).join(\" \")}\" fill=\"${theme.roomFill}\"/>` });\r\n\r\n const cx = r.at.x + r.size.w / 2;\r\n const cy = r.at.y + r.size.h / 2;\r\n const areaM2 = ((r.size.w / 1000) * (r.size.h / 1000)).toFixed(1);\r\n if (r.label) {\r\n ops.push({\r\n pass: \"labels\",\r\n svg: `<text x=\"${fmt(cx)}\" y=\"${fmt(cy - sizes.roomFont * 0.2)}\" font-size=\"${fmt(sizes.roomFont)}\" fill=\"${theme.roomLabel}\" text-anchor=\"middle\" dominant-baseline=\"central\" font-weight=\"600\">${xml(r.label)}</text>`,\r\n });\r\n }\r\n ops.push({\r\n pass: \"labels\",\r\n svg: `<text x=\"${fmt(cx)}\" y=\"${fmt(cy + (r.label ? sizes.roomFont * 0.9 : 0))}\" font-size=\"${fmt(sizes.areaFont)}\" fill=\"${theme.areaLabel}\" text-anchor=\"middle\" dominant-baseline=\"central\">${areaM2} m²</text>`,\r\n });\r\n return ops;\r\n },\r\n};\r\n","/** `door [id=] at (x,y) width N [wall ref] [hinge l|r] [swing in|out]` — opening + leaf + swing arc. */\r\n\r\nimport type { DoorNode, Point } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RDoor } from \"../ir.js\";\r\nimport { add, mul, normal, sub, unit } from \"../geometry.js\";\r\n\r\nexport const door: ElementDef = {\r\n kind: \"door\",\r\n keyword: \"door\",\r\n\r\n parse(ctx: ParseCtx): DoorNode {\r\n const kw = ctx.eatKeyword(\"door\");\r\n const id = ctx.parseIdOpt();\r\n ctx.eatKeyword(\"at\");\r\n const at = ctx.parsePoint();\r\n ctx.eatKeyword(\"width\");\r\n const width = ctx.parseExpr();\r\n const node: DoorNode = { kind: \"door\", id, at, width, hinge: \"left\", swing: \"in\", line: kw.line };\r\n if (ctx.isKeyword(\"wall\")) {\r\n ctx.next();\r\n node.wall = ctx.eatIdent().value;\r\n }\r\n if (ctx.isKeyword(\"hinge\")) {\r\n ctx.next();\r\n const h = ctx.eatIdent().value;\r\n if (h !== \"left\" && h !== \"right\") ctx.fail(`Expected hinge \"left\" or \"right\" but found \"${h}\"`);\r\n node.hinge = h;\r\n }\r\n if (ctx.isKeyword(\"swing\")) {\r\n ctx.next();\r\n const s = ctx.eatIdent().value;\r\n if (s !== \"in\" && s !== \"out\") ctx.fail(`Expected swing \"in\" or \"out\" but found \"${s}\"`);\r\n node.swing = s;\r\n }\r\n return node;\r\n },\r\n\r\n idPrefix: () => \"door\",\r\n\r\n resolve(node, ctx: ResolveCtx): RDoor {\r\n const n = node as DoorNode;\r\n const id = ctx.id;\r\n const at = ctx.snapPt(ctx.evalPt(n.at));\r\n const wv = ctx.eval(n.width);\r\n const width = ctx.snap(wv) || wv;\r\n if (width <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Door \"${id}\" must have a positive width`, code: \"E_DOOR_WIDTH\", span: n.span });\r\n }\r\n if (ctx.walls.length > 0 && !ctx.isOnWall(at, n.wall)) {\r\n ctx.diag({ severity: \"warning\", message: `Door \"${id}\" does not lie on any wall`, code: \"W_DOOR_OFF_WALL\", span: n.span });\r\n }\r\n return { kind: \"door\", id, at, width, hinge: n.hinge, swing: n.swing, host: ctx.hostSegment(at, n.wall), span: n.span };\r\n },\r\n\r\n bounds: () => [],\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const dr = resolved as RDoor;\r\n const seg = dr.host;\r\n if (!seg) return [];\r\n const { fmt, pt, theme, sizes } = ctx;\r\n const d = unit(sub(seg.b, seg.a));\r\n const n = normal(d);\r\n const h = seg.thickness / 2 + sizes.wallStroke;\r\n const hw = dr.width / 2;\r\n const cover: Point[] = [\r\n add(add(dr.at, mul(d, -hw)), mul(n, h)),\r\n add(add(dr.at, mul(d, hw)), mul(n, h)),\r\n add(add(dr.at, mul(d, hw)), mul(n, -h)),\r\n add(add(dr.at, mul(d, -hw)), mul(n, -h)),\r\n ];\r\n const ops: RenderOp[] = [];\r\n ops.push({ pass: \"doors\", svg: `<polygon points=\"${cover.map(pt).join(\" \")}\" fill=\"${theme.opening}\"/>` });\r\n const hinge = dr.hinge === \"left\" ? add(dr.at, mul(d, -hw)) : add(dr.at, mul(d, hw));\r\n const farJamb = dr.hinge === \"left\" ? add(dr.at, mul(d, hw)) : add(dr.at, mul(d, -hw));\r\n const leafDir = dr.swing === \"in\" ? n : mul(n, -1);\r\n const leafEnd = add(hinge, mul(leafDir, dr.width));\r\n const cross = (leafEnd.x - hinge.x) * (farJamb.y - hinge.y) - (leafEnd.y - hinge.y) * (farJamb.x - hinge.x);\r\n const sweep = cross < 0 ? 1 : 0;\r\n ops.push({\r\n pass: \"doors\",\r\n svg: `<line x1=\"${fmt(hinge.x)}\" y1=\"${fmt(hinge.y)}\" x2=\"${fmt(leafEnd.x)}\" y2=\"${fmt(leafEnd.y)}\" stroke=\"${theme.doorLeaf}\" stroke-width=\"${fmt(sizes.thin * 1.3)}\"/>`,\r\n });\r\n ops.push({\r\n pass: \"doors\",\r\n svg: `<path d=\"M ${pt(leafEnd)} A ${fmt(dr.width)} ${fmt(dr.width)} 0 0 ${sweep} ${pt(farJamb)}\" fill=\"none\" stroke=\"${theme.doorLeaf}\" stroke-width=\"${fmt(sizes.thin)}\" stroke-dasharray=\"${fmt(sizes.thin * 4)} ${fmt(sizes.thin * 3)}\"/>`,\r\n });\r\n return ops;\r\n },\r\n};\r\n","/** `window [id=] at (x,y) width N [wall ref]` — opening + glazing panes. */\r\n\r\nimport type { Point, WindowNode } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RWindow } from \"../ir.js\";\r\nimport { add, mul, normal, sub, unit } from \"../geometry.js\";\r\n\r\nexport const windowEl: ElementDef = {\r\n kind: \"window\",\r\n keyword: \"window\",\r\n\r\n parse(ctx: ParseCtx): WindowNode {\r\n const kw = ctx.eatKeyword(\"window\");\r\n const id = ctx.parseIdOpt();\r\n ctx.eatKeyword(\"at\");\r\n const at = ctx.parsePoint();\r\n ctx.eatKeyword(\"width\");\r\n const width = ctx.parseExpr();\r\n const node: WindowNode = { kind: \"window\", id, at, width, line: kw.line };\r\n if (ctx.isKeyword(\"wall\")) {\r\n ctx.next();\r\n node.wall = ctx.eatIdent().value;\r\n }\r\n return node;\r\n },\r\n\r\n idPrefix: () => \"window\",\r\n\r\n resolve(node, ctx: ResolveCtx): RWindow {\r\n const n = node as WindowNode;\r\n const id = ctx.id;\r\n const at = ctx.snapPt(ctx.evalPt(n.at));\r\n const wv = ctx.eval(n.width);\r\n const width = ctx.snap(wv) || wv;\r\n if (width <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Window \"${id}\" must have a positive width`, code: \"E_WINDOW_WIDTH\", span: n.span });\r\n }\r\n if (ctx.walls.length > 0 && !ctx.isOnWall(at, n.wall)) {\r\n ctx.diag({ severity: \"warning\", message: `Window \"${id}\" does not lie on any wall`, code: \"W_WINDOW_OFF_WALL\", span: n.span });\r\n }\r\n return { kind: \"window\", id, at, width, host: ctx.hostSegment(at, n.wall), span: n.span };\r\n },\r\n\r\n bounds: () => [],\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const wn = resolved as RWindow;\r\n const seg = wn.host;\r\n if (!seg) return [];\r\n const { fmt, pt, theme, sizes } = ctx;\r\n const d = unit(sub(seg.b, seg.a));\r\n const n = normal(d);\r\n const h = seg.thickness / 2;\r\n const he = h + sizes.wallStroke;\r\n const hw = wn.width / 2;\r\n const cover: Point[] = [\r\n add(add(wn.at, mul(d, -hw)), mul(n, he)),\r\n add(add(wn.at, mul(d, hw)), mul(n, he)),\r\n add(add(wn.at, mul(d, hw)), mul(n, -he)),\r\n add(add(wn.at, mul(d, -hw)), mul(n, -he)),\r\n ];\r\n const ops: RenderOp[] = [];\r\n ops.push({ pass: \"windows\", svg: `<polygon points=\"${cover.map(pt).join(\" \")}\" fill=\"${theme.opening}\"/>` });\r\n const jA = add(wn.at, mul(d, -hw));\r\n const jB = add(wn.at, mul(d, hw));\r\n for (const off of [h, -h]) {\r\n const a = add(jA, mul(n, off));\r\n const bb = add(jB, mul(n, off));\r\n ops.push({\r\n pass: \"windows\",\r\n svg: `<line x1=\"${fmt(a.x)}\" y1=\"${fmt(a.y)}\" x2=\"${fmt(bb.x)}\" y2=\"${fmt(bb.y)}\" stroke=\"${theme.wallStroke}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n });\r\n }\r\n ops.push({\r\n pass: \"windows\",\r\n svg: `<line x1=\"${fmt(jA.x)}\" y1=\"${fmt(jA.y)}\" x2=\"${fmt(jB.x)}\" y2=\"${fmt(jB.y)}\" stroke=\"${theme.windowPane}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n });\r\n return ops;\r\n },\r\n};\r\n","/** `furniture <category> [id=] at (x,y) size WxH [label \"…\"]` — outlined fill + label. */\r\n\r\nimport type { FurnitureNode, Point } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RFurniture } from \"../ir.js\";\r\nimport { rectCorners } from \"../geometry.js\";\r\n\r\nexport const furniture: ElementDef = {\r\n kind: \"furniture\",\r\n keyword: \"furniture\",\r\n\r\n parse(ctx: ParseCtx): FurnitureNode {\r\n const kw = ctx.eatKeyword(\"furniture\");\r\n const id = ctx.parseIdOpt();\r\n const category = ctx.eatIdent().value;\r\n ctx.eatKeyword(\"at\");\r\n const at = ctx.parsePoint();\r\n ctx.eatKeyword(\"size\");\r\n const size = ctx.parseDimensions();\r\n const node: FurnitureNode = { kind: \"furniture\", id, category, at, size, line: kw.line };\r\n if (ctx.isKeyword(\"label\")) {\r\n ctx.next();\r\n node.label = ctx.eatString();\r\n }\r\n return node;\r\n },\r\n\r\n idPrefix: (node) => (node as FurnitureNode).category || \"furniture\",\r\n\r\n resolve(node, ctx: ResolveCtx): RFurniture {\r\n const n = node as FurnitureNode;\r\n const id = ctx.id;\r\n const at = ctx.snapPt(ctx.evalPt(n.at));\r\n const size = { w: ctx.snap(ctx.eval(n.size.w)), h: ctx.snap(ctx.eval(n.size.h)) };\r\n if (size.w <= 0 || size.h <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Furniture \"${id}\" must have a positive size`, code: \"E_FURN_SIZE\", span: n.span });\r\n }\r\n return { kind: \"furniture\", id, category: n.category, at, size, label: n.label, span: n.span };\r\n },\r\n\r\n bounds(resolved): Point[] {\r\n const f = resolved as RFurniture;\r\n return rectCorners(f.at.x, f.at.y, f.size.w, f.size.h);\r\n },\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const f = resolved as RFurniture;\r\n const { fmt, pt, xml, theme, sizes } = ctx;\r\n const ops: RenderOp[] = [];\r\n const c = rectCorners(f.at.x, f.at.y, f.size.w, f.size.h);\r\n ops.push({\r\n pass: \"furniture\",\r\n svg: `<polygon points=\"${c.map(pt).join(\" \")}\" fill=\"${theme.furnitureFill}\" stroke=\"${theme.furnitureStroke}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n });\r\n if (f.label) {\r\n const cx = f.at.x + f.size.w / 2;\r\n const cy = f.at.y + f.size.h / 2;\r\n ops.push({\r\n pass: \"furniture\",\r\n svg: `<text x=\"${fmt(cx)}\" y=\"${fmt(cy)}\" font-size=\"${fmt(sizes.furnFont)}\" fill=\"${theme.furnitureLabel}\" text-anchor=\"middle\" dominant-baseline=\"central\">${xml(f.label)}</text>`,\r\n });\r\n }\r\n return ops;\r\n },\r\n};\r\n","/** `dim (x,y)->(x,y) [offset N] [text \"…\"]` — dimension line with ticks + length. */\r\n\r\nimport type { DimNode } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RDim } from \"../ir.js\";\r\nimport { add, length, mul, normal, sub, unit } from \"../geometry.js\";\r\n\r\nexport const dim: ElementDef = {\r\n kind: \"dim\",\r\n keyword: \"dim\",\r\n\r\n parse(ctx: ParseCtx): DimNode {\r\n const kw = ctx.eatKeyword(\"dim\");\r\n const from = ctx.parsePoint();\r\n ctx.eat(\"arrow\");\r\n const to = ctx.parsePoint();\r\n const node: DimNode = { kind: \"dim\", id: \"\", from, to, offset: { t: \"num\", value: 300 }, line: kw.line };\r\n if (ctx.isKeyword(\"offset\")) {\r\n ctx.next();\r\n node.offset = ctx.parseExpr();\r\n }\r\n if (ctx.isKeyword(\"text\")) {\r\n ctx.next();\r\n node.text = ctx.eatString();\r\n }\r\n return node;\r\n },\r\n\r\n idPrefix: () => \"dim\",\r\n\r\n resolve(node, ctx: ResolveCtx): RDim {\r\n const n = node as DimNode;\r\n return {\r\n kind: \"dim\",\r\n id: ctx.id,\r\n from: ctx.snapPt(ctx.evalPt(n.from)),\r\n to: ctx.snapPt(ctx.evalPt(n.to)),\r\n offset: ctx.eval(n.offset),\r\n text: n.text,\r\n span: n.span,\r\n };\r\n },\r\n\r\n bounds(resolved) {\r\n const dm = resolved as RDim;\r\n return [dm.from, dm.to];\r\n },\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const dm = resolved as RDim;\r\n const { fmt, xml, theme, sizes } = ctx;\r\n const dir = unit(sub(dm.to, dm.from));\r\n const n = normal(dir);\r\n const off = mul(n, dm.offset);\r\n const p1 = add(dm.from, off);\r\n const p2 = add(dm.to, off);\r\n const tick = sizes.refDim * 0.012;\r\n const ops: RenderOp[] = [];\r\n ops.push({\r\n pass: \"dims\",\r\n svg: `<line x1=\"${fmt(dm.from.x)}\" y1=\"${fmt(dm.from.y)}\" x2=\"${fmt(p1.x)}\" y2=\"${fmt(p1.y)}\" stroke=\"${theme.dim}\" stroke-width=\"${fmt(sizes.thin * 0.7)}\"/>`,\r\n });\r\n ops.push({\r\n pass: \"dims\",\r\n svg: `<line x1=\"${fmt(dm.to.x)}\" y1=\"${fmt(dm.to.y)}\" x2=\"${fmt(p2.x)}\" y2=\"${fmt(p2.y)}\" stroke=\"${theme.dim}\" stroke-width=\"${fmt(sizes.thin * 0.7)}\"/>`,\r\n });\r\n ops.push({\r\n pass: \"dims\",\r\n svg: `<line x1=\"${fmt(p1.x)}\" y1=\"${fmt(p1.y)}\" x2=\"${fmt(p2.x)}\" y2=\"${fmt(p2.y)}\" stroke=\"${theme.dim}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n });\r\n for (const p of [p1, p2]) {\r\n const t1 = add(p, mul(unit({ x: dir.x + n.x, y: dir.y + n.y }), tick));\r\n const t2 = add(p, mul(unit({ x: dir.x + n.x, y: dir.y + n.y }), -tick));\r\n ops.push({\r\n pass: \"dims\",\r\n svg: `<line x1=\"${fmt(t1.x)}\" y1=\"${fmt(t1.y)}\" x2=\"${fmt(t2.x)}\" y2=\"${fmt(t2.y)}\" stroke=\"${theme.dim}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n });\r\n }\r\n const mid = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };\r\n const tp = add(mid, mul(n, sizes.dimFont * 0.7));\r\n let angle = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\r\n if (angle > 90) angle -= 180;\r\n if (angle < -90) angle += 180;\r\n const label = dm.text ?? String(Math.round(length(sub(dm.to, dm.from))));\r\n ops.push({\r\n pass: \"dims\",\r\n svg: `<text x=\"${fmt(tp.x)}\" y=\"${fmt(tp.y)}\" font-size=\"${fmt(sizes.dimFont)}\" fill=\"${theme.dim}\" text-anchor=\"middle\" dominant-baseline=\"central\" transform=\"rotate(${fmt(angle)} ${fmt(tp.x)} ${fmt(tp.y)})\">${xml(label)}</text>`,\r\n });\r\n return ops;\r\n },\r\n};\r\n","/**\r\n * `column [id=] at (x,y) size WxH` — a solid structural column.\r\n *\r\n * This module is the extensibility proof for the v0.3 registry: a brand-new\r\n * element type added as ONE file + one `register` line in `index.ts`, with no\r\n * edits to the parser, resolver, or renderer cores.\r\n */\r\n\r\nimport type { ColumnNode, Point } from \"../ast.js\";\r\nimport type { ElementDef, ParseCtx, RenderCtx, RenderOp, ResolveCtx } from \"../registry.js\";\r\nimport type { RColumn } from \"../ir.js\";\r\nimport { rectCorners } from \"../geometry.js\";\r\n\r\nexport const column: ElementDef = {\r\n kind: \"column\",\r\n keyword: \"column\",\r\n\r\n parse(ctx: ParseCtx): ColumnNode {\r\n const kw = ctx.eatKeyword(\"column\");\r\n const id = ctx.parseIdOpt();\r\n ctx.eatKeyword(\"at\");\r\n const at = ctx.parsePoint();\r\n ctx.eatKeyword(\"size\");\r\n const size = ctx.parseDimensions();\r\n return { kind: \"column\", id, at, size, line: kw.line };\r\n },\r\n\r\n idPrefix: () => \"column\",\r\n\r\n resolve(node, ctx: ResolveCtx): RColumn {\r\n const n = node as ColumnNode;\r\n const id = ctx.id;\r\n const at = ctx.snapPt(ctx.evalPt(n.at));\r\n const size = { w: ctx.snap(ctx.eval(n.size.w)), h: ctx.snap(ctx.eval(n.size.h)) };\r\n if (size.w <= 0 || size.h <= 0) {\r\n ctx.diag({ severity: \"error\", message: `Column \"${id}\" must have a positive size`, code: \"E_COLUMN_SIZE\", span: n.span });\r\n }\r\n return { kind: \"column\", id, at, size, span: n.span };\r\n },\r\n\r\n bounds(resolved): Point[] {\r\n const c = resolved as RColumn;\r\n return rectCorners(c.at.x, c.at.y, c.size.w, c.size.h);\r\n },\r\n\r\n render(resolved, ctx: RenderCtx): RenderOp[] {\r\n const c = resolved as RColumn;\r\n const { fmt, pt, theme, sizes } = ctx;\r\n const pts = rectCorners(c.at.x, c.at.y, c.size.w, c.size.h);\r\n return [\r\n {\r\n pass: \"furniture\",\r\n svg: `<polygon points=\"${pts.map(pt).join(\" \")}\" fill=\"${theme.column}\" stroke=\"${theme.wallStroke}\" stroke-width=\"${fmt(sizes.thin)}\"/>`,\r\n },\r\n ];\r\n },\r\n};\r\n","/**\r\n * Element registry assembly. Registration order is canonical: it drives id\r\n * assignment and resolve ordering (walls first, so openings can host against\r\n * them). To add an element: write one module and add one `register()` line.\r\n */\r\n\r\nimport type { ElementDef } from \"../registry.js\";\r\nimport { wall } from \"./wall.js\";\r\nimport { room } from \"./room.js\";\r\nimport { door } from \"./door.js\";\r\nimport { windowEl } from \"./window.js\";\r\nimport { furniture } from \"./furniture.js\";\r\nimport { dim } from \"./dim.js\";\r\nimport { column } from \"./column.js\";\r\n\r\n/** Defs in canonical (registration) order. */\r\nexport const registryOrder: ElementDef[] = [];\r\n/** Lookup by keyword. */\r\nexport const registry = new Map<string, ElementDef>();\r\n\r\nfunction register(def: ElementDef): void {\r\n registry.set(def.keyword, def);\r\n registryOrder.push(def);\r\n}\r\n\r\nregister(wall);\r\nregister(room);\r\nregister(door);\r\nregister(windowEl);\r\nregister(furniture);\r\nregister(dim);\r\nregister(column);\r\n","/** Recursive-descent parser: tokens -> PlanNode. Registry-driven element dispatch. */\r\n\r\nimport type { Token } from \"./lexer.js\";\r\nimport { lex } from \"./lexer.js\";\r\nimport type { Diagnostic, Span } from \"./diagnostics.js\";\r\nimport type {\r\n ComponentDef,\r\n ExprPoint,\r\n InstanceNode,\r\n LetNode,\r\n NorthDir,\r\n PlanNode,\r\n Statement,\r\n TitleNode,\r\n} from \"./ast.js\";\r\nimport type { Expr } from \"./expr.js\";\r\nimport { parseExpr as parseExprPratt } from \"./expr.js\";\r\nimport type { ParseCtx } from \"./registry.js\";\r\nimport { registry } from \"./elements/index.js\";\r\n\r\nexport interface ParseOutcome {\r\n plan?: PlanNode;\r\n diagnostics: Diagnostic[];\r\n}\r\n\r\n/** Plan-level settings + binding/definition keywords (not registry elements). */\r\nconst SETTINGS = [\"units\", \"grid\", \"scale\", \"north\", \"title\", \"let\", \"component\"];\r\n/** Keywords that begin a plan-body statement; recovery resynchronizes to one. */\r\nconst STATEMENT_STARTS = new Set<string>([...SETTINGS, ...registry.keys()]);\r\n\r\n/** Thrown internally by `eat*` helpers; always caught within the parser. */\r\nclass ParseError extends Error {\r\n constructor(public override message: string, public span: Span) {\r\n super(message);\r\n }\r\n}\r\n\r\nexport function parse(src: string): ParseOutcome {\r\n const { tokens, errors: lexErrors } = lex(src);\r\n const lexDiags: Diagnostic[] = lexErrors.map((e) => ({\r\n severity: \"error\" as const,\r\n message: e.message,\r\n span: e.span,\r\n }));\r\n\r\n const p = new Parser(tokens);\r\n let plan: PlanNode | undefined;\r\n try {\r\n plan = p.parsePlan();\r\n } catch (e) {\r\n // Only a malformed plan *header* escapes parsePlan's per-statement recovery.\r\n if (e instanceof ParseError) {\r\n p.diagnostics.push({ severity: \"error\", message: e.message, span: e.span });\r\n } else {\r\n throw e;\r\n }\r\n }\r\n return { plan, diagnostics: [...lexDiags, ...p.diagnostics] };\r\n}\r\n\r\nclass Parser {\r\n private pos = 0;\r\n public diagnostics: Diagnostic[] = [];\r\n /** Facade passed to element parse functions (see registry.ts). */\r\n private readonly ctx: ParseCtx;\r\n\r\n constructor(private toks: Token[]) {\r\n this.ctx = {\r\n peek: (o) => this.peek(o),\r\n next: () => this.next(),\r\n eat: (type) => this.eat(type),\r\n eatKeyword: (kw) => this.eatKeyword(kw),\r\n eatIdent: () => this.eatIdent(),\r\n eatNumber: () => this.eatNumber(),\r\n eatString: () => this.eatString(),\r\n isKeyword: (kw, o) => this.isKeyword(kw, o),\r\n isType: (type) => this.isType(type),\r\n parsePoint: () => this.parsePoint(),\r\n parseExpr: () => parseExprPratt(this.ctx),\r\n parseDimensions: () => this.parseDimensions(),\r\n parseIdOpt: () => this.parseIdOpt(),\r\n fail: (msg, t) => this.fail(msg, t),\r\n };\r\n }\r\n\r\n private peek(o = 0): Token {\r\n return this.toks[Math.min(this.pos + o, this.toks.length - 1)];\r\n }\r\n private next(): Token {\r\n return this.toks[Math.min(this.pos++, this.toks.length - 1)];\r\n }\r\n private fail(msg: string, t = this.peek()): never {\r\n throw new ParseError(msg, { start: t.start, end: t.end });\r\n }\r\n\r\n /** Span from a start offset to the end of the last consumed token. */\r\n private spanFrom(start: number): Span {\r\n const last = this.toks[Math.max(0, Math.min(this.pos - 1, this.toks.length - 1))];\r\n return { start, end: last.end };\r\n }\r\n\r\n /** Recover after a statement error: skip to the next statement start or block end. */\r\n private synchronize(): void {\r\n // Always make progress so a hard-stuck token can't loop forever.\r\n if (!this.isType(\"rcurly\") && !this.isType(\"eof\")) this.next();\r\n while (!this.isType(\"rcurly\") && !this.isType(\"eof\")) {\r\n const t = this.peek();\r\n if (t.type === \"ident\" && STATEMENT_STARTS.has(t.value)) return;\r\n this.next();\r\n }\r\n }\r\n\r\n private isKeyword(kw: string, o = 0): boolean {\r\n const t = this.peek(o);\r\n return t.type === \"ident\" && t.value === kw;\r\n }\r\n private eatKeyword(kw: string): Token {\r\n const t = this.peek();\r\n if (t.type !== \"ident\" || t.value !== kw) this.fail(`Expected \"${kw}\" but found ${describe(t)}`);\r\n return this.next();\r\n }\r\n private eat(type: Token[\"type\"]): Token {\r\n const t = this.peek();\r\n if (t.type !== type) this.fail(`Expected ${type} but found ${describe(t)}`);\r\n return this.next();\r\n }\r\n private eatIdent(): Token {\r\n return this.eat(\"ident\");\r\n }\r\n private eatNumber(): number {\r\n const t = this.eat(\"number\");\r\n return t.num!;\r\n }\r\n private eatString(): string {\r\n return this.eat(\"string\").value;\r\n }\r\n\r\n parsePlan(): PlanNode {\r\n this.eatKeyword(\"plan\");\r\n const name = this.eatString();\r\n this.eat(\"lcurly\");\r\n\r\n const plan: PlanNode = {\r\n name,\r\n units: \"mm\",\r\n grid: 0,\r\n north: \"up\",\r\n components: new Map(),\r\n body: [],\r\n };\r\n\r\n while (!this.isType(\"rcurly\") && !this.isType(\"eof\")) {\r\n const t = this.peek();\r\n const start = t.start;\r\n try {\r\n if (t.type !== \"ident\") this.fail(`Expected a statement but found ${describe(t)}`);\r\n const def = registry.get(t.value);\r\n if (def) {\r\n const node = def.parse(this.ctx);\r\n node.span = this.spanFrom(start);\r\n plan.body.push(node);\r\n continue;\r\n }\r\n // A defined component name followed by `(` is an instantiation.\r\n if (plan.components.has(t.value) && this.peek(1).type === \"lparen\") {\r\n const node = this.parseInstance();\r\n node.span = this.spanFrom(start);\r\n plan.body.push(node);\r\n continue;\r\n }\r\n switch (t.value) {\r\n case \"units\": {\r\n this.next();\r\n const u = this.eatIdent().value;\r\n if (u !== \"mm\") this.fail(`Unsupported units \"${u}\" (only \"mm\" is supported)`, t);\r\n plan.units = \"mm\";\r\n break;\r\n }\r\n case \"grid\":\r\n this.next();\r\n plan.grid = this.eatNumber();\r\n break;\r\n case \"scale\": {\r\n this.next();\r\n const a = this.eatNumber();\r\n this.eat(\"colon\");\r\n const b = this.eatNumber();\r\n plan.scale = `${a}:${b}`;\r\n break;\r\n }\r\n case \"north\":\r\n this.next();\r\n plan.north = this.parseNorth();\r\n break;\r\n case \"title\": {\r\n const n = this.parseTitle();\r\n n.span = this.spanFrom(start);\r\n plan.title = n;\r\n break;\r\n }\r\n case \"let\": {\r\n const n = this.parseLet();\r\n n.span = this.spanFrom(start);\r\n plan.body.push(n);\r\n break;\r\n }\r\n case \"component\": {\r\n const def = this.parseComponent(plan.components);\r\n def.span = this.spanFrom(start);\r\n if (plan.components.has(def.name)) {\r\n this.fail(`Component \"${def.name}\" is already defined`, t);\r\n }\r\n plan.components.set(def.name, def);\r\n break;\r\n }\r\n default:\r\n this.fail(`Unknown statement \"${t.value}\"`, t);\r\n }\r\n } catch (e) {\r\n if (e instanceof ParseError) {\r\n this.diagnostics.push({ severity: \"error\", message: e.message, span: e.span });\r\n this.synchronize();\r\n } else {\r\n throw e;\r\n }\r\n }\r\n }\r\n // A missing closing brace is reported but the partial plan is still returned.\r\n try {\r\n this.eat(\"rcurly\");\r\n } catch (e) {\r\n if (e instanceof ParseError) {\r\n this.diagnostics.push({ severity: \"error\", message: e.message, span: e.span });\r\n } else {\r\n throw e;\r\n }\r\n }\r\n return plan;\r\n }\r\n\r\n private isType(type: Token[\"type\"]): boolean {\r\n return this.peek().type === type;\r\n }\r\n\r\n /** Optional `id=<ident>` prefix; returns \"\" when absent. */\r\n private parseIdOpt(): string {\r\n if (this.isKeyword(\"id\")) {\r\n this.next();\r\n this.eat(\"equals\");\r\n return this.eatIdent().value;\r\n }\r\n return \"\";\r\n }\r\n\r\n private parseNorth(): NorthDir {\r\n const t = this.peek();\r\n if (t.type === \"number\") {\r\n this.next();\r\n return { deg: t.num! };\r\n }\r\n if (t.type === \"ident\" && [\"up\", \"down\", \"left\", \"right\"].includes(t.value)) {\r\n this.next();\r\n return t.value as NorthDir;\r\n }\r\n this.fail(`Expected a north direction (up|down|left|right|<degrees>) but found ${describe(t)}`);\r\n }\r\n\r\n private parsePoint(): ExprPoint {\r\n this.eat(\"lparen\");\r\n const x = parseExprPratt(this.ctx);\r\n this.eat(\"comma\");\r\n const y = parseExprPratt(this.ctx);\r\n this.eat(\"rparen\");\r\n return { x, y };\r\n }\r\n\r\n /** A size: either a `WxH` literal dimension token or `<expr> x <expr>`. */\r\n private parseDimensions(): { w: Expr; h: Expr } {\r\n if (this.isType(\"dimension\")) {\r\n const d = this.eat(\"dimension\");\r\n return { w: { t: \"num\", value: d.num! }, h: { t: \"num\", value: d.num2! } };\r\n }\r\n const w = parseExprPratt(this.ctx);\r\n if (this.isKeyword(\"x\")) this.next();\r\n else this.fail(`Expected \"x\" between width and height but found ${describe(this.peek())}`);\r\n const h = parseExprPratt(this.ctx);\r\n return { w, h };\r\n }\r\n\r\n private parseTitle(): TitleNode {\r\n const kw = this.eatKeyword(\"title\");\r\n this.eat(\"lcurly\");\r\n const node: TitleNode = { line: kw.line };\r\n while (!this.isType(\"rcurly\") && !this.isType(\"eof\")) {\r\n const t = this.peek();\r\n if (t.type !== \"ident\") this.fail(`Expected a title field but found ${describe(t)}`);\r\n switch (t.value) {\r\n case \"project\":\r\n this.next();\r\n node.project = this.eatString();\r\n break;\r\n case \"drawn_by\":\r\n this.next();\r\n node.drawnBy = this.eatString();\r\n break;\r\n case \"date\":\r\n this.next();\r\n node.date = this.eatString();\r\n break;\r\n default:\r\n this.fail(`Unknown title field \"${t.value}\"`, t);\r\n }\r\n }\r\n this.eat(\"rcurly\");\r\n return node;\r\n }\r\n\r\n private parseLet(): LetNode {\r\n const kw = this.eatKeyword(\"let\");\r\n const name = this.eatIdent().value;\r\n this.eat(\"equals\");\r\n const value = parseExprPratt(this.ctx);\r\n return { kind: \"let\", id: \"\", name, value, line: kw.line };\r\n }\r\n\r\n private parseInstance(): InstanceNode {\r\n const nameTok = this.eatIdent();\r\n this.eat(\"lparen\");\r\n const args: Expr[] = [];\r\n while (!this.isType(\"rparen\") && !this.isType(\"eof\")) {\r\n args.push(parseExprPratt(this.ctx));\r\n if (this.isType(\"comma\")) this.next();\r\n else break;\r\n }\r\n this.eat(\"rparen\");\r\n return { kind: \"instance\", id: \"\", name: nameTok.value, args, line: nameTok.line };\r\n }\r\n\r\n /** `component NAME(p1, p2, …) { <statements> }`. */\r\n private parseComponent(components: Map<string, ComponentDef>): ComponentDef {\r\n const kw = this.eatKeyword(\"component\");\r\n const name = this.eatIdent().value;\r\n this.eat(\"lparen\");\r\n const params: string[] = [];\r\n while (!this.isType(\"rparen\") && !this.isType(\"eof\")) {\r\n params.push(this.eatIdent().value);\r\n if (this.isType(\"comma\")) this.next();\r\n else break;\r\n }\r\n this.eat(\"rparen\");\r\n this.eat(\"lcurly\");\r\n const body: Statement[] = [];\r\n while (!this.isType(\"rcurly\") && !this.isType(\"eof\")) {\r\n const t = this.peek();\r\n const start = t.start;\r\n const def = registry.get(t.value);\r\n if (def) {\r\n const node = def.parse(this.ctx);\r\n node.span = this.spanFrom(start);\r\n body.push(node);\r\n continue;\r\n }\r\n if (t.value === \"let\") {\r\n const n = this.parseLet();\r\n n.span = this.spanFrom(start);\r\n body.push(n);\r\n continue;\r\n }\r\n // A previously-defined component (or this one, recursively) may be called.\r\n if ((components.has(t.value) || t.value === name) && this.peek(1).type === \"lparen\") {\r\n const n = this.parseInstance();\r\n n.span = this.spanFrom(start);\r\n body.push(n);\r\n continue;\r\n }\r\n this.fail(`Expected an element, \"let\", or component call in component body but found ${describe(t)}`, t);\r\n }\r\n this.eat(\"rcurly\");\r\n return { name, params, body, line: kw.line };\r\n }\r\n}\r\n\r\nfunction describe(t: Token): string {\r\n if (t.type === \"eof\") return \"end of input\";\r\n if (t.type === \"string\") return `string ${JSON.stringify(t.value)}`;\r\n return `\"${t.value}\"`;\r\n}\r\n","/**\r\n * Intermediate representation + `resolve(ast)`.\r\n *\r\n * `resolve` is the single place semantics live: it grid-snaps coordinates,\r\n * assigns ids, hosts openings, and runs semantic checks — producing a NEW\r\n * immutable IR (the input AST is never mutated). `render` consumes IR only.\r\n */\r\n\r\nimport type {\r\n AstElement,\r\n ComponentDef,\r\n ElementKind,\r\n ExprPoint,\r\n NorthDir,\r\n PlanNode,\r\n Point,\r\n Statement,\r\n TitleNode,\r\n} from \"./ast.js\";\r\nimport type { Diagnostic, Span } from \"./diagnostics.js\";\r\nimport type { Env, Expr } from \"./expr.js\";\r\nimport { closest, evalExpr } from \"./expr.js\";\r\nimport type { ResolveCtx } from \"./registry.js\";\r\nimport type { WallSegment } from \"./geometry.js\";\r\nimport { hostSegmentForWalls, isOnSomeWall } from \"./geometry.js\";\r\nimport { registryOrder } from \"./elements/index.js\";\r\n\r\nexport interface RBase {\r\n kind: ElementKind;\r\n id: string;\r\n span?: Span;\r\n}\r\n\r\nexport interface RWall extends RBase {\r\n kind: \"wall\";\r\n category: string;\r\n thickness: number;\r\n points: Point[];\r\n closed: boolean;\r\n}\r\nexport interface RRoom extends RBase {\r\n kind: \"room\";\r\n at: Point;\r\n size: { w: number; h: number };\r\n label?: string;\r\n}\r\nexport interface RDoor extends RBase {\r\n kind: \"door\";\r\n at: Point;\r\n width: number;\r\n hinge: \"left\" | \"right\";\r\n swing: \"in\" | \"out\";\r\n host: WallSegment | null;\r\n}\r\nexport interface RWindow extends RBase {\r\n kind: \"window\";\r\n at: Point;\r\n width: number;\r\n host: WallSegment | null;\r\n}\r\nexport interface RFurniture extends RBase {\r\n kind: \"furniture\";\r\n category: string;\r\n at: Point;\r\n size: { w: number; h: number };\r\n label?: string;\r\n}\r\nexport interface RDim extends RBase {\r\n kind: \"dim\";\r\n from: Point;\r\n to: Point;\r\n offset: number;\r\n text?: string;\r\n}\r\nexport interface RColumn extends RBase {\r\n kind: \"column\";\r\n at: Point;\r\n size: { w: number; h: number };\r\n}\r\n\r\nexport type ResolvedElement = RWall | RRoom | RDoor | RWindow | RFurniture | RDim | RColumn;\r\n\r\nexport interface ResolvedPlan {\r\n name: string;\r\n units: \"mm\";\r\n grid: number;\r\n scale?: string;\r\n north: NorthDir;\r\n title?: TitleNode;\r\n /** Resolved elements, in source order (for rendering). */\r\n elements: ResolvedElement[];\r\n /** Resolved walls (for bounds/hosting), in source order. */\r\n walls: RWall[];\r\n}\r\n\r\n/** Max component-instantiation nesting depth before bailing out. */\r\nconst MAX_DEPTH = 64;\r\n\r\n/** An element flattened out of the body, paired with the env its exprs use. */\r\ninterface Entry {\r\n node: AstElement;\r\n env: Env;\r\n id: string;\r\n resolved?: ResolvedElement;\r\n}\r\n\r\n/**\r\n * Expand a statement list into a flat element stream: evaluate `let`s into the\r\n * scope env (source order, no forward refs), and inline component instances.\r\n *\r\n * Scoping is lexical with the plan as the global scope: a component body sees\r\n * the plan-level `let`s (`global`) plus its own params and local `let`s, but\r\n * NOT the caller's locals. `env` is this scope's env; at the top level it *is*\r\n * `global`, so top-level `let`s populate the global scope.\r\n */\r\nfunction expandScope(\r\n body: Statement[],\r\n env: Env,\r\n defined: Set<string>,\r\n global: Env,\r\n components: Map<string, ComponentDef>,\r\n diagnostics: Diagnostic[],\r\n depth: number,\r\n): Entry[] {\r\n const diag = (d: Diagnostic) => diagnostics.push(d);\r\n const out: Entry[] = [];\r\n\r\n for (const stmt of body) {\r\n if (stmt.kind === \"let\") {\r\n if (defined.has(stmt.name)) {\r\n diag({ severity: \"error\", message: `\"${stmt.name}\" is already defined in this scope`, code: \"E_REDEF\", span: stmt.span });\r\n continue;\r\n }\r\n env.set(stmt.name, evalExpr(stmt.value, env, diag));\r\n defined.add(stmt.name);\r\n } else if (stmt.kind === \"instance\") {\r\n const comp = components.get(stmt.name);\r\n if (!comp) {\r\n const hint = closest(stmt.name, [...components.keys()]);\r\n diag({ severity: \"error\", message: `Unknown component \"${stmt.name}\"`, code: \"E_UNKNOWN_COMPONENT\", span: stmt.span, hints: hint ? [`did you mean \"${hint}\"?`] : undefined });\r\n continue;\r\n }\r\n if (depth >= MAX_DEPTH) {\r\n diag({ severity: \"error\", message: `Component recursion too deep (limit ${MAX_DEPTH}) instantiating \"${stmt.name}\"`, code: \"E_RECURSION\", span: stmt.span });\r\n continue;\r\n }\r\n if (stmt.args.length !== comp.params.length) {\r\n diag({ severity: \"error\", message: `Component \"${stmt.name}\" expects ${comp.params.length} argument(s) but got ${stmt.args.length}`, code: \"E_ARGCOUNT\", span: stmt.span });\r\n }\r\n const argVals = comp.params.map((_, i) => (stmt.args[i] !== undefined ? evalExpr(stmt.args[i], env, diag) : 0));\r\n // Component scope = plan global + params; its lets are local.\r\n const childEnv: Env = new Map(global);\r\n const childDefined = new Set<string>();\r\n comp.params.forEach((p, i) => {\r\n childEnv.set(p, argVals[i]);\r\n childDefined.add(p);\r\n });\r\n out.push(...expandScope(comp.body, childEnv, childDefined, global, components, diagnostics, depth + 1));\r\n } else {\r\n out.push({ node: stmt, env: new Map(env), id: \"\" });\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport function resolve(ast: PlanNode): { ir: ResolvedPlan; diagnostics: Diagnostic[] } {\r\n const diagnostics: Diagnostic[] = [];\r\n const g = ast.grid;\r\n const snap = (v: number) => (g > 0 ? Math.round(v / g) * g : v);\r\n const snapPt = (p: Point): Point => ({ x: snap(p.x), y: snap(p.y) });\r\n\r\n // 0. Expand body (lets + component instantiation) into a flat element stream.\r\n // At the top level the scope env IS the global env (plan-level `let`s).\r\n const globalEnv: Env = new Map();\r\n const entries = expandScope(ast.body, globalEnv, new Set(), globalEnv, ast.components, diagnostics, 0);\r\n\r\n // 1. Assign ids in registry (canonical) order. The flat stream is numbered\r\n // globally per kind, so auto-ids stay unique across component instances.\r\n const seen = new Set<string>();\r\n const assignId = (provided: string, prefix: string, idx: number, span?: Span): string => {\r\n if (provided) {\r\n if (seen.has(provided)) {\r\n diagnostics.push({ severity: \"error\", message: `Duplicate id \"${provided}\"`, code: \"E_DUP_ID\", span });\r\n }\r\n seen.add(provided);\r\n return provided;\r\n }\r\n let auto = `${prefix}_${idx}`;\r\n while (seen.has(auto)) auto = `${auto}_`;\r\n seen.add(auto);\r\n return auto;\r\n };\r\n for (const def of registryOrder) {\r\n let idx = 0;\r\n for (const e of entries) {\r\n if (e.node.kind !== def.kind) continue;\r\n idx++;\r\n e.id = assignId(e.node.id, def.idPrefix(e.node), idx, e.node.span);\r\n }\r\n }\r\n\r\n // 2. Resolve in registry order (walls first → openings can host against them).\r\n // `activeEnv`/`activeId` are swapped per entry so each element evaluates\r\n // its expressions against the env captured during expansion.\r\n const walls: RWall[] = [];\r\n let activeEnv: Env = new Map();\r\n const evalNum = (e: Expr): number => evalExpr(e, activeEnv, (d) => diagnostics.push(d));\r\n const evalPt = (p: ExprPoint): Point => ({ x: evalNum(p.x), y: evalNum(p.y) });\r\n const ctx: ResolveCtx = {\r\n grid: g,\r\n snap,\r\n snapPt,\r\n eval: evalNum,\r\n evalPt,\r\n id: \"\",\r\n walls,\r\n hostSegment: (at, ref) => hostSegmentForWalls(walls, at, ref),\r\n isOnWall: (at, ref) => isOnSomeWall(walls, at, ref),\r\n diag: (d) => diagnostics.push(d),\r\n };\r\n for (const def of registryOrder) {\r\n for (const e of entries) {\r\n if (e.node.kind !== def.kind) continue;\r\n activeEnv = e.env;\r\n ctx.id = e.id;\r\n const r = def.resolve(e.node, ctx);\r\n e.resolved = r;\r\n if (r.kind === \"wall\") walls.push(r);\r\n }\r\n }\r\n\r\n // 3. IR element list in source order (for rendering).\r\n const elements = entries.map((e) => e.resolved!);\r\n\r\n // 4. Cross-element checks.\r\n const drawable = elements.some(\r\n (e) => e.kind === \"wall\" || e.kind === \"room\" || e.kind === \"furniture\" || e.kind === \"column\",\r\n );\r\n if (!drawable) {\r\n diagnostics.push({\r\n severity: \"warning\",\r\n message: \"Plan has no walls, rooms, or furniture — nothing to draw\",\r\n code: \"W_EMPTY_PLAN\",\r\n });\r\n }\r\n const rooms = elements.filter((e): e is RRoom => e.kind === \"room\");\r\n for (let a = 0; a < rooms.length; a++) {\r\n for (let b = a + 1; b < rooms.length; b++) {\r\n const r1 = rooms[a];\r\n const r2 = rooms[b];\r\n const ox = Math.max(0, Math.min(r1.at.x + r1.size.w, r2.at.x + r2.size.w) - Math.max(r1.at.x, r2.at.x));\r\n const oy = Math.max(0, Math.min(r1.at.y + r1.size.h, r2.at.y + r2.size.h) - Math.max(r1.at.y, r2.at.y));\r\n if (ox > 1 && oy > 1) {\r\n diagnostics.push({\r\n severity: \"warning\",\r\n message: `Rooms \"${r1.id}\" and \"${r2.id}\" overlap`,\r\n code: \"W_ROOM_OVERLAP\",\r\n span: r2.span,\r\n });\r\n }\r\n }\r\n }\r\n\r\n const ir: ResolvedPlan = {\r\n name: ast.name,\r\n units: ast.units,\r\n grid: ast.grid,\r\n scale: ast.scale,\r\n north: ast.north,\r\n title: ast.title,\r\n elements,\r\n walls,\r\n };\r\n return { ir, diagnostics };\r\n}\r\n","/**\r\n * Element registry: the single extension point. Each element type is one module\r\n * exporting an {@link ElementDef}; parse/resolve/render iterate the registry\r\n * rather than a hard-coded switch. Adding an element = one new module + one\r\n * `register` line in `elements/index.ts`.\r\n */\r\n\r\nimport type { Token } from \"./lexer.js\";\r\nimport type { AstElement, ElementKind, ExprPoint, Point } from \"./ast.js\";\r\nimport type { Expr } from \"./expr.js\";\r\nimport type { Diagnostic } from \"./diagnostics.js\";\r\nimport type { ResolvedElement, RWall } from \"./ir.js\";\r\nimport type { Bounds, WallSegment } from \"./geometry.js\";\r\n\r\n/**\r\n * Ordered render layers. Element ops are bucketed by pass and emitted in this\r\n * order, preserving source order within a pass — this exactly reproduces the\r\n * v0.1 global draw order (all wall fills, then all wall faces, doors before\r\n * windows, labels above fills, …).\r\n */\r\nexport const RENDER_PASSES = [\r\n \"floor\",\r\n \"furniture\",\r\n \"wallFill\",\r\n \"wallFace\",\r\n \"doors\",\r\n \"windows\",\r\n \"labels\",\r\n \"dims\",\r\n \"annotations\",\r\n] as const;\r\nexport type RenderPass = (typeof RENDER_PASSES)[number];\r\n\r\nexport interface RenderOp {\r\n pass: RenderPass;\r\n svg: string;\r\n}\r\n\r\n/** Parser facade handed to `ElementDef.parse` — the existing recursive-descent helpers. */\r\nexport interface ParseCtx {\r\n peek(o?: number): Token;\r\n next(): Token;\r\n eat(type: Token[\"type\"]): Token;\r\n eatKeyword(kw: string): Token;\r\n eatIdent(): Token;\r\n eatNumber(): number;\r\n eatString(): string;\r\n isKeyword(kw: string, o?: number): boolean;\r\n isType(type: Token[\"type\"]): boolean;\r\n /** Parse a `(expr, expr)` point. */\r\n parsePoint(): ExprPoint;\r\n /** Parse an arithmetic expression. */\r\n parseExpr(): Expr;\r\n /** Parse a size: either a `WxH` dimension literal or `<expr> x <expr>`. */\r\n parseDimensions(): { w: Expr; h: Expr };\r\n parseIdOpt(): string;\r\n /** Report a fatal parse error at `t` (defaults to the current token); never returns. */\r\n fail(msg: string, t?: Token): never;\r\n}\r\n\r\n/** Semantic-analysis facade handed to `ElementDef.resolve`. */\r\nexport interface ResolveCtx {\r\n grid: number;\r\n snap(v: number): number;\r\n snapPt(p: Point): Point;\r\n /** Evaluate an expression against the current binding environment. */\r\n eval(e: Expr): number;\r\n /** Evaluate an expression-point to a concrete point. */\r\n evalPt(p: ExprPoint): Point;\r\n /** Resolved id of the element currently being resolved. */\r\n id: string;\r\n /** Resolved walls, ready before openings resolve (walls resolve first). */\r\n walls: RWall[];\r\n hostSegment(at: Point, ref?: string): WallSegment | null;\r\n isOnWall(at: Point, ref?: string): boolean;\r\n diag(d: Diagnostic): void;\r\n}\r\n\r\nexport interface RenderSizes {\r\n refDim: number;\r\n wallStroke: number;\r\n thin: number;\r\n roomFont: number;\r\n areaFont: number;\r\n dimFont: number;\r\n furnFont: number;\r\n margin: number;\r\n hatchGap: number;\r\n}\r\n\r\n/** Render facade: number formatting, theme, derived sizes, and drawing bounds. */\r\nexport interface RenderCtx {\r\n fmt(v: number): string;\r\n pt(p: Point): string;\r\n xml(s: string): string;\r\n theme: Record<string, string>;\r\n sizes: RenderSizes;\r\n bounds: Bounds;\r\n}\r\n\r\n/**\r\n * One element type. `TNode`/`TResolved` are the concrete node/IR types; the\r\n * registry stores these widened to the unions, and each module narrows via the\r\n * `kind` discriminant.\r\n */\r\nexport interface ElementDef {\r\n kind: ElementKind;\r\n keyword: string;\r\n parse(ctx: ParseCtx): AstElement;\r\n /** Auto-id prefix (e.g. \"room\", or a wall/furniture's category). */\r\n idPrefix(node: AstElement): string;\r\n resolve(node: AstElement, ctx: ResolveCtx): ResolvedElement;\r\n /** Points this element contributes to the drawing bounds. */\r\n bounds(resolved: ResolvedElement): Point[];\r\n render(resolved: ResolvedElement, ctx: RenderCtx): RenderOp[];\r\n}\r\n","/** Renders a resolved plan (IR) to a professional SVG floor plan. Deterministic. */\r\n\r\nimport type { Point } from \"./ast.js\";\r\nimport type { CompileOptions } from \"./types.js\";\r\nimport type { ResolvedPlan } from \"./ir.js\";\r\nimport type { RenderCtx, RenderSizes } from \"./registry.js\";\r\nimport { RENDER_PASSES } from \"./registry.js\";\r\nimport { registry } from \"./elements/index.js\";\r\nimport type { Bounds } from \"./geometry.js\";\r\nimport { emptyBounds, extendBounds } from \"./geometry.js\";\r\n\r\nconst THEME: Record<string, string> = {\r\n bg: \"#ffffff\",\r\n pocheBase: \"#e9e4db\",\r\n pocheHatch: \"#b9b1a4\",\r\n wallStroke: \"#1b1b1b\",\r\n roomFill: \"#fbfaf7\",\r\n roomLabel: \"#222222\",\r\n areaLabel: \"#7a7a7a\",\r\n furnitureStroke: \"#a8a29a\",\r\n furnitureFill: \"#f4f2ee\",\r\n furnitureLabel: \"#9a948c\",\r\n opening: \"#ffffff\",\r\n doorLeaf: \"#555555\",\r\n windowPane: \"#3a6ea5\",\r\n dim: \"#0E5484\",\r\n annotation: \"#333333\",\r\n annotationMuted: \"#888888\",\r\n column: \"#4a4a4a\",\r\n};\r\n\r\n/** Round to 2 decimals and strip trailing zeros — keeps output stable & compact. */\r\nfunction fmt(v: number): string {\r\n const r = Math.round(v * 100) / 100;\r\n return Object.is(r, -0) ? \"0\" : String(r);\r\n}\r\nconst pt = (p: Point): string => `${fmt(p.x)},${fmt(p.y)}`;\r\n\r\nfunction xml(s: string): string {\r\n return s\r\n .replace(/&/g, \"&\")\r\n .replace(/</g, \"<\")\r\n .replace(/>/g, \">\")\r\n .replace(/\"/g, \""\");\r\n}\r\n\r\nconst NICE_LENGTHS = [500, 1000, 2000, 5000, 10000, 20000, 50000, 100000];\r\nfunction niceBarLength(target: number): number {\r\n let best = NICE_LENGTHS[0];\r\n for (const v of NICE_LENGTHS) if (v <= target) best = v;\r\n return best;\r\n}\r\n\r\n/** Drawing bounds: each element contributes points via its registry `bounds`. */\r\nfunction planBounds(ir: ResolvedPlan): Bounds {\r\n const b = emptyBounds();\r\n for (const el of ir.elements) {\r\n const def = registry.get(el.kind);\r\n if (!def) continue;\r\n for (const p of def.bounds(el)) extendBounds(b, p.x, p.y);\r\n }\r\n if (!isFinite(b.minX)) {\r\n // Nothing to draw; provide a default frame.\r\n return { minX: 0, minY: 0, maxX: 1000, maxY: 1000 };\r\n }\r\n return b;\r\n}\r\n\r\nexport function render(ir: ResolvedPlan, opts: CompileOptions = {}): string {\r\n const b = planBounds(ir);\r\n const drawW = b.maxX - b.minX;\r\n const drawH = b.maxY - b.minY;\r\n const refDim = Math.max(drawW, drawH, 1);\r\n\r\n const sizes: RenderSizes = {\r\n refDim,\r\n wallStroke: refDim * 0.0028,\r\n thin: refDim * 0.0016,\r\n roomFont: refDim * 0.03,\r\n areaFont: refDim * 0.022,\r\n dimFont: refDim * 0.02,\r\n furnFont: refDim * 0.017,\r\n margin: refDim * 0.17,\r\n hatchGap: refDim * 0.013,\r\n };\r\n const { thin, margin, hatchGap } = sizes;\r\n\r\n const vbX = b.minX - margin;\r\n const vbY = b.minY - margin;\r\n const vbW = drawW + margin * 2;\r\n const vbH = drawH + margin * 2;\r\n\r\n const out: string[] = [];\r\n const svgAttrs = opts.width\r\n ? `width=\"${fmt(opts.width)}\" height=\"${fmt((opts.width * vbH) / vbW)}\"`\r\n : \"\";\r\n out.push(\r\n `<svg xmlns=\"http://www.w3.org/2000/svg\" ${svgAttrs} viewBox=\"${fmt(vbX)} ${fmt(vbY)} ${fmt(vbW)} ${fmt(vbH)}\" font-family=\"Helvetica, Arial, sans-serif\">`,\r\n );\r\n\r\n // Defs: poché hatch pattern\r\n out.push(\r\n `<defs><pattern id=\"poche\" patternUnits=\"userSpaceOnUse\" width=\"${fmt(hatchGap)}\" height=\"${fmt(hatchGap)}\" patternTransform=\"rotate(45)\">` +\r\n `<rect width=\"${fmt(hatchGap)}\" height=\"${fmt(hatchGap)}\" fill=\"${THEME.pocheBase}\"/>` +\r\n `<line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"${fmt(hatchGap)}\" stroke=\"${THEME.pocheHatch}\" stroke-width=\"${fmt(thin * 0.7)}\"/>` +\r\n `</pattern></defs>`,\r\n );\r\n\r\n // Background\r\n out.push(`<rect x=\"${fmt(vbX)}\" y=\"${fmt(vbY)}\" width=\"${fmt(vbW)}\" height=\"${fmt(vbH)}\" fill=\"${THEME.bg}\"/>`);\r\n\r\n // Elements: collect ops once (preserving source order), then emit pass by pass.\r\n const ctx: RenderCtx = { fmt, pt, xml, theme: THEME, sizes, bounds: b };\r\n const ops = ir.elements.flatMap((el) => {\r\n const def = registry.get(el.kind);\r\n return def ? def.render(el, ctx) : [];\r\n });\r\n for (const pass of RENDER_PASSES) {\r\n for (const op of ops) if (op.pass === pass) out.push(op.svg);\r\n }\r\n\r\n // Plan-level annotations (after element passes): north, scale bar, title block.\r\n out.push(northArrow(ir, b, margin, refDim));\r\n out.push(scaleBar(b, margin, refDim, thin));\r\n const tb = titleBlock(ir, b, margin, refDim, thin);\r\n if (tb) out.push(tb);\r\n\r\n out.push(\"</svg>\");\r\n return out.join(\"\\n\");\r\n}\r\n\r\nfunction northArrow(ir: ResolvedPlan, b: Bounds, margin: number, refDim: number): string {\r\n const r = refDim * 0.045;\r\n const cx = b.maxX - r;\r\n const cy = b.minY - margin * 0.55;\r\n let deg: number;\r\n switch (ir.north) {\r\n case \"up\": deg = 0; break;\r\n case \"down\": deg = 180; break;\r\n case \"left\": deg = 270; break;\r\n case \"right\": deg = 90; break;\r\n default: deg = typeof ir.north === \"object\" ? ir.north.deg : 0;\r\n }\r\n const fs = refDim * 0.026;\r\n // Triangle points \"up\" before rotation; only the arrow rotates — the \"N\"\r\n // label stays upright at the pointing end so it always reads correctly.\r\n const tri = `${fmt(cx)},${fmt(cy - r)} ${fmt(cx - r * 0.5)},${fmt(cy + r * 0.6)} ${fmt(cx)},${fmt(cy + r * 0.25)} ${fmt(cx + r * 0.5)},${fmt(cy + r * 0.6)}`;\r\n const rad = (deg * Math.PI) / 180;\r\n // North screen vector (rotate the \"up\" vector (0,-1) clockwise by deg).\r\n const nx = Math.sin(rad);\r\n const ny = -Math.cos(rad);\r\n const lx = cx + nx * (r + fs * 0.8);\r\n const ly = cy + ny * (r + fs * 0.8);\r\n return (\r\n `<g>` +\r\n `<polygon points=\"${tri}\" fill=\"${THEME.annotation}\" transform=\"rotate(${fmt(deg)} ${fmt(cx)} ${fmt(cy)})\"/>` +\r\n `<text x=\"${fmt(lx)}\" y=\"${fmt(ly)}\" font-size=\"${fmt(fs)}\" fill=\"${THEME.annotation}\" text-anchor=\"middle\" dominant-baseline=\"central\">N</text>` +\r\n `</g>`\r\n );\r\n}\r\n\r\nfunction scaleBar(b: Bounds, margin: number, refDim: number, thin: number): string {\r\n const barLen = niceBarLength(refDim * 0.3);\r\n const x0 = b.minX;\r\n const y0 = b.maxY + margin * 0.55;\r\n const hgt = refDim * 0.014;\r\n const fs = refDim * 0.02;\r\n const parts: string[] = [];\r\n const half = barLen / 2;\r\n // two-segment alternating bar\r\n parts.push(`<rect x=\"${fmt(x0)}\" y=\"${fmt(y0)}\" width=\"${fmt(half)}\" height=\"${fmt(hgt)}\" fill=\"${THEME.annotation}\"/>`);\r\n parts.push(\r\n `<rect x=\"${fmt(x0 + half)}\" y=\"${fmt(y0)}\" width=\"${fmt(half)}\" height=\"${fmt(hgt)}\" fill=\"none\" stroke=\"${THEME.annotation}\" stroke-width=\"${fmt(thin)}\"/>`,\r\n );\r\n parts.push(\r\n `<text x=\"${fmt(x0)}\" y=\"${fmt(y0 + hgt + fs)}\" font-size=\"${fmt(fs)}\" fill=\"${THEME.annotation}\" text-anchor=\"start\" dominant-baseline=\"central\">0</text>`,\r\n );\r\n parts.push(\r\n `<text x=\"${fmt(x0 + barLen)}\" y=\"${fmt(y0 + hgt + fs)}\" font-size=\"${fmt(fs)}\" fill=\"${THEME.annotation}\" text-anchor=\"middle\" dominant-baseline=\"central\">${barLen / 1000} m</text>`,\r\n );\r\n return `<g>${parts.join(\"\")}</g>`;\r\n}\r\n\r\nfunction titleBlock(ir: ResolvedPlan, b: Bounds, margin: number, refDim: number, thin: number): string | null {\r\n const t = ir.title;\r\n if (!t && !ir.scale) return null;\r\n const boxW = refDim * 0.34;\r\n const boxH = margin * 0.82;\r\n const x0 = b.maxX - boxW;\r\n const y0 = b.maxY + margin * 0.15;\r\n const fs = refDim * 0.019;\r\n const pad = boxW * 0.05;\r\n const lines: { k: string; v: string }[] = [];\r\n if (t?.project) lines.push({ k: \"PROJECT\", v: t.project });\r\n if (t?.drawnBy) lines.push({ k: \"DRAWN BY\", v: t.drawnBy });\r\n if (t?.date) lines.push({ k: \"DATE\", v: t.date });\r\n if (ir.scale) lines.push({ k: \"SCALE\", v: ir.scale });\r\n\r\n const parts: string[] = [];\r\n parts.push(\r\n `<rect x=\"${fmt(x0)}\" y=\"${fmt(y0)}\" width=\"${fmt(boxW)}\" height=\"${fmt(boxH)}\" fill=\"none\" stroke=\"${THEME.annotation}\" stroke-width=\"${fmt(thin)}\"/>`,\r\n );\r\n const rowH = boxH / Math.max(lines.length, 1);\r\n lines.forEach((ln, i) => {\r\n const ly = y0 + rowH * (i + 0.5);\r\n parts.push(\r\n `<text x=\"${fmt(x0 + pad)}\" y=\"${fmt(ly)}\" font-size=\"${fmt(fs * 0.8)}\" fill=\"${THEME.annotationMuted}\" dominant-baseline=\"central\">${xml(ln.k)}</text>`,\r\n );\r\n parts.push(\r\n `<text x=\"${fmt(x0 + boxW - pad)}\" y=\"${fmt(ly)}\" font-size=\"${fmt(fs)}\" fill=\"${THEME.annotation}\" text-anchor=\"end\" dominant-baseline=\"central\">${xml(ln.v)}</text>`,\r\n );\r\n if (i > 0)\r\n parts.push(\r\n `<line x1=\"${fmt(x0)}\" y1=\"${fmt(y0 + rowH * i)}\" x2=\"${fmt(x0 + boxW)}\" y2=\"${fmt(y0 + rowH * i)}\" stroke=\"${THEME.annotation}\" stroke-width=\"${fmt(thin * 0.5)}\"/>`,\r\n );\r\n });\r\n return `<g>${parts.join(\"\")}</g>`;\r\n}\r\n","/**\r\n * Diagnostics for the ArchLang compiler.\r\n *\r\n * A {@link Diagnostic} is the single, span-carrying problem record produced by\r\n * every compiler stage (lex/parse/validate). The legacy `{message, line, col}`\r\n * `errors`/`warnings` arrays on {@link import(\"./types.js\").CompileResult} are\r\n * *derived* from these. {@link formatDiagnostic} renders a codespan-style,\r\n * caret-framed snippet — zero dependencies, pure, isomorphic.\r\n */\r\n\r\n/** A half-open byte range `[start, end)` into the source string. */\r\nexport interface Span {\r\n start: number;\r\n end: number;\r\n}\r\n\r\nexport type Severity = \"error\" | \"warning\";\r\n\r\nexport interface Diagnostic {\r\n severity: Severity;\r\n message: string;\r\n /** Source location; absent for whole-program problems (e.g. an empty plan). */\r\n span?: Span;\r\n /** Stable machine code, e.g. `\"E_ROOM_SIZE\"`. */\r\n code?: string;\r\n /** Optional follow-up suggestions, each rendered as a `= help:` line. */\r\n hints?: string[];\r\n}\r\n\r\n/** Convert a byte offset into a 1-based `{line, col}`. Offsets are clamped. */\r\nexport function offsetToLineCol(source: string, offset: number): { line: number; col: number } {\r\n const o = Math.max(0, Math.min(offset, source.length));\r\n let line = 1;\r\n let col = 1;\r\n for (let k = 0; k < o; k++) {\r\n if (source[k] === \"\\n\") {\r\n line++;\r\n col = 1;\r\n } else {\r\n col++;\r\n }\r\n }\r\n return { line, col };\r\n}\r\n\r\n/** Byte offset of the start of the line containing `offset`. */\r\nfunction lineStart(source: string, offset: number): number {\r\n let k = Math.max(0, Math.min(offset, source.length));\r\n while (k > 0 && source[k - 1] !== \"\\n\") k--;\r\n return k;\r\n}\r\n\r\n/** Byte offset just past the end of the line containing `offset` (excludes `\\n`). */\r\nfunction lineEnd(source: string, offset: number): number {\r\n let k = Math.max(0, Math.min(offset, source.length));\r\n while (k < source.length && source[k] !== \"\\n\") k++;\r\n return k;\r\n}\r\n\r\n/**\r\n * Render a diagnostic as a framed source snippet:\r\n *\r\n * ```text\r\n * error[E_ROOM_SIZE]: room \"bed\" must have a positive size\r\n * --> 4:30\r\n * |\r\n * 4 | room id=bed at (0,0) size 0x4000\r\n * | ^^^^^^ width is 0\r\n * = help: did you mean 3000x4000?\r\n * ```\r\n *\r\n * With no `span`, only the header line is produced.\r\n */\r\nexport function formatDiagnostic(source: string, d: Diagnostic): string {\r\n const codeTag = d.code ? `[${d.code}]` : \"\";\r\n const header = `${d.severity}${codeTag}: ${d.message}`;\r\n const lines: string[] = [header];\r\n\r\n if (d.span) {\r\n const { line, col } = offsetToLineCol(source, d.span.start);\r\n const ls = lineStart(source, d.span.start);\r\n const le = lineEnd(source, d.span.start);\r\n const srcLine = source.slice(ls, le);\r\n // Underline within this one line; multi-line spans underline to line end.\r\n const caretStart = d.span.start - ls;\r\n const caretEnd = Math.min(d.span.end, le) - ls;\r\n const caretLen = Math.max(1, caretEnd - caretStart);\r\n\r\n const gutter = String(line);\r\n const pad = \" \".repeat(gutter.length);\r\n lines.push(`${pad} --> ${line}:${col}`);\r\n lines.push(`${pad} |`);\r\n lines.push(`${gutter} | ${srcLine}`);\r\n lines.push(`${pad} | ${\" \".repeat(caretStart)}${\"^\".repeat(caretLen)}`);\r\n for (const hint of d.hints ?? []) {\r\n lines.push(`${pad} = help: ${hint}`);\r\n }\r\n } else {\r\n for (const hint of d.hints ?? []) {\r\n lines.push(` = help: ${hint}`);\r\n }\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","/**\r\n * ArchLang — compile declarative floor-plan source to a professional SVG.\r\n *\r\n * @example\r\n * import { compile } from \"@chanmeng666/archlang\";\r\n * const { svg, errors } = compile(`plan \"Demo\" { room at (0,0) size 4000x3000 label \"Room\" }`);\r\n */\r\n\r\nimport { parse } from \"./parser.js\";\r\nimport { resolve } from \"./ir.js\";\r\nimport { render } from \"./render.js\";\r\nimport { offsetToLineCol } from \"./diagnostics.js\";\r\nimport type { Diagnostic } from \"./diagnostics.js\";\r\nimport type { CompileError, CompileOptions, CompileResult } from \"./types.js\";\r\n\r\nexport type {\r\n CompileError,\r\n CompileOptions,\r\n CompileResult,\r\n CompileWarning,\r\n Diagnostic,\r\n Span,\r\n Severity,\r\n} from \"./types.js\";\r\nexport { formatDiagnostic, offsetToLineCol } from \"./diagnostics.js\";\r\nexport type * from \"./ast.js\";\r\n\r\n/** Small LRU-ish memo cache keyed by source+options. Bounded to 64 entries. */\r\nconst cache = new Map<string, CompileResult>();\r\nconst CACHE_MAX = 64;\r\n\r\nexport function compile(source: string, opts: CompileOptions = {}): CompileResult {\r\n const key = JSON.stringify([source, opts.width ?? null]);\r\n if (!opts.noCache) {\r\n const hit = cache.get(key);\r\n if (hit) return hit;\r\n }\r\n\r\n const result = compileUncached(source, opts);\r\n\r\n if (!opts.noCache) {\r\n if (cache.size >= CACHE_MAX) {\r\n const oldest = cache.keys().next().value;\r\n if (oldest !== undefined) cache.delete(oldest);\r\n }\r\n cache.set(key, result);\r\n }\r\n return result;\r\n}\r\n\r\n/** Project a span-carrying diagnostic onto the legacy `{message, line, col}` shape. */\r\nfunction toLegacy(source: string, d: Diagnostic): CompileError {\r\n if (!d.span) return { message: d.message };\r\n const { line, col } = offsetToLineCol(source, d.span.start);\r\n return { message: d.message, line, col };\r\n}\r\n\r\nfunction compileUncached(source: string, opts: CompileOptions): CompileResult {\r\n const { plan, diagnostics: parseDiags } = parse(source);\r\n\r\n // parse → resolve (AST→IR, the single place semantics live) → render.\r\n const resolved = plan ? resolve(plan) : null;\r\n const diagnostics: Diagnostic[] = resolved\r\n ? [...parseDiags, ...resolved.diagnostics]\r\n : [...parseDiags];\r\n\r\n const errs = diagnostics.filter((d) => d.severity === \"error\");\r\n const errors = errs.map((d) => toLegacy(source, d));\r\n const warnings = diagnostics\r\n .filter((d) => d.severity === \"warning\")\r\n .map((d) => toLegacy(source, d));\r\n\r\n // Warnings never block rendering; any error (or no plan) aborts with svg = \"\".\r\n const svg = resolved && errs.length === 0 ? render(resolved.ir, opts) : \"\";\r\n\r\n return { svg, errors, warnings, diagnostics, ast: plan };\r\n}\r\n\r\n/** Clear the internal compile cache (useful in long-lived processes/tests). */\r\nexport function clearCache(): void {\r\n cache.clear();\r\n}\r\n"],"mappings":"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","names":["describe","fmt","pt","fmt","pt","xml","fmt","pt","fmt","pt","fmt","pt","xml","fmt","xml","fmt","pt","describe","def"]}
|