diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-12-16 12:27:17 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-12-16 12:27:17 -0200 |
commit | 1a19893d6f8ee16944168a3f2c99002f70522f4c (patch) | |
tree | 7df8b9db5212a34d6206a97fdb54dccd07360d02 | |
parent | 88e23f508c5d3e3bf160febb58cd4608aa994522 (diff) | |
download | lua-1a19893d6f8ee16944168a3f2c99002f70522f4c.tar.gz lua-1a19893d6f8ee16944168a3f2c99002f70522f4c.tar.bz2 lua-1a19893d6f8ee16944168a3f2c99002f70522f4c.zip |
new "calculator mode"; no need to add '=' to print expressions
-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 | ||