Shrimp.run accepts locals

This commit is contained in:
Chris Wanstrath 2025-11-05 14:01:00 -08:00
parent a535dc9605
commit 600330ba7f
2 changed files with 26 additions and 2 deletions

View File

@ -17,18 +17,21 @@ export class Shrimp {
this.globals = globals this.globals = globals
} }
async run(code: string | Bytecode): Promise<any> { async run(code: string | Bytecode, locals?: Record<string, any>): Promise<any> {
let bytecode let bytecode
if (typeof code === 'string') { if (typeof code === 'string') {
const compiler = new Compiler(code, Object.keys(Object.assign({}, shrimpGlobals, this.globals ?? {}))) const compiler = new Compiler(code, Object.keys(Object.assign({}, shrimpGlobals, this.globals ?? {}, locals ?? {})))
bytecode = compiler.bytecode bytecode = compiler.bytecode
} else { } else {
bytecode = code bytecode = code
} }
if (locals) this.vm.pushScope(locals)
this.vm.appendBytecode(bytecode) this.vm.appendBytecode(bytecode)
await this.vm.continue() await this.vm.continue()
if (locals) this.vm.popScope()
return this.vm.stack.length ? fromValue(this.vm.stack.at(-1)!) : null return this.vm.stack.length ? fromValue(this.vm.stack.at(-1)!) : null
} }

View File

@ -29,5 +29,26 @@ describe('Shrimp', () => {
await shrimp.run('abc = hiya') await shrimp.run('abc = hiya')
expect(shrimp.get('abc')).toEqual('hey there') expect(shrimp.get('abc')).toEqual('hey there')
expect(await shrimp.run('type abc')).toEqual('string') expect(await shrimp.run('type abc')).toEqual('string')
// still there
expect(await shrimp.run('hiya')).toEqual('hey there')
})
test('allows setting your own locals', async () => {
const shrimp = new Shrimp({ 'my-global': () => 'hey there' })
await shrimp.run('abc = my-global')
expect(shrimp.get('abc')).toEqual('hey there')
await shrimp.run('abc = my-global', { 'my-global': 'now a local' })
expect(shrimp.get('abc')).toEqual('now a local')
const shrimp2 = new Shrimp()
await shrimp.run('abc = nothing')
expect(shrimp.get('abc')).toEqual('nothing')
await shrimp.run('abc = nothing', { nothing: 'something' })
expect(shrimp.get('abc')).toEqual('something')
await shrimp.run('abc = nothing')
expect(shrimp.get('abc')).toEqual('nothing')
}) })
}) })