feat: support extending loaded libs

pull/31/head
Piotr 3 months ago
parent d121e74c6f
commit d5a3a50d27

@ -79,6 +79,18 @@ console.log(helloStr)
Check out the [math lib](./src/lib/math.ts) for a more extensive example. Check out the [math lib](./src/lib/math.ts) for a more extensive example.
### Extend a library
Use `extendLib` to add new functions to an existing library without overwriting it.
```js
const extraMath = new luainjs.Table({ tau: Math.PI * 2 })
luaEnv.extendLib('math', extraMath)
const tau = luaEnv.parse('return math.tau').exec()
console.log(tau)
```
## Example ## Example
Check out the [test runner](./tests/test.js) for a concrete example. Check out the [test runner](./tests/test.js) for a concrete example.

@ -10,7 +10,7 @@ import { libTable } from './lib/table'
import { libString, metatable as stringMetatable } from './lib/string' import { libString, metatable as stringMetatable } from './lib/string'
import { getLibOS } from './lib/os' import { getLibOS } from './lib/os'
import { getLibPackage } from './lib/package' import { getLibPackage } from './lib/package'
import { LuaType, ensureArray, Config } from './utils' import { LuaType, ensureArray, Config, hasOwnProperty } from './utils'
import { parse as parseScript } from './parser' import { parse as parseScript } from './parser'
interface Script { interface Script {
@ -56,6 +56,7 @@ function createEnv(
parse: (script: string) => Script parse: (script: string) => Script
parseFile: (path: string) => Script parseFile: (path: string) => Script
loadLib: (name: string, value: Table) => void loadLib: (name: string, value: Table) => void
extendLib: (name: string, value: Table) => void
} { } {
const cfg: Config = { const cfg: Config = {
LUA_PATH: './?.lua', LUA_PATH: './?.lua',
@ -77,6 +78,24 @@ function createEnv(
loaded.rawset(name, value) loaded.rawset(name, value)
} }
const extendLib = (name: string, value: Table): void => {
const lib = _G.rawget(name)
if (lib instanceof Table) {
for (let i = 1; i < value.numValues.length; i++) {
if (hasOwnProperty(value.numValues, i)) lib.rawset(i, value.numValues[i])
}
for (const key in value.strValues) {
if (hasOwnProperty(value.strValues, key)) lib.rawset(key, value.strValues[key])
}
for (let i = 0; i < value.keys.length; i++) {
lib.rawset(value.keys[i], value.values[i])
}
return
}
loadLib(name, value)
}
loadLib('_G', _G) loadLib('_G', _G)
loadLib('package', libPackage) loadLib('package', libPackage)
loadLib('math', libMath) loadLib('math', libMath)
@ -105,7 +124,8 @@ function createEnv(
return { return {
parse, parse,
parseFile, parseFile,
loadLib loadLib,
extendLib
} }
} }

@ -41,6 +41,16 @@ let exitCode = 0
} }
} }
{
const luaEnv = luainjs.createEnv()
const ext = new luainjs.Table({ foo: () => 'bar' })
luaEnv.extendLib('math', ext)
const val = luaEnv.parse('return math.foo()').exec()
if (val !== 'bar') {
throw Error('extendLib failed!')
}
}
{ {
const luaEnv = luainjs.createEnv() const luaEnv = luainjs.createEnv()
let str let str

Loading…
Cancel
Save