import { Parser, Input, Output, subinput } from '../parser'; import { always } from '../control/state'; interface Memory { readonly SID: number; readonly source: string; readonly position: number; readonly offset: number; readonly linebreak: number; readonly range: number; } export class Scope { constructor(input: I) { this.inputs.push(input); } private readonly inputs: I[] = []; private readonly memories: Memory[] = []; public peek(): I { //assert(this.inputs.length > 0); return this.inputs.at(-1)!; } public focus(subsource: string): void { const input = this.peek(); assert(subsource.length <= input.source.length); assert(input.position - subsource.length >= 0); input.position -= subsource.length; const { SID, source, position, offset, linebreak, range } = input; this.memories.push({ SID, source, position, offset, linebreak, range, }); subinput(subsource, input); } public unfocus(state = true, continuous = false): void { assert(this.memories.length > 0); const input = this.peek(); const { source, position } = input; const memory = this.memories.pop()!; input.SID = memory.SID; input.position = state ? continuous && position > 0 ? memory.position + position : memory.position + source.length : memory.position; input.source = memory.source; assert(position <= source.length); input.offset = memory.offset; input.linebreak = memory.linebreak; input.range = memory.range; } public push(source: string): I { const input = this.peek().clone(source); this.inputs.push(input); return input; } public pop(): I { this.inputs.pop(); return this.peek(); } } export function scope
( conv: (input: Parser.Input
, output: Output