kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
83 lines • 4.52 kB
TypeScript
/**
* # lex — the indentation-aware lexer (text -> a line tree of tokens)
*
* The inverse projection of the printer begins here (ADR-0004). Kestrel is line-oriented:
* a statement **header** sits at its own indentation and its **clauses** sit one level
* deeper (ADR-0005: "line continuation is solved by an indentation-aware lexer from day
* one"). This lexer does two jobs:
*
* 1. **Tokenize** each physical line into {@link Token}s that carry `line`/`col` so every
* parse error can name exactly where it happened (fail-closed, ARCHITECTURE §6).
* 2. **Nest** physical lines into a {@link LineNode} tree by indentation, so the parser
* can tell a statement's clauses (deeper) from its siblings (same indent) — and so a
* **continued clause line** (deeper still) folds into the clause above it.
*
* The tokenizer is deliberately small: WORD / NUMBER / STRING / PUNCT. The tight lexical
* forms Kestrel prints — `fair-3c`, `velocity(1m)`, `p99`, `0dte`, `zoom-1d` — are
* reassembled by the *parser* from adjacent tokens (it knows the grammar position), not
* guessed at by the lexer.
*/
/** A parse (or lex) failure. Carries `line`/`col` and an instructive message — the text is
* read by LLM agents, so it names what was expected and what was found (ARCHITECTURE §6:
* fail-closed, never degrade silently). */
export declare class KestrelParseError extends Error {
readonly line: number;
readonly col: number;
readonly name = "KestrelParseError";
constructor(message: string, line: number, col: number);
}
export type TokenType = "word" | "number" | "string" | "punct";
/** One lexical token. `col`/`end` are 1-based columns within `line`; adjacency (no
* intervening space) is `next.col === prev.end`, which the parser uses to reassemble tight
* forms like `fair-3c`. For a `string` token, `text` is the DECODED value (quotes and
* escapes removed). */
export interface Token {
readonly type: TokenType;
readonly text: string;
readonly line: number;
readonly col: number;
/** 1-based column one past the last character (exclusive). */
readonly end: number;
}
/** One physical line's tokens, plus any deeper-indented lines nested beneath it (its
* clauses, or — for a continued line — its continuation).
*
* Comment trivia (ADR-0033, byte-stable round-trip): `leading` are the own-line `#` comments
* that immediately precede this line (verbatim, `#` excluded); `trailing` is the inline `#`
* comment on this same line (verbatim, `#` excluded); `tail` are the own-line comments that
* fall INSIDE this block after its last child, at the block's interior indentation. All are
* absent on a comment-free line. */
export interface LineNode {
readonly indent: number;
readonly line: number;
/** 1-based column of the first token. */
readonly col: number;
readonly tokens: readonly Token[];
readonly children: LineNode[];
leading?: readonly string[];
trailing?: string;
tail?: readonly string[];
}
/** The result of lexing: the top-level line forest plus the module-level tail comments
* (own-line `#` comments that fall after the last statement at column 0, owned by no block). */
export interface LexResult {
readonly roots: LineNode[];
/** Verbatim module-tail comment texts (`#` excluded), in source order. */
readonly tail: readonly string[];
}
/**
* Lex a whole document into a forest of top-level {@link LineNode}s. Blank lines are dropped
* (the canonical printer owns vertical spacing — ADR-0033). Comment lines are NOT dropped:
* an own-line `#` comment is captured as the `leading` trivia of the next code line at its
* indentation, or — when it closes a block (it is more deeply indented than the line that
* follows, or it ends the document) — as the `tail` of the block it belongs to. An inline
* `#…` comment rides its code line as `trailing`. Each code line nests under the nearest
* preceding line with strictly smaller indentation, so the tree encodes both block structure
* (a statement and its clauses) and line continuation (a deeper line under a clause).
*/
export declare function lex(src: string): LexResult;
/** Flatten a line and all its continuation descendants into a single token stream. Used
* for leaf lines (a statement header, a clause, a RISK line) where deeper-indented lines
* are continuations rather than nested statements. */
export declare function flatten(node: LineNode): Token[];
//# sourceMappingURL=lex.d.ts.map