README

marianoguerra/wax/basic does not have a README file

#
Annotated

pub(all) struct Annotated[D, Info] {
desc : D
info : Info
} derive(Eq,
Debug
)

A value of type D carried together with an annotation of type Info.

This is the reference's ('desc, 'info) annotated. The annotation is a type parameter rather than a fixed Location because the type checker — which will be ported later — re-annotates the tree with inferred types.

#
Edit

pub(all) struct Edit {
loc : Location
new_text : String
} derive(Eq,
Debug
)

A machine-applicable rewrite: replace the source spanned by loc with new_text. An empty span denotes an insertion. Mirrors Diagnostic.edit.

#
Label

pub(all) struct Label {
loc : Location
message : String
} derive(Eq,
Debug
)

A secondary span attached to a diagnostic, e.g. "This '(' opens the enclosing construct." Mirrors Diagnostic.label.

#
LocStyle

pub(all) enum LocStyle {
Hidden
Json
Str
}

How a Location renders in JSON.

AST snapshot tests are far more readable — and far less churn-prone — when spans are hidden or abbreviated, but the differential harness needs the full form. Rather than thread a formatting flag through every to_json, the reference's own tests set a process-wide knob; moonbitlang/parser does the same in lexer/basic/config.mbt, and this follows suit.

#
Location

pub(all) struct Location {
start : Position
end : Position
} derive(Compare, Eq, Hash,
Debug
)

A source span, mirroring the reference's Wax_utils.Ast.location ({ loc_start; loc_end }).
impl Show for Location
impl ToJson for Location

#
Location::collapse_end

fn Location::collapse_end(self : Location) -> Location

An empty span at the end of self, used for an insertion-point edit.

#
Location::collapse_start

fn Location::collapse_start(self : Location) -> Location

An empty span at the start of self, used for an insertion-point edit.

#
Location::is_dummy

fn Location::is_dummy(self : Location) -> Bool

#
Location::merge

fn Location::merge(self : Location, other : Location) -> Location

The smallest span covering both operands. Both must come from the same file: a merge across files has no meaning, so it is a caller bug rather than a case to handle, and guard! says so.

#
Position

pub(all) struct Position {
fname : String
lnum : Int
bol : Int
cnum : Int
} derive(Hash, ToJson,
Debug
)

A position in a source file.

  • fname — the file name ("" when reading from stdin).
  • lnum — the line number, 1-based.
  • bol — the byte offset of the beginning of the current line.
  • cnum — the absolute byte offset of the position itself.

The column is not stored; it is cnum - bol. Use column0 or column1 depending on the convention the caller needs — see their documentation.
impl Compare for Position
impl Eq for Position
impl Show for Position

#
Position::column0

fn Position::column0(self : Position) -> Int

The 0-based column: the raw cnum - bol.

This is the convention the reference's JSON diagnostic renderer uses for startColumn/endColumn.

#
Position::column1

fn Position::column1(self : Position) -> Int

The 1-based column, cnum - bol + 1.

This is the convention the reference's human and short diagnostic renderers use.

#
Position::is_dummy

fn Position::is_dummy(self : Position) -> Bool

#
Report

pub(all) struct Report {
loc : Location
severity : Severity
message : String
warning : String?
hint : String?
edit : Edit?
related : Array[Label]
} derive(Eq,
Debug
)

A diagnostic, in the accumulate-don't-raise style moonbitlang/parser uses.

message is a plain String here rather than the reference's structured Message.t. That is deliberate for now: the front end only needs to render, not to restyle. When the type checker lands it will want the combinator form (so types can be coloured inside a sentence), at which point this field becomes a Message — every other field stays as-is.

#
Report::error

fn Report::error(loc : Location, message : String) -> Report

An error Report with no warning name, hint, edit or related labels — the shape every syntax and lexical error takes.

#
Severity

pub(all) enum Severity {
Error
Warning
Suggestion
} derive(Eq,
Debug
)

How serious a diagnostic is. Mirrors the reference's Diagnostic.severity.

Suggestion is never produced by the front end — it belongs to the type checker's machine-applicable fixes — but it is declared here so the diagnostic renderers can be written once, against the complete set.

#
Severity::header

fn Severity::header(self : Severity) -> String

The word the reference's human renderer prints as a diagnostic header.

#
Severity::to_str

fn Severity::to_str(self : Severity) -> String

The string the reference's JSON and short renderers use.

#
dummy_loc

let dummy_loc : Location

The span of a synthesized node, mirroring the reference's dummy_loc.

#
dummy_pos

let dummy_pos : Position

The position OCaml's Lexing.dummy_pos denotes, for synthesized nodes that have no source span.

Note cnum is -1, not 0: the reference's output_error_no_source path tests for exactly this to decide whether it can print a File "…", line … header at all, so the sentinel value has to match.

#
no_loc

fn[D] no_loc(desc : D) -> Annotated[D, Location]

Wrap a value with a dummy span, the counterpart of the reference's no_loc.

#
show_loc

The active Location JSON style. Scope a change with show_loc.protect rather than assigning to it directly, so a failing test cannot leak the setting into the next one.