fix fromValue

This commit is contained in:
Chris Wanstrath 2025-11-07 21:50:01 -08:00
parent da0af799d8
commit 3aa40ae2c2
2 changed files with 7 additions and 13 deletions

View File

@ -1,5 +1,5 @@
import { readFileSync } from 'fs' import { readFileSync } from 'fs'
import { VM, fromValue, toValue, type Bytecode } from 'reefvm' import { VM, fromValue, toValue, isValue, type Bytecode } from 'reefvm'
import { type Tree } from '@lezer/common' import { type Tree } from '@lezer/common'
import { Compiler } from '#compiler/compiler' import { Compiler } from '#compiler/compiler'
import { parser } from '#parser/shrimp' import { parser } from '#parser/shrimp'
@ -11,7 +11,7 @@ export { parser } from '#parser/shrimp'
export { globals as prelude } from '#prelude' export { globals as prelude } from '#prelude'
export type { Tree } from '@lezer/common' export type { Tree } from '@lezer/common'
export { type Value, type Bytecode } from 'reefvm' export { type Value, type Bytecode } from 'reefvm'
export { toValue, fromValue, Scope, VM, bytecodeToString } from 'reefvm' export { toValue, fromValue, isValue, Scope, VM, bytecodeToString } from 'reefvm'
export class Shrimp { export class Shrimp {
vm: VM vm: VM
@ -25,7 +25,7 @@ export class Shrimp {
get(name: string): any { get(name: string): any {
const value = this.vm.scope.get(name) const value = this.vm.scope.get(name)
return value ? fromValue(value) : null return value ? fromValue(value, this.vm) : null
} }
set(name: string, value: any) { set(name: string, value: any) {
@ -38,12 +38,7 @@ export class Shrimp {
async call(name: string, ...args: any[]): Promise<any> { async call(name: string, ...args: any[]): Promise<any> {
const result = await this.vm.call(name, ...args) const result = await this.vm.call(name, ...args)
// vm.call() returns Value for native functions, JS values for Reef functions return isValue(result) ? fromValue(result, this.vm) : result
// Check if it's a Value object and unwrap if needed
if (result && typeof result === 'object' && 'type' in result) {
return fromValue(result)
}
return result
} }
parse(code: string): Tree { parse(code: string): Tree {
@ -54,7 +49,6 @@ export class Shrimp {
return compileCode(code, this.globals) return compileCode(code, this.globals)
} }
async run(code: string | Bytecode, locals?: Record<string, any>): Promise<any> { async run(code: string | Bytecode, locals?: Record<string, any>): Promise<any> {
let bytecode let bytecode
@ -70,7 +64,7 @@ export class Shrimp {
await this.vm.continue() await this.vm.continue()
if (locals) this.vm.popScope() 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)!, this.vm) : null
} }
} }
@ -87,7 +81,7 @@ export async function runCode(code: string, globals?: Record<string, any>): Prom
export async function runBytecode(bytecode: Bytecode, globals?: Record<string, any>): Promise<any> { export async function runBytecode(bytecode: Bytecode, globals?: Record<string, any>): Promise<any> {
const vm = new VM(bytecode, Object.assign({}, shrimpGlobals, globals)) const vm = new VM(bytecode, Object.assign({}, shrimpGlobals, globals))
await vm.run() await vm.run()
return vm.stack.length ? fromValue(vm.stack[vm.stack.length - 1]!) : null return vm.stack.length ? fromValue(vm.stack[vm.stack.length - 1]!, vm) : null
} }
export function compileFile(path: string, globals?: Record<string, any>): Bytecode { export function compileFile(path: string, globals?: Record<string, any>): Bytecode {

View File

@ -136,7 +136,7 @@ describe('Shrimp', () => {
const shrimp = new Shrimp() const shrimp = new Shrimp()
await shrimp.run(`greet = do name: await shrimp.run(`greet = do name:
concat 'Hello ' name str.join [ 'Hello ' name ] ''
end`) end`)
const result = await shrimp.call('greet', { name: 'World' }) const result = await shrimp.call('greet', { name: 'World' })