add Shrimp class as a nicer way to run code

This commit is contained in:
Chris Wanstrath 2025-11-05 13:33:32 -08:00
parent 5f46346213
commit 0e96911879
2 changed files with 49 additions and 0 deletions

View File

@ -7,6 +7,34 @@ export { Compiler } from '#compiler/compiler'
export { parser } from '#parser/shrimp' export { parser } from '#parser/shrimp'
export { globals } from '#prelude' export { globals } from '#prelude'
export class Shrimp {
vm: VM
constructor() {
this.vm = new VM({ instructions: [], constants: [], labels: new Map() }, shrimpGlobals)
}
async run(code: string | Bytecode): Promise<any> {
let bytecode
if (typeof code === 'string') {
const compiler = new Compiler(code, Object.keys(shrimpGlobals))
bytecode = compiler.bytecode
} else {
bytecode = code
}
this.vm.appendBytecode(bytecode)
await this.vm.continue()
return this.vm.stack.length ? fromValue(this.vm.stack.at(-1)!) : null
}
get(name: string): any {
const value = this.vm.scope.get(name)
return value ? fromValue(value) : null
}
}
export async function runFile(path: string, globals?: Record<string, any>): Promise<any> { export async function runFile(path: string, globals?: Record<string, any>): Promise<any> {
const code = readFileSync(path, 'utf-8') const code = readFileSync(path, 'utf-8')
return await runCode(code, globals) return await runCode(code, globals)

21
src/tests/shrimp.test.ts Normal file
View File

@ -0,0 +1,21 @@
import { describe } from 'bun:test'
import { expect, test } from 'bun:test'
import { Shrimp } from '..'
describe('Shrimp', () => {
test('allows running Shrimp code', async () => {
const shrimp = new Shrimp()
expect(await shrimp.run(`1 + 5`)).toEqual(6)
await shrimp.run(`abc = true`)
expect(shrimp.get('abc')).toEqual(true)
await shrimp.run(`name = Bob`)
expect(shrimp.get('abc')).toEqual(true)
expect(shrimp.get('name')).toEqual('Bob')
await shrimp.run(`abc = false`)
expect(shrimp.get('abc')).toEqual(false)
})
})