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
129
|
#!/usr/bin/env node
"use strict";
const lua = require('../../src/lua.js');
const lapi = require('../../src/lapi.js');
const lauxlib = require('../../src/lauxlib.js');
const linit = require('../../src/linit.js');
const fs = require('fs');
const readlineSync = require('readline-sync');
const stdin = lua.to_luastring("=stdin");
const _PROMPT = lua.to_luastring("_PROMPT");
const _PROMPT2 = lua.to_luastring("_PROMPT2");
const report = function(L, status) {
if (status !== lua.thread_status.LUA_OK) {
lauxlib.lua_writestringerror(`${lapi.lua_tojsstring(L, -1)}\n`);
lapi.lua_pop(L, 1);
}
return status;
};
const docall = function(L, narg, nres) {
let status = lapi.lua_pcall(L, narg, nres, 0);
return status;
};
const dochunk = function(L, status) {
if (status === lua.thread_status.LUA_OK) {
status = docall(L, 0, 0);
}
return report(L, status);
};
const dofile = function(L, name) {
return dochunk(L, lauxlib.luaL_loadfile(L, lua.to_luastring(name)));
};
const dostring = function(L, s, name) {
let buffer = lua.to_luastring(s);
return dochunk(L, lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring(name)));
};
const L = lauxlib.luaL_newstate();
let script = 2; // Where to start args from
linit.luaL_openlibs(L);
/* create 'arg' table */
lapi.lua_createtable(L, process.argv.length - (script + 1), script + 1);
for (let i = 0; i < process.argv.length; i++) {
lapi.lua_pushliteral(L, process.argv[i]);
lapi.lua_seti(L, -2, i - script); /* TODO: rawseti */
}
lapi.lua_setglobal(L, lua.to_luastring("arg"));
{
let name = "LUA_INIT"+lua.LUA_VERSUFFIX;
let init = process.env[name];
if (!init) {
name = "LUA_INIT";
init = process.env[name];
}
if (init) {
let status;
if (init[0] === '@') {
status = dofile(L, init.substring(1));
} else {
status = dostring(L, init, name);
}
if (status !== lua.thread_status.LUA_OK) {
return process.exit(1);
}
}
}
console.log(lua.FENGARI_COPYRIGHT);
for (;;) {
lapi.lua_getglobal(L, _PROMPT);
let input = readlineSync.prompt({
prompt: lapi.lua_tojsstring(L, -1) || '> '
});
lapi.lua_pop(L, 1);
if (input.length === 0)
continue;
let status;
{
let buffer = lua.to_luastring("return " + input);
status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
}
if (status !== lua.thread_status.LUA_OK) {
lapi.lua_pop(L, 1);
let buffer = lua.to_luastring(input);
if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin) === lua.thread_status.LUA_OK) {
status = lua.thread_status.LUA_OK;
}
}
while (status === lua.thread_status.LUA_ERRSYNTAX && lapi.lua_tojsstring(L, -1).endsWith("<eof>")) {
/* continuation */
lapi.lua_pop(L, 1);
lapi.lua_getglobal(L, _PROMPT2);
input += "\n" + readlineSync.prompt({
prompt: lapi.lua_tojsstring(L, -1) || '>> '
});
lapi.lua_pop(L, 1);
let buffer = lua.to_luastring(input);
status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
}
if (status === lua.thread_status.LUA_OK) {
status = docall(L, 0, lua.LUA_MULTRET);
}
if (status === lua.thread_status.LUA_OK) {
let n = lapi.lua_gettop(L);
if (n > 0) { /* any result to be printed? */
lapi.lua_getglobal(L, lua.to_luastring("print"));
lapi.lua_insert(L, 1);
if (lapi.lua_pcall(L, n, 0, 0) != lua.thread_status.LUA_OK) {
lauxlib.lua_writestringerror(`error calling 'print' (${lapi.lua_tojsstring(L, -1)})\n`);
}
}
} else {
report(L, status);
}
lapi.lua_settop(L, 0); /* remove eventual returns */
}
|