From 0bd95f16e2af2028f0a5c9b41478bca74f16cc99 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 4 May 2017 16:18:29 +1000 Subject: Add lua_pushfstring and lua_pushvstring --- README.md | 2 -- src/lapi.js | 12 +++++++++ src/ldebug.js | 3 ++- src/lobject.js | 85 +++++++++++++++++++++++++++++++++++++++++++++++++--------- src/lua.js | 2 ++ 5 files changed, 88 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ebfb588..40ca22c 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,6 @@ - [x] ... - [ ] `lua_arith` - [ ] `lua_islightuserdata` - - [ ] `lua_pushfstring` - - [ ] `lua_pushvfstring` - [ ] `lua_register` - [ ] `lua_setallocf` - [ ] `lua_tocfunction` diff --git a/src/lapi.js b/src/lapi.js index 15cf2ef..4516fcc 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -239,6 +239,16 @@ const lua_pushstring = function (L, s) { return s; }; +const lua_pushvfstring = function (L, fmt, argp) { + assert(Array.isArray(fmt)); + return lobject.luaO_pushvfstring(L, fmt, argp); +}; + +const lua_pushfstring = function (L, fmt, ...argp) { + assert(Array.isArray(fmt)); + return lobject.luaO_pushvfstring(L, fmt, argp); +}; + const lua_pushliteral = function (L, s) { assert(typeof s === "string" || s === undefined || s === null, "lua_pushliteral expects a JS string"); @@ -1065,6 +1075,8 @@ module.exports.lua_pushlstring = lua_pushlstring; module.exports.lua_pushnil = lua_pushnil; module.exports.lua_pushnumber = lua_pushnumber; module.exports.lua_pushstring = lua_pushstring; +module.exports.lua_pushfstring = lua_pushfstring; +module.exports.lua_pushvfstring = lua_pushvfstring; module.exports.lua_pushthread = lua_pushthread; module.exports.lua_pushvalue = lua_pushvalue; module.exports.lua_rawequal = lua_rawequal; diff --git a/src/ldebug.js b/src/ldebug.js index 3bd5cf0..9c67f26 100644 --- a/src/ldebug.js +++ b/src/ldebug.js @@ -576,8 +576,9 @@ const luaG_addinfo = function(L, msg, src, line) { return L.stack[L.top - 1]; }; -const luaG_runerror = function(L, msg) { +const luaG_runerror = function(L, fmt, ...argp) { let ci = L.ci; + let msg = lobject.luaO_pushvfstring(L, fmt, argp); if (ci.callstatus & lstate.CIST_LUA) /* if Lua function, add source:line information */ luaG_addinfo(L, msg, ci.func.value.p.source, currentline(ci)); luaG_errormsg(L); diff --git a/src/lobject.js b/src/lobject.js index fe04f23..dafeb88 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -5,7 +5,9 @@ const assert = require('assert'); const defs = require('./defs.js'); const ljstype = require('./ljstype.js'); +const ldebug = require('./ldebug.js'); const luaconf = require('./luaconf.js'); +const lvm = require('./lvm.js'); const llimit = require('./llimit.js'); const CT = defs.constant_types; const char = defs.char; @@ -415,6 +417,61 @@ const luaO_utf8esc = function(x) { }; }; +const pushstr = function(L, str) { + L.stack[L.top++] = L.l_G.intern(str); +}; + +const luaO_pushvfstring = function(L, fmt, argp) { + let n = 0; + let i = 0; + let a = 0; + let e; + while (1) { + e = fmt.indexOf(char['%'], i); + if (e == -1) break; + pushstr(L, fmt.slice(i, e)); + switch(fmt[e+1]) { + case char['s']: + let s = argp[a++]; + if (s === null) s = defs.to_luastring("(null)", true) + pushstr(L, s); + break; + case char['c']: + let buff = argp[a++]; + if (ljstype.lisprint(buff)) + pushstr(L, [buff]); + else + luaO_pushfstring(L, defs.to_luastring("<\\%d>", true), buff); + break; + case char['d']: + case char['I']: + case char['f']: + pushstr(L, defs.to_luastring(''+argp[a++])); + break; + // case char['p']: + case char['U']: + pushstr(L, defs.to_luastring(String.fromCodePoint(argp[a++]))); + break; + case char['%']: + pushstr(L, char['%']); + break; + default: { + ldebug.luaG_runerror(L, defs.to_luastring("invalid option '%%%c' to 'lua_pushfstring'"), fmt[e + 1]); + } + } + n += 2; + i = e + 2; + } + pushstr(L, fmt.slice(i)); + if (n > 0) lvm.luaV_concat(L, n+1); + return L.stack[L.top-1].value; +}; + +const luaO_pushfstring = function(L, fmt, ...argp) { + return luaO_pushvfstring(L, fmt, argp); +}; + + /* ** converts an integer to a "floating point byte", represented as ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if @@ -465,16 +522,18 @@ const numarith = function(L, op, v1, v2) { } }; -module.exports.CClosure = CClosure; -module.exports.LClosure = LClosure; -module.exports.LocVar = LocVar; -module.exports.TValue = TValue; -module.exports.UTF8BUFFSZ = UTF8BUFFSZ; -module.exports.intarith = intarith; -module.exports.luaO_chunkid = luaO_chunkid; -module.exports.luaO_hexavalue = luaO_hexavalue; -module.exports.luaO_int2fb = luaO_int2fb; -module.exports.luaO_str2num = luaO_str2num; -module.exports.luaO_utf8desc = luaO_utf8desc; -module.exports.luaO_utf8esc = luaO_utf8esc; -module.exports.numarith = numarith; +module.exports.CClosure = CClosure; +module.exports.LClosure = LClosure; +module.exports.LocVar = LocVar; +module.exports.TValue = TValue; +module.exports.UTF8BUFFSZ = UTF8BUFFSZ; +module.exports.intarith = intarith; +module.exports.luaO_chunkid = luaO_chunkid; +module.exports.luaO_hexavalue = luaO_hexavalue; +module.exports.luaO_int2fb = luaO_int2fb; +module.exports.luaO_pushfstring = luaO_pushfstring; +module.exports.luaO_pushvfstring = luaO_pushvfstring; +module.exports.luaO_str2num = luaO_str2num; +module.exports.luaO_utf8desc = luaO_utf8desc; +module.exports.luaO_utf8esc = luaO_utf8esc; +module.exports.numarith = numarith; diff --git a/src/lua.js b/src/lua.js index fb8abe4..793b39a 100644 --- a/src/lua.js +++ b/src/lua.js @@ -158,6 +158,8 @@ module.exports.lua_pushlstring = lapi.lua_pushlstring; module.exports.lua_pushnil = lapi.lua_pushnil; module.exports.lua_pushnumber = lapi.lua_pushnumber; module.exports.lua_pushstring = lapi.lua_pushstring; +module.exports.lua_pushfstring = lapi.lua_pushfstring; +module.exports.lua_pushvfstring = lapi.lua_pushvfstring; module.exports.lua_pushthread = lapi.lua_pushthread; module.exports.lua_pushvalue = lapi.lua_pushvalue; module.exports.lua_rawequal = lapi.lua_rawequal; -- cgit v1.2.3-70-g09d2