spanner
A small Gleam library for tracking positions and spans in source code, designed for use in lexers and parsers.
Installation
gleam add spanner@1
Usage
import spanner
// A Position tracks where you are in a source file.
// start() gives you line 1, column 1, byte offset 0.
let pos = spanner.start()
// advance() moves the position forward through any chunk of source text.
// It handles \r\n and \r line endings, and counts multi-byte characters
// like é as a single column.
let token_start = pos
let pos = spanner.advance(pos, "hello")
// pos is now Position(line: 1, column: 6, byte_offset: 5)
// between() records the span of a token by capturing where it started
// and where the position is now.
let token_span = spanner.between(token_start, pos)
// label() formats a span for use in error messages.
spanner.label("src/main.gl", token_span)
// "src/main.gl:1:1"
// In a parser, combine child spans to get the parent node's span.
let expr_span = spanner.between(left_span.start, right_span.end)
API
pub type Position {
Position(line: Int, column: Int, byte_offset: Int)
}
pub type Span {
Span(start: Position, end: Position)
}
pub fn start() -> Position
pub fn advance(Position, String) -> Position
pub fn between(start: Position, end: Position) -> Span
pub fn label(filename: String, Span) -> String
Development
gleam test # Run the tests
gleam build # Build the library