diff options
| -rw-r--r-- | lua.c | 58 |
1 files changed, 40 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.207 2013/10/07 14:20:31 roberto Exp roberto $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -257,45 +257,67 @@ static int incomplete (lua_State *L, int status) { | |||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | 259 | ||
| 260 | /* prompt the user, read a line, and push it into the Lua stack */ | ||
| 260 | static int pushline (lua_State *L, int firstline) { | 261 | static int pushline (lua_State *L, int firstline) { |
| 261 | char buffer[LUA_MAXINPUT]; | 262 | char buffer[LUA_MAXINPUT]; |
| 262 | char *b = buffer; | 263 | char *b = buffer; |
| 263 | size_t l; | 264 | size_t l; |
| 264 | const char *prmt = get_prompt(L, firstline); | 265 | const char *prmt = get_prompt(L, firstline); |
| 265 | int readstatus = lua_readline(L, b, prmt); | 266 | int readstatus = lua_readline(L, b, prmt); |
| 266 | lua_pop(L, 1); /* remove result from 'get_prompt' */ | ||
| 267 | if (readstatus == 0) | 267 | if (readstatus == 0) |
| 268 | return 0; /* no input */ | 268 | return 0; /* no input (prompt will be popped by caller) */ |
| 269 | lua_pop(L, 1); /* remove prompt */ | ||
| 269 | l = strlen(b); | 270 | l = strlen(b); |
| 270 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ | 271 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ |
| 271 | b[l-1] = '\0'; /* remove it */ | 272 | b[l-1] = '\0'; /* remove it */ |
| 272 | if (firstline && b[0] == '=') /* first line starts with `=' ? */ | 273 | lua_pushstring(L, b); /* save line in Lua */ |
| 273 | lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ | ||
| 274 | else | ||
| 275 | lua_pushstring(L, b); | ||
| 276 | lua_freeline(L, b); | 274 | lua_freeline(L, b); |
| 277 | return 1; | 275 | return 1; |
| 278 | } | 276 | } |
| 279 | 277 | ||
| 280 | 278 | ||
| 281 | static int loadline (lua_State *L) { | 279 | /* try to compile line on the stack as 'return <line>'; on return, stack |
| 280 | has either compiled chunk or original line (if compilation failed) */ | ||
| 281 | static int addreturn (lua_State *L) { | ||
| 282 | int status; | 282 | int status; |
| 283 | lua_settop(L, 0); | 283 | size_t len; const char *line; |
| 284 | if (!pushline(L, 1)) | 284 | lua_pushliteral(L, "return "); |
| 285 | return -1; /* no input */ | 285 | lua_pushvalue(L, -2); /* duplicate line */ |
| 286 | lua_concat(L, 2); /* new line is "return ..." */ | ||
| 287 | line = lua_tolstring(L, -1, &len); | ||
| 288 | if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) | ||
| 289 | lua_remove(L, -3); /* remove original line */ | ||
| 290 | else | ||
| 291 | lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */ | ||
| 292 | return status; | ||
| 293 | } | ||
| 294 | |||
| 295 | |||
| 296 | /* read multiple lines until a complete line */ | ||
| 297 | static int multiline (lua_State *L) { | ||
| 286 | for (;;) { /* repeat until gets a complete line */ | 298 | for (;;) { /* repeat until gets a complete line */ |
| 287 | size_t l; | 299 | size_t len; |
| 288 | const char *line = lua_tolstring(L, 1, &l); | 300 | const char *line = lua_tolstring(L, 1, &len); /* get what it has */ |
| 289 | status = luaL_loadbuffer(L, line, l, "=stdin"); | 301 | int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ |
| 290 | if (!incomplete(L, status)) break; /* cannot try to add lines? */ | 302 | if (!incomplete(L, status) || !pushline(L, 0)) |
| 291 | if (!pushline(L, 0)) /* no more input? */ | 303 | return status; /* cannot/should not try to add continuation line */ |
| 292 | return -1; | 304 | lua_pushliteral(L, "\n"); /* add newline... */ |
| 293 | lua_pushliteral(L, "\n"); /* add a new line... */ | ||
| 294 | lua_insert(L, -2); /* ...between the two lines */ | 305 | lua_insert(L, -2); /* ...between the two lines */ |
| 295 | lua_concat(L, 3); /* join them */ | 306 | lua_concat(L, 3); /* join them */ |
| 296 | } | 307 | } |
| 308 | } | ||
| 309 | |||
| 310 | |||
| 311 | static int loadline (lua_State *L) { | ||
| 312 | int status; | ||
| 313 | lua_settop(L, 0); | ||
| 314 | if (!pushline(L, 1)) | ||
| 315 | return -1; /* no input */ | ||
| 316 | if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ | ||
| 317 | status = multiline(L); /* try as command, maybe with continuation lines */ | ||
| 297 | lua_saveline(L, 1); | 318 | lua_saveline(L, 1); |
| 298 | lua_remove(L, 1); /* remove line */ | 319 | lua_remove(L, 1); /* remove line */ |
| 320 | lua_assert(lua_gettop(L) == 1); | ||
| 299 | return status; | 321 | return status; |
| 300 | } | 322 | } |
| 301 | 323 | ||
