1// Copied straight from https://www.lua.org/source/5.1/lua.c.html
2// with some of the cli stuff stripped out.
5** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
6** Lua stand-alone interpreter
7** See Copyright Notice in lua.h
24extern lua_State *pry_L;
26static const char *progname = LUA_PROGNAME;
28static void lstop(lua_State *L, lua_Debug *ar) {
29 (void)ar; /* unused arg. */
30 lua_sethook(L, NULL, 0, 0);
31 luaL_error(L, "interrupted!");
34static void laction(int i) {
35 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
36 terminate process (default action) */
37 lua_sethook(pry_L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
40static void l_message(const char *pname, const char *msg) {
42 fprintf(stderr, "%s: ", pname);
43 fprintf(stderr, "%s\n", msg);
47static int report(lua_State *L, int status) {
48 if (status && !lua_isnil(L, -1)) {
49 const char *msg = lua_tostring(L, -1);
51 msg = "(error object is not a string)";
52 l_message(progname, msg);
58static int traceback(lua_State *L) {
59 if (!lua_isstring(L, 1)) /* 'message' not a string? */
60 return 1; /* keep it intact */
61 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
62 if (!lua_istable(L, -1)) {
66 lua_getfield(L, -1, "traceback");
67 if (!lua_isfunction(L, -1)) {
71 lua_pushvalue(L, 1); /* pass error message */
72 lua_pushinteger(L, 2); /* skip this function and traceback */
73 lua_call(L, 2, 1); /* call debug.traceback */
77static int docall(lua_State *L, int narg, int clear) {
79 int base = lua_gettop(L) - narg; /* function index */
80 lua_pushcfunction(L, traceback); /* push traceback function */
81 lua_insert(L, base); /* put it under chunk and args */
82 signal(SIGINT, laction);
83 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
84 signal(SIGINT, SIG_DFL);
85 lua_remove(L, base); /* remove traceback function */
86 /* force a complete garbage collection in case of errors */
88 lua_gc(L, LUA_GCCOLLECT, 0);
92static void print_version(void) {
93 l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
96static int getargs(lua_State *L, char **argv, int n) {
101 argc++; /* count total number of arguments */
102 narg = argc - (n + 1); /* number of arguments to the script */
103 luaL_checkstack(L, narg + 3, "too many arguments to script");
104 for (i = n + 1; i < argc; i++)
105 lua_pushstring(L, argv[i]);
106 lua_createtable(L, narg, n + 1);
107 for (i = 0; i < argc; i++) {
108 lua_pushstring(L, argv[i]);
109 lua_rawseti(L, -2, i - n);
114int dostring(lua_State *L, const char *s, const char *name) {
115 int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
116 return report(L, status);
119static const char *get_prompt(lua_State *L, int firstline) {
121 lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
122 p = lua_tostring(L, -1);
124 p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
125 lua_pop(L, 1); /* remove global */
129static int incomplete(lua_State *L, int status) {
130 if (status == LUA_ERRSYNTAX) {
132 const char *msg = lua_tolstring(L, -1, &lmsg);
133 const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
134 if (strstr(msg, LUA_QL("<eof>")) == tp) {
140 return 0; /* else... */
143static int pushline(lua_State *L, int firstline) {
144 char buffer[LUA_MAXINPUT];
147 const char *prmt = get_prompt(L, firstline);
148 if (lua_readline(L, b, prmt) == 0)
149 return 0; /* no input */
151 if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */
152 b[l - 1] = '\0'; /* remove it */
153 if (firstline && b[0] == '=') /* first line starts with `=' ? */
154 lua_pushfstring(L, "return %s", b + 1); /* change it to `return' */
156 lua_pushstring(L, b);
161static int try_expression(lua_State *L) {
162 lua_pushliteral(L, "return ");
167 luaL_loadbuffer(L, lua_tostring(L, -1), lua_strlen(L, -1), "=stdin");
179static int loadline(lua_State *L) {
183 return -1; /* no input */
185 for (;;) { /* repeat until gets a complete line */
186 status = try_expression(L);
190 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
192 if (!incomplete(L, status))
193 break; /* cannot try to add lines? */
195 if (!pushline(L, 0)) /* no more input? */
197 lua_pushliteral(L, "\n"); /* add a new line... */
198 lua_insert(L, -2); /* ...between the two lines */
199 lua_concat(L, 3); /* join them */
203 lua_remove(L, 1); /* remove line */
207void dotty(lua_State *L) {
209 const char *oldprogname = progname;
211 while ((status = loadline(L)) != -1) {
213 status = docall(L, 0, 0);
215 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
216 lua_getglobal(L, "print");
218 if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0)
220 lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
221 lua_tostring(L, -1)));
224 lua_settop(L, 0); /* clear stack */
227 progname = oldprogname;
230int handle_script(lua_State *L, char **argv, int n) {
233 int narg = getargs(L, argv, n); /* collect arguments */
234 lua_setglobal(L, "arg");
236 if (strcmp(fname, "-") == 0 && strcmp(argv[n - 1], "--") != 0)
237 fname = NULL; /* stdin */
238 status = luaL_loadfile(L, fname);
239 lua_insert(L, -(narg + 1));
241 status = docall(L, narg, 0);
244 return report(L, status);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list