[WIP] Start implementing support for history

This commit is contained in:
Garrett Mills 2026-02-10 07:25:55 -06:00
parent 06ff1b396f
commit 390a6280c2

View File

@ -53,6 +53,12 @@ export class Scope {
makeChild(): Scope {
return new Scope(this)
}
clone(): Scope {
const s = new Scope
s.entries = {...this.entries}
return s
}
}
/**
@ -81,11 +87,31 @@ export type TermOperator = {
}
export class ExecutionContext {
private history: [StrRVal, Scope][] = []
constructor(
private subject: StrRVal,
private scope: Scope,
) {}
public pushHistory() {
this.history.push([this.subject, this.scope.clone()])
}
public restoreHistory() {
const [subject, scope] = this.popHistory()
this.subject = subject
this.scope = scope
}
public popHistory(): [StrRVal, Scope] {
const state = this.history.pop()
if ( !state ) {
throw new Error('No history to undo')
}
return state
}
async replaceSubject(operator: (sub: StrRVal) => Awaitable<StrRVal>) {
this.subject = await operator(this.subject)
}
@ -201,7 +227,14 @@ export class StrVM {
) {}
public async runInPlace<TReturn>(operator: (ctx: ExecutionContext) => Awaitable<TReturn>): Promise<TReturn> {
return operator(this.context)
this.context.pushHistory()
try {
return await operator(this.context)
} catch (e: unknown) {
// If we got an error, return to the previous state:
this.context.restoreHistory()
throw e
}
}
public async tapInPlace(operator: (ctx: ExecutionContext) => Awaitable<unknown>): Promise<this> {