CodePointSpan and qol

This commit is contained in:
Yura Dupyn 2026-04-25 01:09:15 +02:00
parent 000949f3c3
commit 8471c60967

View file

@ -8,11 +8,49 @@ export function char(c: string): CodePoint {
return c.codePointAt(0) as CodePoint; return c.codePointAt(0) as CodePoint;
} }
// Whitespace
export const NEW_LINE: CodePoint = char('\n');
export const CARRIAGE_RETURN: CodePoint = char('\r');
export const SPACE: CodePoint = char(' ');
export const TAB: CodePoint = char('\t');
// Digit Boundaries
export const DIGIT_0: CodePoint = char('0');
export const DIGIT_9: CodePoint = char('9');
export const DOT: CodePoint = char('.');
// Hex Boundaries
export const LOWERCASE_a: CodePoint = char('a');
export const UPPERCASE_A: CodePoint = char('A');
export const LOWERCASE_f: CodePoint = char('f');
export const UPPERCASE_F: CodePoint = char('F');
export const LOWERCASE_z: CodePoint = char('z');
export const UPPERCASE_Z: CodePoint = char('Z');
export function isBetween(a: CodePoint, x: CodePoint, b: CodePoint): boolean {
return a <= x && x <= b;
}
export function isDigit(x: CodePoint): boolean {
return isBetween(DIGIT_0, x, DIGIT_9);
}
export function isAlphanumeric(x: CodePoint): boolean {
return isDigit(x) || isBetween(LOWERCASE_a, x, LOWERCASE_z) || isBetween(LOWERCASE_z, x, UPPERCASE_Z);
}
export type CodePointRef = { export type CodePointRef = {
char: CodePoint, char: CodePoint,
offset: StringIndex, offset: StringIndex,
}; };
export type CodePointSpan = {
start: CodePointIndex,
end: CodePointIndex,
}
// === Source Text === // === Source Text ===
export class SourceText { export class SourceText {
readonly source: string; readonly source: string;
@ -147,6 +185,10 @@ export class SourceText {
return { index, line, column }; return { index, line, column };
} }
getSpan(span: CodePointSpan): Span {
return { start: this.getLocation(span.start), end: this.getLocation(span.end) };
}
// Creates a SourceRegion from a Span. // Creates a SourceRegion from a Span.
makeRegion(span: Span): SourceRegion { makeRegion(span: Span): SourceRegion {
// Basic validation // Basic validation
@ -202,6 +244,10 @@ export function span(start: SourceLocation, end: SourceLocation): Span {
return { start, end }; return { start, end };
} }
export function rawSpan(start: CodePointIndex, end: CodePointIndex): CodePointSpan {
return { start, end };
}
export class SourceRegion { export class SourceRegion {
constructor( constructor(
public readonly source: SourceText, public readonly source: SourceText,
@ -238,11 +284,11 @@ export class SourceRegion {
} }
toString(): string { toString(): string {
return this.source.sliceByCp(this.span.start.index, this.span.end.index); return this.stringOf(this.span);
} }
stringOf(span: Span): string { stringOf(span: Span): string {
return this.subRegion(span).toString(); return this.source.sliceByCp(span.start.index, span.end.index);
} }
// Returns a Span for the given line (1-based index). // Returns a Span for the given line (1-based index).
@ -292,24 +338,6 @@ export type SourceLocation = {
column: number; // 1-based column: number; // 1-based
} }
// Whitespace
export const NEW_LINE: CodePoint = char('\n');
export const CARRIAGE_RETURN: CodePoint = char('\r');
export const SPACE: CodePoint = char(' ');
export const TAB: CodePoint = char('\t');
// Digit Boundaries
export const DIGIT_0: CodePoint = char('0');
export const DIGIT_9: CodePoint = char('9');
export const DOT: CodePoint = char('.');
// Hex Boundaries
export const LOWERCASE_a: CodePoint = char('a');
export const UPPERCASE_A: CodePoint = char('A');
export const LOWERCASE_f: CodePoint = char('f');
export const UPPERCASE_F: CodePoint = char('F');
// === Rendering Utilities === // === Rendering Utilities ===
export type LineView = { export type LineView = {