1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/* jshint esversion: 6 */
"use strict";
const assert = require('assert');
const lua = require('./lua.js');
const lapi = require('./lapi.js');
const lauxlib = require('./lauxlib.js');
const CT = lua.constant_types;
const luaB_print = function(L) {
let n = lapi.lua_gettop(L); /* number of arguments */
let str = "";
lapi.lua_getglobal(L, "tostring");
for (let i = 1; i <= n; i++) {
lapi.lua_pushvalue(L, -1); /* function to be called */
lapi.lua_pushvalue(L, i); /* value to print */
lapi.lua_call(L, 1, 1);
let s = lapi.lua_tolstring(L, -1);
if (s === null)
return lauxlib.luaL_error(L, "'tostring' must return a string to 'print'");
if (i > 1) s = `\t${s}`;
str = `${str}${s}`;
lapi.lua_pop(L, 1);
}
console.log(str);
return 0;
};
const luaB_tostring = function(L) {
lauxlib.luaL_checkany(L, 1);
lauxlib.luaL_tolstring(L, 1);
return 1;
};
const luaB_getmetatable = function(L) {
lauxlib.luaL_checkany(L, 1);
if (!lapi.lua_getmetatable(L, 1)) {
lapi.lua_pushnil(L);
return 1; /* no metatable */
}
lauxlib.luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */
};
const luaB_setmetatable = function(L) {
let t = lapi.lua_type(L, 2);
lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE);
lauxlib.luaL_argcheck(L, t === CT.LUA_TNIL || t === CT.LUA_TTABLE, 2, "nil or table expected");
if (lauxlib.luaL_getmetafield(L, 1, "__metatable") !== CT.LUA_TNIL)
return lauxlib.luaL_error(L, "cannot change a protected metatable");
lapi.lua_settop(L, 2);
lapi.lua_setmetatable(L, 1);
return 1;
};
const luaB_rawequal = function(L) {
lauxlib.luaL_checkany(L, 1);
lauxlib.luaL_checkany(L, 2);
lapi.lua_pushboolean(L, lapi.lua_rawequal(L, 1, 2));
return 1;
};
const luaB_rawget = function(L) {
lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE);
lauxlib.luaL_checkany(L, 2);
lapi.lua_settop(L, 2);
lapi.lua_rawget(L, 1);
return 1;
};
const luaB_rawset = function(L) {
lauxlib.luaL_checktype(L, 1, CT.LUA_TTABLE);
lauxlib.luaL_checkany(L, 2);
lauxlib.luaL_checkany(L, 3);
lapi.lua_settop(L, 3);
lapi.lua_rawset(L, 1);
return 1;
};
const luaB_type = function(L) {
let t = lapi.lua_type(L, 1);
lauxlib.luaL_argcheck(L, t != CT.LUA_TNONE, 1, "value expected");
lapi.lua_pushstring(L, lapi.lua_typename(L, t));
return 1;
};
const luaB_error = function(L) {
let level = lauxlib.luaL_optinteger(L, 2, 1);
lapi.lua_settop(L, 1);
if (lapi.lua_type(L, 1) === CT.LUA_TSTRING && level > 0) {
lauxlib.luaL_where(L, level); /* add extra information */
lapi.lua_pushvalue(L, 1);
lapi.lua_concat(L, 2);
}
return lapi.lua_error(L);
};
const base_funcs = {
"collectgarbage": function () {},
"print": luaB_print,
"tostring": luaB_tostring,
"getmetatable": luaB_getmetatable,
"setmetatable": luaB_setmetatable,
"rawequal": luaB_rawequal,
"rawset": luaB_rawset,
"rawget": luaB_rawget,
"type": luaB_type,
"error": luaB_error
};
const luaopen_base = function(L) {
/* open lib into global table */
lapi.lua_pushglobaltable(L);
lauxlib.luaL_setfuncs(L, base_funcs, 0);
/* set global _G */
lapi.lua_pushvalue(L, -1);
lapi.lua_setfield(L, -2, "_G");
/* set global _VERSION */
lapi.lua_pushliteral(L, lua.LUA_VERSION);
lapi.lua_setfield(L, -2, "_VERSION");
return 1;
};
module.exports.luaopen_base = luaopen_base;
|