summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-12-16 12:27:17 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-12-16 12:27:17 -0200
commit1a19893d6f8ee16944168a3f2c99002f70522f4c (patch)
tree7df8b9db5212a34d6206a97fdb54dccd07360d02
parent88e23f508c5d3e3bf160febb58cd4608aa994522 (diff)
downloadlua-1a19893d6f8ee16944168a3f2c99002f70522f4c.tar.gz
lua-1a19893d6f8ee16944168a3f2c99002f70522f4c.tar.bz2
lua-1a19893d6f8ee16944168a3f2c99002f70522f4c.zip
new "calculator mode"; no need to add '=' to print expressions
-rw-r--r--lua.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/lua.c b/lua.c
index 267e42e4..70f7cc24 100644
--- a/lua.c
+++ b/lua.c
@@ -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 */
260static int pushline (lua_State *L, int firstline) { 261static 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
281static 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) */
281static 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 */
297static 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
311static 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