summaryrefslogtreecommitdiff
path: root/src/luascript.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/luascript.cc')
-rw-r--r--src/luascript.cc283
1 files changed, 283 insertions, 0 deletions
diff --git a/src/luascript.cc b/src/luascript.cc
new file mode 100644
index 0000000..1699cdf
--- /dev/null
+++ b/src/luascript.cc
@@ -0,0 +1,283 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * luascript.cc
+ *
+ * Tue Jan 10 14:43:39 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pracro is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "luascript.h"
+
+// For atoi
+#include <stdlib.h>
+
+//#include "luautil.h"
+
+#define GLOBAL_POINTER "_pracroGlobalLUAObjectPointerThisShouldBeANameThatIsNotAccidentallyOverwritten"
+
+#define DEBUG(x, fmt...) printf(fmt)
+#define ERR(x, fmt...) printf(fmt)
+
+static int _debug(lua_State *L)
+{/*
+ Pracro::checkParameters(L,
+ Pracro::T_STRING,
+ Pracro::T_END);
+ */
+ std::string msg = lua_tostring(L, lua_gettop(L));
+
+ printf("%s\n", msg.c_str());
+
+ return 0;
+}
+
+static int _forward(lua_State *L)
+{/*
+ Pracro::checkParameters(L,
+ Pracro::T_STRING,
+ Pracro::T_END);
+ */
+ int x = lua_tonumber(L, lua_gettop(L));
+
+ printf("forward %d\n", x);
+
+ lua_getglobal(L, GLOBAL_POINTER);
+ LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L));
+
+ if(!lua) {
+ lua_pushstring(L, "No LUA pointer!");
+ lua_error(L);
+ return 1;
+ }
+
+ lua->out->forward(x * 5);
+
+ return 0;
+}
+
+static int _turn(lua_State *L)
+{/*
+ Pracro::checkParameters(L,
+ Pracro::T_STRING,
+ Pracro::T_END);
+ */
+ int x = lua_tonumber(L, lua_gettop(L));
+
+ printf("turn %d\n", x);
+
+ lua_getglobal(L, GLOBAL_POINTER);
+ LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L));
+
+ if(!lua) {
+ lua_pushstring(L, "No LUA pointer!");
+ lua_error(L);
+ return 1;
+ }
+
+ lua->out->turn(-x);
+
+ return 0;
+}
+
+static int _reset(lua_State *L)
+{/*
+ Pracro::checkParameters(L,
+ Pracro::T_STRING,
+ Pracro::T_END);
+ */
+
+ printf("reset\n");
+
+ lua_getglobal(L, GLOBAL_POINTER);
+ LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L));
+
+ if(!lua) {
+ lua_pushstring(L, "No LUA pointer!");
+ lua_error(L);
+ return 1;
+ }
+
+ lua->out->reset();
+
+ return 0;
+}
+
+LUAScript::LUAScript(OutputWindow *o)
+{
+ DEBUG(luascript, "LUAScript()\n");
+ L = NULL;
+ out = o;
+}
+
+LUAScript::~LUAScript()
+{
+ if(L) {
+ free(L);
+ L = NULL;
+ }
+ DEBUG(luascript, "~LUAScript()\n");
+}
+
+void LUAScript::init()
+ throw(Exception)
+{
+ if(L) return;
+
+ L = luaL_newstate();
+ if(L == NULL) {
+ ERR(luascript, "Could not create LUA state.\n");
+ throw Exception("Could not create LUA state.");
+ }
+
+ luaL_openlibs(L);
+
+ lua_pushlightuserdata(L, this); // Push the pointer to 'this' instance
+ lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var.
+
+ lua_register(L, "debug", _debug);
+ lua_register(L, "fremad", _forward);
+ lua_register(L, "drej", _turn);
+ lua_register(L, "reset", _reset);
+
+ connect(&watcher, SIGNAL(fileChanged(const QString &)),
+ this, SLOT(reload()));
+}
+
+void LUAScript::addFile(std::string src)
+{
+ file = src.c_str();
+ FILE *fp = fopen(src.c_str(), "r");
+ if(fp) {
+ char buf[64];
+ size_t sz;
+ std::string inc;
+ while((sz = fread(buf, 1, sizeof(buf), fp)) != 0) {
+ inc.append(buf, sz);
+ }
+ fclose(fp);
+ addCode(inc, src);
+ }
+
+ watcher.addPath(file);
+}
+
+void LUAScript::reload()
+{
+ printf("Reload\n");
+ // luaL_error(L, "Terminated due to reload.");
+ // runScript();
+}
+
+void LUAScript::addCode(std::string c, std::string name)
+{
+ scripts.push_back(std::make_pair(c, name));
+}
+
+void LUAScript::run()
+{
+ /*
+ while(true) {
+ printf("."); fflush(stdout);
+ }
+ */
+ try {
+ runScript();
+ } catch(Exception &e) {
+ printf("LUA Error: %s\n", e.msg.c_str());
+ }
+}
+
+void LUAScript::runScript()
+ throw(Exception)
+{
+ try {
+ init();
+ } catch(Exception &e) {
+ throw Exception(e.msg);
+ }
+
+ if(L == NULL) {
+ ERR(luascript, "LUA state not initialized!");
+ return;
+ }
+
+ top = lua_gettop(L);
+
+ std::vector<std::pair<std::string, std::string> >::iterator i =
+ scripts.begin();
+ while(i != scripts.end()) {
+ std::string program = i->first;
+ std::string codename = name();
+ if(i->second != "") codename += ": " + i->second;
+
+ DEBUG(luascript, "Running %s: %s\n", codename.c_str(), program.c_str());
+
+ if(luaL_loadbuffer(L, program.c_str(), program.size(), codename.c_str())) {
+ ERR(luascript, "loadbuffer: %s\n", lua_tostring(L, lua_gettop(L)));
+ throw Exception(lua_tostring(L, lua_gettop(L)));
+ }
+
+ // Run the loaded code
+ if(lua_pcall(L, 0, LUA_MULTRET, 0)) {
+ ERR(luascript, "pcall: %s\n" , lua_tostring(L, lua_gettop(L)));
+ throw Exception(lua_tostring(L, lua_gettop(L)));
+ }
+
+ i++;
+ }
+}
+
+std::string LUAScript::resultString() throw(Exception)
+{
+ if(top != lua_gettop(L) - 1) {
+ ERR(luascript, "Program did not return a single value.\n");
+ throw Exception("Program did not return a single value.");
+ }
+
+ if(lua_isstring(L, lua_gettop(L)) == false) {
+ ERR(luascript, "Program did not return a string value.\n");
+ throw Exception("Program did not return a string value.");
+ }
+
+ std::string res = lua_tostring(L, lua_gettop(L));
+ lua_pop(L, 1);
+
+ return res;
+}
+
+#ifdef TEST_LUASCRIPT
+//Additional dependency files
+//deps:
+//Required cflags (autoconf vars may be used)
+//cflags:
+//Required link options (autoconf vars may be used)
+//libs:
+#include "test.h"
+
+TEST_BEGIN;
+
+// TODO: Put some testcode here (see test.h for usable macros).
+TEST_TRUE(false, "No tests yet!");
+
+TEST_END;
+
+#endif/*TEST_LUASCRIPT*/