Compare commits

...

4 Commits

@ -79,6 +79,18 @@ console.log(helloStr)
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
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 { getLibOS } from './lib/os'
import { getLibPackage } from './lib/package'
import { LuaType, ensureArray, Config } from './utils'
import { LuaType, ensureArray, Config, hasOwnProperty } from './utils'
import { parse as parseScript } from './parser'
interface Script {
@ -56,6 +56,7 @@ function createEnv(
parse: (script: string) => Script
parseFile: (path: string) => Script
loadLib: (name: string, value: Table) => void
extendLib: (name: string, value: Table) => void
} {
const cfg: Config = {
LUA_PATH: './?.lua',
@ -77,6 +78,24 @@ function createEnv(
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('package', libPackage)
loadLib('math', libMath)
@ -105,7 +124,8 @@ function createEnv(
return {
parse,
parseFile,
loadLib
loadLib,
extendLib
}
}

@ -1,7 +1,15 @@
import { sprintf } from 'printj'
import { Table } from '../Table'
import { LuaError } from '../LuaError'
import { tostring, posrelat, coerceArgToNumber, coerceArgToString, hasOwnProperty, LuaType } from '../utils'
import {
coerceArgToBoolean,
coerceArgToNumber,
coerceArgToString,
hasOwnProperty,
LuaType,
posrelat,
tostring
} from '../utils'
const ROSETTA_STONE: Record<string, string> = {
'([^a-zA-Z0-9%(])-': '$1*?',
@ -117,7 +125,7 @@ function find(s: LuaType, pattern: LuaType, init: LuaType, plain: LuaType): (num
const S = coerceArgToString(s, 'find', 1)
const P = coerceArgToString(pattern, 'find', 2)
const INIT = init === undefined ? 1 : coerceArgToNumber(init, 'find', 3)
const PLAIN = plain === undefined ? false : coerceArgToNumber(plain, 'find', 4)
const PLAIN = plain === undefined ? false : coerceArgToBoolean(plain, 'find', 4)
// Regex
if (!PLAIN) {

@ -160,7 +160,7 @@ function coerceToString(val: LuaType, errorMessage?: string): string {
function coerceArg<T>(
value: LuaType,
coerceFunc: (val: LuaType, errorMessage?: string) => T,
typ: 'number' | 'string',
typ: 'number' | 'string' | 'boolean',
funcName: string,
index: number
): T {
@ -175,6 +175,10 @@ function coerceArgToString(value: LuaType, funcName: string, index: number): str
return coerceArg<string>(value, coerceToString, 'string', funcName, index)
}
function coerceArgToBoolean(value: LuaType, funcName: string, index: number): boolean {
return coerceArg<boolean>(value, coerceToBoolean, 'boolean', funcName, index)
}
function coerceArgToTable(value: LuaType, funcName: string, index: number): Table {
if (value instanceof Table) {
return value
@ -207,6 +211,7 @@ export {
coerceToBoolean,
coerceToNumber,
coerceToString,
coerceArgToBoolean,
coerceArgToNumber,
coerceArgToString,
coerceArgToTable,

@ -101,6 +101,13 @@ b = string.find(a, 'The .* fox')
assertTrue (b == 1, 'The dot pattern should match across lines in string.find()')
local ok, plainFind = pcall(function () return string.find('abc', 'a.c', 1, true) end)
assertTrue (ok and plainFind == nil, 'string.find() should accept a boolean plain argument and disable pattern matching')
local literalFind = string.find('a.c', 'a.c', 1, true)
assertTrue (literalFind == 1, 'string.find() should find literal matches when plain is true')
-- format

@ -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()
let str

Loading…
Cancel
Save