summaryrefslogtreecommitdiff
path: root/plugins/Dfusion
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-03-30 11:57:27 +0400
committerAlexander Gavrilov2012-03-30 11:57:27 +0400
commite989ca58db10b644bfe1f05d7d2f851c4d943deb (patch)
treed98945fb748e68e2409c60f644589792e81d872d /plugins/Dfusion
parent81bc73f435ce4d5a609304c322c55d4053bcde91 (diff)
downloaddfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.gz
dfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.bz2
dfhack-e989ca58db10b644bfe1f05d7d2f851c4d943deb.tar.xz
Enhance the interactive interpreter mode of dfusion.
1. Reimplement Console.print* to behave exactly as the standard print function, and apply print = Console.println from c++ init code. 2. Add a couple of convenience shortcuts to save some manual typing when poking around data structures using the interactive prompt. 3. Change the prompt string to a more distinguished shape.
Diffstat (limited to 'plugins/Dfusion')
-rw-r--r--plugins/Dfusion/dfusion.cpp68
-rw-r--r--plugins/Dfusion/luafiles/init.lua3
-rw-r--r--plugins/Dfusion/src/lua_Console.cpp55
3 files changed, 105 insertions, 21 deletions
diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp
index b7ff4747..a53bd45d 100644
--- a/plugins/Dfusion/dfusion.cpp
+++ b/plugins/Dfusion/dfusion.cpp
@@ -64,6 +64,11 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
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 <filename>' to run <filename> 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<Console&>(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 <std::string> &parameters)
{
diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua
index aaf2677f..9ec8baf2 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 4f0d62f1..2a8222af 100644
--- a/plugins/Dfusion/src/lua_Console.cpp
+++ b/plugins/Dfusion/src/lua_Console.cpp
@@ -1,4 +1,7 @@
#include "lua_Console.h"
+
+#include <sstream>
+
//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<string>(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<string>(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},