diff --git a/src/index.ts b/src/index.ts index 963ba25..3a91bed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,18 +17,21 @@ export class Shrimp { this.globals = globals } - async run(code: string | Bytecode): Promise { + async run(code: string | Bytecode, locals?: Record): Promise { let bytecode 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 } else { bytecode = code } + if (locals) this.vm.pushScope(locals) this.vm.appendBytecode(bytecode) await this.vm.continue() + if (locals) this.vm.popScope() + return this.vm.stack.length ? fromValue(this.vm.stack.at(-1)!) : null } diff --git a/src/tests/shrimp.test.ts b/src/tests/shrimp.test.ts index 2713f3e..d8ddb7d 100644 --- a/src/tests/shrimp.test.ts +++ b/src/tests/shrimp.test.ts @@ -29,5 +29,26 @@ describe('Shrimp', () => { await shrimp.run('abc = hiya') expect(shrimp.get('abc')).toEqual('hey there') 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') }) }) \ No newline at end of file