/** * Source-position metadata attached to AST nodes by `ProgramParser.parse`. * Lives in its own module so both `program.ts` and `dice-expression.ts` can * import it without introducing a circular dependency. */ export interface SourceSpan { /** Zero-based UTF-16 code-unit offset into the source string. */ offset: number; /** Length in UTF-16 code units. */ length: number; } /** * A source comment, preserved by the parser when comment-aware parsing is * enabled. Comments attach to AST nodes via the optional `comments` slot; * the formatter (`format`) re-emits them in their original position. The * evaluator and canonicalize ignore comments — they are pure decoration. * * Lives here (alongside {@link SourceSpan}) rather than in `program.ts` so * that both program-side nodes and `dice-expression.ts` nodes can carry a * uniform `comments` slot without a circular import. */ export interface Comment { /** * Comment body with the leading `#` stripped and exactly one optional * leading space stripped — the canonical form most renderers want. * * `# foo` → `text: "foo"` * `#foo` → `text: "foo"` * `# foo` → `text: " foo"` (extra spaces preserved) */ text: string; /** * Verbatim source of the comment token, including the leading `#` and * any internal whitespace, but excluding the trailing newline. Useful * for tooling that needs to preserve the user's exact formatting. * Optional so comments synthesised by transforms (canonicalize rewrites, * downstream codegen) don't need to invent a raw form. */ raw?: string; /** Source range of the original comment token, if known. */ loc?: SourceSpan; } export interface CommentAttachment { /** Comments emitted on the line(s) immediately above this node. */ leading?: Comment[]; /** Comments emitted at end-of-line after this node. */ trailing?: Comment[]; }