export class CGError extends Error { line?: number; column?: number; source?: string; errorType: 'RuntimeError' | 'ParseError'; constructor( message: string, line?: number, column?: number, source?: string, errorType: 'RuntimeError' | 'ParseError' = 'RuntimeError' ) { super(message); this.name = errorType; this.line = line; this.column = column; this.source = source; this.errorType = errorType; } format(): string { if (this.line === undefined || this.column === undefined || !this.source) { return `${this.name}: ${this.message}`; } const lines = this.source.split('\n'); const errorLine = lines[this.line - 1]; if (!errorLine) { return `${this.name}: ${this.message} at line ${this.line}, column ${this.column}`; } const lineNumStr = `${this.line}`; const padding = ' '.repeat(lineNumStr.length); const pointer = ' '.repeat(this.column - 1) + '^'; return `${this.name}: ${this.message}\n\n ${lineNumStr} | ${errorLine}\n${padding} | ${pointer}`; } } export function RuntimeError(message: string, line?: number, column?: number, source?: string) { return new CGError(message, line, column, source, 'RuntimeError'); } export function ParseError(message: string, line?: number, column?: number, source?: string) { return new CGError(message, line, column, source, 'ParseError'); }