PseudoScript
Module

format

container

Format #

public
format::Format

`crates/pseudoscript-format`. The canonical formatter: parse, then pretty-print the tree to one canonical form. The string-to-string entry the CLI and LSP depend on.

Inbound

Outbound

Scenarios

FormatIsIdempotent

Formatting the output again changes nothing.

  • given a parseable .pds source
  • when it is formatted and the result is formatted a second time
  • then the first pass yields canonical text
  • and the second pass returns that text unchanged
Flow Flow — FormatIsIdempotent scroll to zoom · drag to pan
FEATUREFormatIsIdempotentfor FormatGIVENa parseable .pds sourceWHENit is formatted and the result isformatted a second timeTHENthe first pass yields canonical textANDthe second pass returns that textunchanged
FormatPreservesSemantics

Reformatting only touches layout, never meaning.

  • given a parseable .pds source
  • when it is formatted
  • then the result re-parses to a structurally equivalent tree
  • but only whitespace and comment layout differ from the source
Flow Flow — FormatPreservesSemantics scroll to zoom · drag to pan
FEATUREFormatPreservesSemanticsfor FormatGIVENa parseable .pds sourceWHENit is formattedTHENthe result re-parses to a structurallyequivalent treeBUTonly whitespace and comment layoutdiffer from the source
Components Component diagram scroll to zoom · drag to pan
PseudoscriptFormatCOMPONENTFormatterDrives the headline flow: parse the source,short-circuit to `FormatError::Parse` if an…COMPONENTPrinterThe canonical pretty-printer: walks the ASTtop-down, appending to a buffer, and emits…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…renderTokensprintparse
data

FormatError #

public
format::FormatError

Why formatting failed. The only failure is unparseable input: `Parse` carries the rendered error messages (one per diagnostic) for context, and the caller keeps its original text.

Entities Entity diagram scroll to zoom · drag to pan
UNIONFormatErrorParseRECORDParsemessagesstring[]
component

Formatter #

private
format::Formatter

Drives the headline flow: parse the source, short-circuit to `FormatError::Parse` if any error diagnostic surfaced, else hand the tree to the printer for canonical text.

Parent

Inbound

Outbound

Scenarios

ParseErrorsShortCircuit

Unparseable source short-circuits and is left untouched.

  • given source with at least one error-severity parse diagnostic
  • when it is formatted
  • then formatting returns FormatError::Parse carrying the rendered messages
  • but the source is not rewritten and the caller keeps the original text
Flow Flow — ParseErrorsShortCircuit scroll to zoom · drag to pan
FEATUREParseErrorsShortCircuitfor FormatterGIVENsource with at least oneerror-severity parse diagnosticWHENit is formattedTHENformatting returns FormatError::Parsecarrying the rendered messagesBUTthe source is not rewritten and thecaller keeps the original text
OnlyErrorsBlockFormatting

Warnings and info never block formatting.

  • given source that parses with only warning or info diagnostics
  • when it is formatted
  • then the tree is pretty-printed to canonical text
  • but the non-error diagnostics do not short-circuit the formatter
Flow Flow — OnlyErrorsBlockFormatting scroll to zoom · drag to pan
FEATUREOnlyErrorsBlockFormattingfor FormatterGIVENsource that parses with only warningor info diagnosticsWHENit is formattedTHENthe tree is pretty-printed tocanonical textBUTthe non-error diagnostics do notshort-circuit the formatter
data

Parse #

public
format::Parse
Entities Entity diagram scroll to zoom · drag to pan
RECORDParsemessagesstring[]
component

Printer #

private
format::Printer

The canonical pretty-printer: walks the AST top-down, appending to a buffer, and emits one canonical form. Indentation is a level counter (two spaces each); leading trivia is normalised — blank-line runs collapse to at most one separator and `//` / `/* */` comments reproduce at the current indent in source order. Internals are black-boxed per construct; the top-level `print` flow is disclosed.

Parent

Inbound

Outbound

Scenarios

CanonicalRecord

Records render on one line.

  • given a data record declaration
  • when it is printed
  • then the fields render inline as { a: T, b: U }
  • and an empty record renders as { }
Flow Flow — CanonicalRecord scroll to zoom · drag to pan
FEATURECanonicalRecordfor PrinterGIVENa data record declarationWHENit is printedTHENthe fields render inline as { a: T, b:U }ANDan empty record renders as { }
CanonicalUnion

Unions stack one variant per line.

  • given a data union declaration
  • when it is printed
  • then the body opens with ` =` on the declaration line
  • and each variant prints as `| Name` on its own line, indented one level
Flow Flow — CanonicalUnion scroll to zoom · drag to pan
FEATURECanonicalUnionfor PrinterGIVENa data union declarationWHENit is printedTHENthe body opens with ` =` on thedeclaration lineANDeach variant prints as `| Name` on itsown line, indented one level
CanonicalFeature

Features render one step per line.

  • given a feature declaration with given/when/then steps
  • when it is printed
  • then each step prints on its own line, keyword then prose
  • but the keywords are not column-aligned, keeping the form idempotent
Flow Flow — CanonicalFeature scroll to zoom · drag to pan
FEATURECanonicalFeaturefor PrinterGIVENa feature declaration withgiven/when/then stepsWHENit is printedTHENeach step prints on its own line,keyword then proseBUTthe keywords are not column-aligned,keeping the form idempotent
TwoSpaceIndent

Indentation is two spaces per nesting level.

  • given a disclosed node, block, union, or feature body
  • when its members are printed
  • then each nesting level adds two spaces of indentation
Flow Flow — TwoSpaceIndent scroll to zoom · drag to pan
FEATURETwoSpaceIndentfor PrinterGIVENa disclosed node, block, union, orfeature bodyWHENits members are printedTHENeach nesting level adds two spaces ofindentation
TriviaPreserved

Comments and blank-line runs survive; runs collapse to one.

  • given source interleaving declarations with comments and runs of blank lines
  • when it is printed
  • then each comment reproduces on its own line at the current indent
  • and a run of blank lines collapses to a single blank separator
  • but the first member in a block or file gets no leading blank line
Flow Flow — TriviaPreserved scroll to zoom · drag to pan
FEATURETriviaPreservedfor PrinterGIVENsource interleaving declarations withcomments and runs of blank linesWHENit is printedTHENeach comment reproduces on its ownline at the current indentANDa run of blank lines collapses to asingle blank separatorBUTthe first member in a block or filegets no leading blank line
BodyFormsPreserved

Black-box and disclosed forms are each kept, never converted.

  • given a mix of black-box `;` and disclosed `{ }` nodes and callables
  • when they are printed
  • then a black-box body stays `;`
  • and a disclosed body keeps its `{ }`, one member per line
  • but an empty disclosed body renders ` { }`
Flow Flow — BodyFormsPreserved scroll to zoom · drag to pan
FEATUREBodyFormsPreservedfor PrinterGIVENa mix of black-box `;` and disclosed`{ }` nodes and callablesWHENthey are printedTHENa black-box body stays `;`ANDa disclosed body keeps its `{ }`, onemember per lineBUTan empty disclosed body renders ` { }`
data

PrinterState #

private
format::PrinterState

The running pretty-printer state: the text buffer being built, the current nesting depth (two spaces each), and whether the current line has had its indentation written yet so further writes append in place.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDPrinterStateoutstringindentnumberlineStartedbool
Generated by pds doc.