diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index b7ff47476..a53bd45d5 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -64,6 +64,11 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector st.setglobal("WINDOWS"); #endif + st.getglobal("Console"); + st.getfield("println"); + st.setglobal("print"); + st.pop(); + commands.push_back(PluginCommand("dfusion","Run dfusion system (interactive i.e. can input further commands).",dfusion,true)); commands.push_back(PluginCommand("dfuse","Init dfusion system (not interactive).",dfuse,false)); commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run,true)); @@ -115,27 +120,74 @@ void InterpreterLoop(color_ostream &out) DFHack::CommandHistory hist; lua::state s=lua::glua::Get(); string curline; - out.print("Type quit to exit interactive mode\n"); + out.print("Type quit to exit interactive mode.\n" + "Shortcuts:\n" + " '= foo' => '_1,_2,... = foo'\n" + " '! foo' => 'print(foo)'\n"); assert(out.is_console()); Console &con = static_cast(out); - con.lineedit(">>",curline,hist); + int vcnt = 1; + + s.settop(0); + + for (;;) { + con.lineedit("[lua]# ",curline,hist); + + if (curline.empty()) + continue; + if (curline == "quit") + break; - while (curline!="quit") { hist.add(curline); + try { - s.loadstring(curline); - s.pcall(); + if (curline[0] == '=') + { + curline = "return " + curline.substr(1); + + s.loadstring(curline); + s.pcall(0, LUA_MULTRET); + int numret = s.gettop(); + + for (int i = 1; i <= numret; i++) + { + if (i == 1) + { + s.pushvalue(i); + s.setglobal("_"); + } + + std::string name = stl_sprintf("_%d", vcnt++); + s.pushvalue(i); + s.setglobal(name); + + con.print("%s = ", name.c_str()); + s.getglobal("print"); + s.pushvalue(i); + s.pcall(1,0); + } + } + else if (curline[0] == '!') + { + curline = "print(" + curline.substr(1) + ")"; + s.loadstring(curline); + s.pcall(); + } + else + { + s.loadstring(curline); + s.pcall(); + } } catch(lua::exception &e) { con.printerr("Error:%s\n",e.what()); con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); - s.settop(0); } - con.lineedit(">>",curline,hist); + + s.settop(0); } - s.settop(0); } command_result lua_run_file (color_ostream &out, std::vector ¶meters) { diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index aaf2677fc..9ec8baf2e 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -1,6 +1,3 @@ -function print(msg) - Console.print(msg.."\n") -end function err(msg) --make local maybe... print(msg) print(debug.traceback()) diff --git a/plugins/Dfusion/src/lua_Console.cpp b/plugins/Dfusion/src/lua_Console.cpp index 4f0d62f12..2a8222af2 100644 --- a/plugins/Dfusion/src/lua_Console.cpp +++ b/plugins/Dfusion/src/lua_Console.cpp @@ -1,4 +1,7 @@ #include "lua_Console.h" + +#include + //TODO error management. Using lua error? or something other? static DFHack::color_ostream* GetConsolePtr(lua::state &st) { @@ -9,22 +12,53 @@ static DFHack::color_ostream* GetConsolePtr(lua::state &st) st.settop(t); return c; } + +static std::string lua_print_fmt(lua_State *L) +{ + /* Copied from lua source to fully replicate builtin print */ + int n = lua_gettop(L); /* number of arguments */ + lua_getglobal(L, "tostring"); + + std::stringstream ss; + + for (int i=1; i<=n; i++) { + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + const char *s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + luaL_error(L, "tostring must return a string to print"); + if (i>1) + ss << '\t'; + ss << s; + lua_pop(L, 1); /* pop result */ + } + + return ss.str(); +} + static int lua_Console_print(lua_State *S) { - lua::state st(S); - int t=st.gettop(); - DFHack::color_ostream* c=GetConsolePtr(st); - c->print("%s",st.as(t).c_str()); - return 0; + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->print("%s", lua_print_fmt(S).c_str()); + return 0; +} + +static int lua_Console_println(lua_State *S) +{ + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->print("%s\n", lua_print_fmt(S).c_str()); + return 0; } static int lua_Console_printerr(lua_State *S) { - lua::state st(S); - int t=st.gettop(); - DFHack::color_ostream* c=GetConsolePtr(st); - c->printerr("%s",st.as(t).c_str()); - return 0; + lua::state st(S); + DFHack::color_ostream* c=GetConsolePtr(st); + c->printerr("%s", lua_print_fmt(S).c_str()); + return 0; } static int lua_Console_clear(lua_State *S) @@ -123,6 +157,7 @@ static int lua_Console_lineedit(lua_State *S) const luaL_Reg lua_console_func[]= { {"print",lua_Console_print}, + {"println",lua_Console_println}, {"printerr",lua_Console_printerr}, {"clear",lua_Console_clear}, {"gotoxy",lua_Console_gotoxy},