summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md23
-rw-r--r--src/lapi.js3
-rw-r--r--src/lauxlib.js13
-rw-r--r--src/ldo.js2
-rw-r--r--src/linit.js8
-rw-r--r--src/lstate.js1
-rw-r--r--src/lstrlib.js22
-rw-r--r--tests/lstrlib.js81
8 files changed, 138 insertions, 15 deletions
diff --git a/README.md b/README.md
index 2cd5d93..a6e11df 100644
--- a/README.md
+++ b/README.md
@@ -146,12 +146,14 @@
- [x] luaL_argcheck
- [x] luaL_argerror
- [x] luaL_buffinit
+ - [x] luaL_buffinitsize
- [x] luaL_callmeta
- [x] luaL_checkany
- [x] luaL_checkinteger
- [x] luaL_checklstring
- [x] luaL_checknumber
- [x] luaL_checkstack
+ - [x] luaL_checkstring
- [x] luaL_checktype
- [x] luaL_error
- [x] luaL_getmetafield
@@ -166,6 +168,7 @@
- [x] luaL_opt
- [x] luaL_optinteger
- [x] luaL_optlstring
+ - [x] luaL_prepbuffsize
- [x] luaL_pushresult
- [x] luaL_requiref
- [x] luaL_setfuncs
@@ -174,9 +177,7 @@
- [x] luaL_where
- [ ] luaL_addchar
- [ ] luaL_addsize
- - [ ] luaL_buffinitsize
- [ ] luaL_checkoption
- - [ ] luaL_checkstring
- [ ] luaL_checkudata
- [ ] luaL_checkversion
- [ ] luaL_dofile
@@ -192,7 +193,6 @@
- [ ] luaL_optnumber
- [ ] luaL_optstring
- [ ] luaL_prepbuffer
- - [ ] luaL_prepbuffsize
- [ ] luaL_pushresultsize
- [ ] luaL_ref
- [ ] luaL_setmetatable
@@ -209,6 +209,23 @@
- [x] Table
- [x] Math
- [ ] String
+ - [x] string.char
+ - [x] string.len
+ - [ ] string.byte
+ - [ ] string.dump
+ - [ ] string.find
+ - [ ] string.format
+ - [ ] string.gmatch
+ - [ ] string.gsub
+ - [ ] string.lower
+ - [ ] string.match
+ - [ ] string.pack
+ - [ ] string.packsize
+ - [ ] string.rep
+ - [ ] string.reverse
+ - [ ] string.sub
+ - [ ] string.unpack
+ - [ ] string.upper
- [ ] Package
- [ ] os
- [ ] io
diff --git a/src/lapi.js b/src/lapi.js
index dae533d..2fbd777 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -226,8 +226,7 @@ const lua_pushlstring = function(L, s, len) { // TODO: embedded \0
};
const lua_pushstring = function (L, s) {
- assert(typeof s === "string");
- if (!s)
+ if (typeof s !== "string")
L.stack[L.top] = ldo.nil;
else {
let ts = new TValue(CT.LUA_TLNGSTR, s);
diff --git a/src/lauxlib.js b/src/lauxlib.js
index 5223b9b..e3afa60 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -159,7 +159,7 @@ const luaL_checktype = function(L, arg, t) {
};
const luaL_checkstring = function(L, n) {
- luaL_checklstring(L, n, null);
+ return luaL_checklstring(L, n, null);
};
const luaL_checklstring = function(L, arg) {
@@ -201,11 +201,20 @@ const luaL_optinteger = function(L, arg, def) {
return luaL_opt(L, luaL_checkinteger, arg, def);
};
+const luaL_prepbuffsize = function(B, sz) {
+ return B;
+};
+
const luaL_buffinit = function(L, B) {
B.L = L;
B.b = "";
};
+const luaL_buffinitsize = function(L, B, sz) {
+ luaL_buffinit(L, B);
+ return B;
+};
+
const luaL_addlstring = function(B, s) {
B.b += s;
};
@@ -392,6 +401,7 @@ module.exports.luaL_addvalue = luaL_addvalue;
module.exports.luaL_argcheck = luaL_argcheck;
module.exports.luaL_argerror = luaL_argerror;
module.exports.luaL_buffinit = luaL_buffinit;
+module.exports.luaL_buffinitsize = luaL_buffinitsize;
module.exports.luaL_callmeta = luaL_callmeta;
module.exports.luaL_checkany = luaL_checkany;
module.exports.luaL_checkinteger = luaL_checkinteger;
@@ -413,6 +423,7 @@ module.exports.luaL_opt = luaL_opt;
module.exports.luaL_optinteger = luaL_optinteger;
module.exports.luaL_optlstring = luaL_optlstring;
module.exports.luaL_optstring = luaL_optstring;
+module.exports.luaL_prepbuffsize = luaL_prepbuffsize;
module.exports.luaL_pushresult = luaL_pushresult;
module.exports.luaL_requiref = luaL_requiref;
module.exports.luaL_setfuncs = luaL_setfuncs;
diff --git a/src/ldo.js b/src/ldo.js
index 1d5c81b..e9bc9eb 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -521,7 +521,7 @@ class SParser {
}
const checkmode = function(L, mode, x) {
- if (mode && mode.indexOf(x.charAt(0))) {
+ if (mode && mode.indexOf(x.charAt(0)) !== -1) {
lapi.lua_pushstring(L, `attempt to load a ${x} chunk (mode is '${mode}')`);
luaD_throw(L, TS.LUA_ERRSYNTAX);
}
diff --git a/src/linit.js b/src/linit.js
index b926683..f9f8296 100644
--- a/src/linit.js
+++ b/src/linit.js
@@ -4,16 +4,18 @@ const assert = require('assert');
const lapi = require('./lapi.js');
const lauxlib = require('./lauxlib.js');
-const lualib = require('./lualib.js');
const lbaselib = require('./lbaselib.js');
const lcorolib = require('./lcorolib.js');
-const ltablib = require('./ltablib.js');
const lmathlib = require('./lmathlib.js');
+const lstrlib = require('./lstrlib.js');
+const ltablib = require('./ltablib.js');
+const lualib = require('./lualib.js');
const loadedlibs = {
+ [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine,
[lualib.LUA_MATHLIBNAME]: lmathlib.luaopen_math,
+ [lualib.LUA_STRLIBNAME]: lstrlib.luaopen_string,
[lualib.LUA_TABLIBNAME]: ltablib.luaopen_table,
- [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine,
"_G": lbaselib.luaopen_base
};
diff --git a/src/lstate.js b/src/lstate.js
index 29bf186..2e6ebbe 100644
--- a/src/lstate.js
+++ b/src/lstate.js
@@ -111,7 +111,6 @@ const f_luaopen = function(L) {
let g = L.l_G;
stack_init(L, L);
init_registry(L, g);
- // TODO: luaS_init(L);
luaT_init(L);
g.version = lapi.lua_version(null);
};
diff --git a/src/lstrlib.js b/src/lstrlib.js
index 194d6ba..69f634d 100644
--- a/src/lstrlib.js
+++ b/src/lstrlib.js
@@ -9,13 +9,25 @@ const CT = lua.constant_types;
const TS = lua.thread_status;
const str_len = function(L) {
- lauxlib.luaL_checkstring(L, 1);
- lapi.lua_pushinteger(L, lapi.lua_tostring(L, 1).length);
+ lapi.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length);
+ return 1;
+};
+
+const str_char = function(L) {
+ let n = lapi.lua_gettop(L); /* number of arguments */
+ let p = "";
+ for (let i = 1; i <= n; i++) {
+ let c = lauxlib.luaL_checkinteger(L, i);
+ lauxlib.luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean
+ p += String.fromCharCode(c);
+ }
+ lapi.lua_pushstring(L, p);
return 1;
};
const strlib = {
- "len": str_len
+ "len": str_len,
+ "char": str_char
};
const createmetatable = function(L) {
@@ -33,4 +45,6 @@ const luaopen_string = function(L) {
lauxlib.luaL_newlib(L, strlib);
createmetatable(L);
return 1;
-}; \ No newline at end of file
+};
+
+module.exports.luaopen_string = luaopen_string; \ No newline at end of file
diff --git a/tests/lstrlib.js b/tests/lstrlib.js
new file mode 100644
index 0000000..494b881
--- /dev/null
+++ b/tests/lstrlib.js
@@ -0,0 +1,81 @@
+"use strict";
+
+const test = require('tape');
+const beautify = require('js-beautify').js_beautify;
+
+const tests = require("./tests.js");
+const toByteCode = tests.toByteCode;
+
+const lapi = require("../src/lapi.js");
+const lauxlib = require("../src/lauxlib.js");
+const linit = require('../src/linit.js');
+
+
+test('string.len', function (t) {
+ let luaCode = `
+ local a = "world"
+ return string.len("hello"), a:len()
+ `, L;
+
+ t.plan(4);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lauxlib.luaL_loadstring(L, luaCode);
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tointeger(L, -2),
+ 5,
+ "Correct element(s) on the stack"
+ );
+
+ t.strictEqual(
+ lapi.lua_tointeger(L, -1),
+ 5,
+ "Correct element(s) on the stack"
+ );
+
+});
+
+
+test('string.char', function (t) {
+ let luaCode = `
+ return string.char(104, 101, 108, 108, 111)
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lauxlib.luaL_loadstring(L, luaCode);
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tostring(L, -1),
+ "hello",
+ "Correct element(s) on the stack"
+ );
+}); \ No newline at end of file