#define lbaselib_c
#define LUA_LIB
#include "lprefix.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static
int
luaB_print (lua_State *L) {
int
n = marpa_lua_gettop(L);
int
i;
marpa_lua_getglobal(L,
"tostring"
);
for
(i=1; i<=n; i++) {
const
char
*s;
size_t
l;
marpa_lua_pushvalue(L, -1);
marpa_lua_pushvalue(L, i);
marpa_lua_call(L, 1, 1);
s = marpa_lua_tolstring(L, -1, &l);
if
(s == NULL)
return
marpa_luaL_error(L,
"'tostring' must return a string to 'print'"
);
if
(i>1) marpa_lua_writestring(
"\t"
, 1);
marpa_lua_writestring(s, l);
marpa_lua_pop(L, 1);
}
marpa_lua_writeline();
return
0;
}
#define SPACECHARS " \f\n\r\t\v"
static
const
char
*b_str2int (
const
char
*s,
int
base, lua_Integer *pn) {
lua_Unsigned n = 0;
int
neg = 0;
s +=
strspn
(s, SPACECHARS);
if
(*s ==
'-'
) { s++; neg = 1; }
else
if
(*s ==
'+'
) s++;
if
(!
isalnum
((unsigned
char
)*s))
return
NULL;
do
{
int
digit = (
isdigit
((unsigned
char
)*s)) ? *s -
'0'
: (
toupper
((unsigned
char
)*s) -
'A'
) + 10;
if
(digit >= base)
return
NULL;
n = n * base + digit;
s++;
}
while
(
isalnum
((unsigned
char
)*s));
s +=
strspn
(s, SPACECHARS);
*pn = (lua_Integer)((neg) ? (0u - n) : n);
return
s;
}
static
int
luaB_tonumber (lua_State *L) {
if
(marpa_lua_isnoneornil(L, 2)) {
marpa_luaL_checkany(L, 1);
if
(marpa_lua_type(L, 1) == LUA_TNUMBER) {
marpa_lua_settop(L, 1);
return
1;
}
else
{
size_t
l;
const
char
*s = marpa_lua_tolstring(L, 1, &l);
if
(s != NULL && marpa_lua_stringtonumber(L, s) == l + 1)
return
1;
}
}
else
{
size_t
l;
const
char
*s;
lua_Integer n = 0;
lua_Integer base = marpa_luaL_checkinteger(L, 2);
marpa_luaL_checktype(L, 1, LUA_TSTRING);
s = marpa_lua_tolstring(L, 1, &l);
marpa_luaL_argcheck(L, 2 <= base && base <= 36, 2,
"base out of range"
);
if
(b_str2int(s, (
int
)base, &n) == s + l) {
marpa_lua_pushinteger(L, n);
return
1;
}
}
marpa_lua_pushnil(L);
return
1;
}
static
int
luaB_error (lua_State *L) {
int
level = (
int
)marpa_luaL_optinteger(L, 2, 1);
marpa_lua_settop(L, 1);
if
(marpa_lua_isstring(L, 1) && level > 0) {
marpa_luaL_where(L, level);
marpa_lua_pushvalue(L, 1);
marpa_lua_concat(L, 2);
}
return
marpa_lua_error(L);
}
static
int
luaB_getmetatable (lua_State *L) {
marpa_luaL_checkany(L, 1);
if
(!marpa_lua_getmetatable(L, 1)) {
marpa_lua_pushnil(L);
return
1;
}
marpa_luaL_getmetafield(L, 1,
"__metatable"
);
return
1;
}
static
int
luaB_setmetatable (lua_State *L) {
int
t = marpa_lua_type(L, 2);
marpa_luaL_checktype(L, 1, LUA_TTABLE);
marpa_luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected"
);
if
(marpa_luaL_getmetafield(L, 1,
"__metatable"
) != LUA_TNIL)
return
marpa_luaL_error(L,
"cannot change a protected metatable"
);
marpa_lua_settop(L, 2);
marpa_lua_setmetatable(L, 1);
return
1;
}
static
int
luaB_rawequal (lua_State *L) {
marpa_luaL_checkany(L, 1);
marpa_luaL_checkany(L, 2);
marpa_lua_pushboolean(L, marpa_lua_rawequal(L, 1, 2));
return
1;
}
static
int
luaB_rawlen (lua_State *L) {
int
t = marpa_lua_type(L, 1);
marpa_luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
"table or string expected"
);
marpa_lua_pushinteger(L, marpa_lua_rawlen(L, 1));
return
1;
}
static
int
luaB_rawget (lua_State *L) {
marpa_luaL_checktype(L, 1, LUA_TTABLE);
marpa_luaL_checkany(L, 2);
marpa_lua_settop(L, 2);
marpa_lua_rawget(L, 1);
return
1;
}
static
int
luaB_rawset (lua_State *L) {
marpa_luaL_checktype(L, 1, LUA_TTABLE);
marpa_luaL_checkany(L, 2);
marpa_luaL_checkany(L, 3);
marpa_lua_settop(L, 3);
marpa_lua_rawset(L, 1);
return
1;
}
static
int
luaB_collectgarbage (lua_State *L) {
static
const
char
*
const
opts[] = {
"stop"
,
"restart"
,
"collect"
,
"count"
,
"step"
,
"setpause"
,
"setstepmul"
,
"isrunning"
, NULL};
static
const
int
optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCISRUNNING};
int
o = optsnum[marpa_luaL_checkoption(L, 1,
"collect"
, opts)];
int
ex = (
int
)marpa_luaL_optinteger(L, 2, 0);
int
res = marpa_lua_gc(L, o, ex);
switch
(o) {
case
LUA_GCCOUNT: {
int
b = marpa_lua_gc(L, LUA_GCCOUNTB, 0);
marpa_lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
return
1;
}
case
LUA_GCSTEP:
case
LUA_GCISRUNNING: {
marpa_lua_pushboolean(L, res);
return
1;
}
default
: {
marpa_lua_pushinteger(L, res);
return
1;
}
}
}
static
int
luaB_type (lua_State *L) {
int
t = marpa_lua_type(L, 1);
marpa_luaL_argcheck(L, t != LUA_TNONE, 1,
"value expected"
);
marpa_lua_pushstring(L, marpa_lua_typename(L, t));
return
1;
}
static
int
pairsmeta (lua_State *L,
const
char
*method,
int
iszero,
lua_CFunction iter) {
if
(marpa_luaL_getmetafield(L, 1, method) == LUA_TNIL) {
marpa_luaL_checktype(L, 1, LUA_TTABLE);
marpa_lua_pushcfunction(L, iter);
marpa_lua_pushvalue(L, 1);
if
(iszero) marpa_lua_pushinteger(L, 0);
else
marpa_lua_pushnil(L);
}
else
{
marpa_lua_pushvalue(L, 1);
marpa_lua_call(L, 1, 3);
}
return
3;
}
static
int
luaB_next (lua_State *L) {
marpa_luaL_checktype(L, 1, LUA_TTABLE);
marpa_lua_settop(L, 2);
if
(marpa_lua_next(L, 1))
return
2;
else
{
marpa_lua_pushnil(L);
return
1;
}
}
static
int
luaB_pairs (lua_State *L) {
return
pairsmeta(L,
"__pairs"
, 0, luaB_next);
}
static
int
ipairsaux (lua_State *L) {
lua_Integer i = marpa_luaL_checkinteger(L, 2) + 1;
marpa_lua_pushinteger(L, i);
return
(marpa_lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
static
int
luaB_ipairs (lua_State *L) {
#if defined(LUA_COMPAT_IPAIRS)
return
pairsmeta(L,
"__ipairs"
, 1, ipairsaux);
#else
marpa_luaL_checkany(L, 1);
marpa_lua_pushcfunction(L, ipairsaux);
marpa_lua_pushvalue(L, 1);
marpa_lua_pushinteger(L, 0);
return
3;
#endif
}
static
int
load_aux (lua_State *L,
int
status,
int
envidx) {
if
(status == LUA_OK) {
if
(envidx != 0) {
marpa_lua_pushvalue(L, envidx);
if
(!marpa_lua_setupvalue(L, -2, 1))
marpa_lua_pop(L, 1);
}
return
1;
}
else
{
marpa_lua_pushnil(L);
marpa_lua_insert(L, -2);
return
2;
}
}
static
int
luaB_loadfile (lua_State *L) {
const
char
*fname = marpa_luaL_optstring(L, 1, NULL);
const
char
*mode = marpa_luaL_optstring(L, 2, NULL);
int
env = (!marpa_lua_isnone(L, 3) ? 3 : 0);
int
status = marpa_luaL_loadfilex(L, fname, mode);
return
load_aux(L, status, env);
}
#define RESERVEDSLOT 5
static
const
char
*generic_reader (lua_State *L,
void
*ud,
size_t
*size) {
(
void
)(ud);
marpa_luaL_checkstack(L, 2,
"too many nested functions"
);
marpa_lua_pushvalue(L, 1);
marpa_lua_call(L, 0, 1);
if
(marpa_lua_isnil(L, -1)) {
marpa_lua_pop(L, 1);
*size = 0;
return
NULL;
}
else
if
(!marpa_lua_isstring(L, -1))
marpa_luaL_error(L,
"reader function must return a string"
);
marpa_lua_replace(L, RESERVEDSLOT);
return
marpa_lua_tolstring(L, RESERVEDSLOT, size);
}
static
int
luaB_load (lua_State *L) {
int
status;
size_t
l;
const
char
*s = marpa_lua_tolstring(L, 1, &l);
const
char
*mode = marpa_luaL_optstring(L, 3,
"bt"
);
int
env = (!marpa_lua_isnone(L, 4) ? 4 : 0);
if
(s != NULL) {
const
char
*chunkname = marpa_luaL_optstring(L, 2, s);
status = marpa_luaL_loadbufferx(L, s, l, chunkname, mode);
}
else
{
const
char
*chunkname = marpa_luaL_optstring(L, 2,
"=(load)"
);
marpa_luaL_checktype(L, 1, LUA_TFUNCTION);
marpa_lua_settop(L, RESERVEDSLOT);
status = marpa_lua_load(L, generic_reader, NULL, chunkname, mode);
}
return
load_aux(L, status, env);
}
static
int
dofilecont (lua_State *L,
int
d1, lua_KContext d2) {
(
void
)d1; (
void
)d2;
return
marpa_lua_gettop(L) - 1;
}
static
int
luaB_dofile (lua_State *L) {
const
char
*fname = marpa_luaL_optstring(L, 1, NULL);
marpa_lua_settop(L, 1);
if
(marpa_luaL_loadfile(L, fname) != LUA_OK)
return
marpa_lua_error(L);
marpa_lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
return
dofilecont(L, 0, 0);
}
static
int
luaB_assert (lua_State *L) {
if
(marpa_lua_toboolean(L, 1))
return
marpa_lua_gettop(L);
else
{
marpa_luaL_checkany(L, 1);
marpa_lua_remove(L, 1);
marpa_lua_pushliteral(L,
"assertion failed!"
);
marpa_lua_settop(L, 1);
return
luaB_error(L);
}
}
static
int
luaB_select (lua_State *L) {
int
n = marpa_lua_gettop(L);
if
(marpa_lua_type(L, 1) == LUA_TSTRING && *marpa_lua_tostring(L, 1) ==
'#'
) {
marpa_lua_pushinteger(L, n-1);
return
1;
}
else
{
lua_Integer i = marpa_luaL_checkinteger(L, 1);
if
(i < 0) i = n + i;
else
if
(i > n) i = n;
marpa_luaL_argcheck(L, 1 <= i, 1,
"index out of range"
);
return
n - (
int
)i;
}
}
static
int
finishpcall (lua_State *L,
int
status, lua_KContext extra) {
if
(status != LUA_OK && status != LUA_YIELD) {
marpa_lua_pushboolean(L, 0);
marpa_lua_pushvalue(L, -2);
return
2;
}
else
return
marpa_lua_gettop(L) - (
int
)extra;
}
static
int
luaB_pcall (lua_State *L) {
int
status;
marpa_luaL_checkany(L, 1);
marpa_lua_pushboolean(L, 1);
marpa_lua_insert(L, 1);
status = marpa_lua_pcallk(L, marpa_lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
return
finishpcall(L, status, 0);
}
static
int
luaB_xpcall (lua_State *L) {
int
status;
int
n = marpa_lua_gettop(L);
marpa_luaL_checktype(L, 2, LUA_TFUNCTION);
marpa_lua_pushboolean(L, 1);
marpa_lua_pushvalue(L, 1);
marpa_lua_rotate(L, 3, 2);
status = marpa_lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
return
finishpcall(L, status, 2);
}
static
int
luaB_tostring (lua_State *L) {
marpa_luaL_checkany(L, 1);
marpa_luaL_tolstring(L, 1, NULL);
return
1;
}
static
const
luaL_Reg base_funcs[] = {
{
"assert"
, luaB_assert},
{
"collectgarbage"
, luaB_collectgarbage},
{
"dofile"
, luaB_dofile},
{
"error"
, luaB_error},
{
"getmetatable"
, luaB_getmetatable},
{
"ipairs"
, luaB_ipairs},
{
"loadfile"
, luaB_loadfile},
{
"load"
, luaB_load},
#if defined(LUA_COMPAT_LOADSTRING)
{
"loadstring"
, luaB_load},
#endif
{
"next"
, luaB_next},
{
"pairs"
, luaB_pairs},
{
"pcall"
, luaB_pcall},
{
"print"
, luaB_print},
{
"rawequal"
, luaB_rawequal},
{
"rawlen"
, luaB_rawlen},
{
"rawget"
, luaB_rawget},
{
"rawset"
, luaB_rawset},
{
"select"
, luaB_select},
{
"setmetatable"
, luaB_setmetatable},
{
"tonumber"
, luaB_tonumber},
{
"tostring"
, luaB_tostring},
{
"type"
, luaB_type},
{
"xpcall"
, luaB_xpcall},
{
"_G"
, NULL},
{
"_VERSION"
, NULL},
{NULL, NULL}
};
LUAMOD_API
int
marpa_luaopen_base (lua_State *L) {
marpa_lua_pushglobaltable(L);
marpa_luaL_setfuncs(L, base_funcs, 0);
marpa_lua_pushvalue(L, -1);
marpa_lua_setfield(L, -2,
"_G"
);
marpa_lua_pushliteral(L, LUA_VERSION);
marpa_lua_setfield(L, -2,
"_VERSION"
);
return
1;
}