summaryrefslogtreecommitdiff
path: root/tests/manual-tests/lua-cli.js
blob: b71a576dac992d170c18e5ab25557436c0ac1350 (plain)
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 */
}