Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Syntax.Report

Caret rendering for Syntax.Diagnostic: the plain-text report the compiler prints for a refused source.

It is rebuilt in Prism from the diagnostic and the source text alone. The target is exact bytes, not a lookalike, so the layout below is an executable specification of the compiler’s renderer: the header line, the location line, the gutter, the source line with tabs expanded to four-column stops, the underline row, the arrow row carrying the label, and the closing rule. Syntax.Diagnostic supplies the data; this module is the only thing in Prism that can draw it.

The shape reproduced is one primary span drawn as a caret under one source line, which is every diagnostic the syntax boundary raises: a lexical fault is a zero-width caret at its offset, and a parse fault is the offending token’s span or a caret at end of input. rp_exact is the predicate for that shape and rp_report answers None outside it rather than guessing. Three things fall outside.

A span crossing a line boundary, reachable through a multi-line string literal, draws the compiler’s multi-line form instead: an arrow down the margin from the opening line to the closing one. That form is not implemented.

Several labels on one report, and the help and note trailers, belong to the structured type-error path rather than the syntax boundary. related is a reserved surface on Diagnostic and nothing populates it yet, so a second label has no source here to draw from.

A non-ASCII byte at or before the end of the diagnostic’s own line changes the answer, and there the compiler’s output is the right one: it draws one cell per character, while every column here is counted in bytes, so a two-byte character before the caret pulls this module’s caret one cell further right. Counting characters would mean carrying a decoder the rest of the module has no use for, so the predicate below declines those lines instead.

Functions and Values

rp_kind

rp_kind : (Syntax.Diagnostic.DiagPhase) -> String

The report-kind label the compiler stamps in the header for a phase.

rp_kind(DPLex)
Lexical Error

rp_label

rp_label : (Syntax.Diagnostic.Diagnostic) -> String

The text on the caret’s label. The end-of-input parse fault asks for more input; every other diagnostic points here.

rp_message

rp_message : (String, Syntax.Diagnostic.Diagnostic) -> String

The message on the header line. A parse fault’s message already carries its own position; a lexical fault’s is followed by the line and column of its caret.

rp_exact

rp_exact : (String, Syntax.Diagnostic.Diagnostic) -> Bool

Whether the compiler draws this diagnostic as one caret under one source line, the shape this module reproduces byte for byte. False for a span that crosses a line boundary, a span running past the end of the text, and a source carrying a non-ASCII byte at or before the end of the caret’s line.

rp_report

rp_report : (String, String, Syntax.Diagnostic.Diagnostic) -> Option(String)

The compiler’s plain-text report for one diagnostic, or None when the diagnostic falls outside the shape this module draws (see rp_exact). name is the source name in the location line; the compiler passes <source> when reporting on a single file. The result ends with a newline.

let d = Diagnostic {
  code = "E7100",
  phase = DPParse,
  span = Span { lo = 12, hi = 13 },
  message = "unexpected ')'",
  expected = Nil,
  related = Nil
}
print(unwrap_or("", rp_report("<source>", "fn main() = )\n", d)))
[E7100] Parse Error: unexpected ')'
   ╭─[ <source>:1:13 ]
   │
 1 │ fn main() = )
   │             ┬
   │             ╰── here
───╯

rp_report_doc

rp_report_doc : (String, Syntax.Diagnostic.DiagnosticsDoc) -> Option(String)

Every diagnostic in a document rendered in order and concatenated, or None when any one of them falls outside the shape this module draws. The compiler stops at its first refusal, so a document carrying more than one diagnostic has no single compiler report to compare against.