summaryrefslogtreecommitdiffstats
path: root/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h
diff options
context:
space:
mode:
Diffstat (limited to 'squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h')
-rw-r--r--squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h255
1 files changed, 255 insertions, 0 deletions
diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h
new file mode 100644
index 000000000..48a909300
--- /dev/null
+++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h
@@ -0,0 +1,255 @@
+// wrapper for the Squirrel VM under Sqrat
+//
+// Copyright (c) 2011 Alston Chen
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//
+
+#if !defined(_SCRAT_VM_H_)
+#define _SCRAT_VM_H_
+
+#include <squirrel.h>
+#include <sqrat.h>
+#include <map>
+
+#include <iostream>
+#include <stdarg.h>
+
+#include <sqstdio.h>
+#include <sqstdblob.h>
+#include <sqstdmath.h>
+#include <sqstdsystem.h>
+#include <sqstdstring.h>
+
+namespace Sqrat {
+
+class SqratVM
+{
+private:
+ static std::map<HSQUIRRELVM, SqratVM*> ms_sqratVMs;
+ static void s_addVM(HSQUIRRELVM vm, SqratVM* sqratvm);
+ static void s_deleteVM(HSQUIRRELVM vm);
+ static SqratVM* s_getVM(HSQUIRRELVM vm);
+
+ HSQUIRRELVM m_vm;
+ Sqrat::RootTable* m_rootTable;
+ Sqrat::Script* m_script;
+ Sqrat::string m_lastErrorMsg;
+
+private:
+ static void printFunc(HSQUIRRELVM v, const SQChar *s, ...);
+ static SQInteger runtimeErrorHandler(HSQUIRRELVM v);
+ static void compilerErrorHandler(HSQUIRRELVM v,
+ const SQChar* desc,
+ const SQChar* source,
+ SQInteger line,
+ SQInteger column);
+public:
+ enum ERROR_STATE
+ {
+ NO_ERROR, COMPILE_ERROR, RUNTIME_ERROR
+ };
+
+ SqratVM(int initialStackSize = 1024);
+ ~SqratVM();
+
+ HSQUIRRELVM getVM() { return m_vm; }
+ Sqrat::RootTable& getRootTable() { return *m_rootTable; }
+ Sqrat::Script& getScript() { return *m_script; }
+
+ Sqrat::string getLastErrorMsg() { return m_lastErrorMsg; }
+ void setLastErrorMsg(const Sqrat::string& str) { m_lastErrorMsg = str; }
+
+ void setPrintFunc(SQPRINTFUNCTION printFunc, SQPRINTFUNCTION errFunc);
+ void setErrorHandler(SQFUNCTION runErr, SQCOMPILERERROR comErr);
+
+ ERROR_STATE doString(const Sqrat::string& str);
+ ERROR_STATE doFile(const Sqrat::string& file);
+};
+
+
+
+
+#ifdef SQUNICODE
+ #define scvprintf vwprintf
+#else
+ #define scvprintf vprintf
+#endif
+
+
+std::map<HSQUIRRELVM, SqratVM*> SqratVM::ms_sqratVMs;
+
+void SqratVM::s_addVM(HSQUIRRELVM vm, SqratVM* sqratvm)
+{
+ //TODO: use mutex to lock ms_sqratVMs
+ ms_sqratVMs.insert(std::make_pair(vm, sqratvm));
+}
+void SqratVM::s_deleteVM(HSQUIRRELVM vm)
+{
+ //TODO: use mutex to lock ms_sqratVMs
+ ms_sqratVMs.erase(vm);
+}
+SqratVM* SqratVM::s_getVM(HSQUIRRELVM vm)
+{
+ //TODO: use mutex to lock ms_sqratVMs
+ return ms_sqratVMs[vm];
+}
+
+void SqratVM::printFunc(HSQUIRRELVM v, const SQChar *s, ...)
+{
+ va_list vl;
+ va_start(vl, s);
+ scvprintf(s, vl);
+ va_end(vl);
+}
+
+SQInteger SqratVM::runtimeErrorHandler(HSQUIRRELVM v)
+{
+ const SQChar *sErr = 0;
+ if(sq_gettop(v) >= 1)
+ {
+ Sqrat::string& errStr = s_getVM(v)->m_lastErrorMsg;
+
+ if(SQ_SUCCEEDED(sq_getstring(v, 2, &sErr)))
+ {
+ //scprintf(_SC("RuntimeError: %s\n"), sErr);
+ //errStr = _SC("RuntimeError: ") + sErr;
+ errStr = sErr;
+ }
+ else
+ {
+ //scprintf(_SC("An Unknown RuntimeError Occured.\n"));
+ errStr = _SC("An Unknown RuntimeError Occured.");
+ }
+ }
+ return 0;
+}
+
+void SqratVM::compilerErrorHandler(HSQUIRRELVM v,
+ const SQChar* desc,
+ const SQChar* source,
+ SQInteger line,
+ SQInteger column)
+{
+ //scprintf(_SC("%s(%d:%d): %s\n"), source, line, column, desc);
+
+ SQChar buf[512];
+ scsprintf(buf, _SC("%s(%d:%d): %s"), source, line, column, desc);
+ s_getVM(v)->m_lastErrorMsg = buf;
+}
+
+SqratVM::SqratVM(int initialStackSize /* = 1024 */)
+ : m_vm(sq_open(initialStackSize))
+ , m_rootTable(new Sqrat::RootTable(m_vm))
+ , m_script(new Sqrat::Script(m_vm))
+ , m_lastErrorMsg()
+{
+ s_addVM(m_vm, this);
+
+ //register std libs
+ sq_pushroottable(m_vm);
+ sqstd_register_iolib(m_vm);
+ sqstd_register_bloblib(m_vm);
+ sqstd_register_mathlib(m_vm);
+ sqstd_register_systemlib(m_vm);
+ sqstd_register_stringlib(m_vm);
+ sq_pop(m_vm, 1);
+
+ setPrintFunc(printFunc, printFunc);
+ setErrorHandler(runtimeErrorHandler, compilerErrorHandler);
+}
+
+SqratVM::~SqratVM()
+{
+ s_deleteVM(m_vm);
+
+ delete m_script;
+ delete m_rootTable;
+ sq_close(m_vm);
+}
+
+void SqratVM::setPrintFunc(SQPRINTFUNCTION printFunc, SQPRINTFUNCTION errFunc)
+{
+ sq_setprintfunc(m_vm, printFunc, errFunc);
+}
+
+void SqratVM::setErrorHandler(SQFUNCTION runErr, SQCOMPILERERROR comErr)
+{
+ sq_newclosure(m_vm, runErr, 0);
+ sq_seterrorhandler(m_vm);
+
+ sq_setcompilererrorhandler(m_vm, comErr);
+}
+
+SqratVM::ERROR_STATE SqratVM::doString(const Sqrat::string& str)
+{
+ Sqrat::string msg;
+ m_lastErrorMsg.clear();
+
+ if(!m_script->CompileString(str, msg))
+ {
+ if(m_lastErrorMsg.empty())
+ {
+ m_lastErrorMsg = msg;
+ }
+ return COMPILE_ERROR;
+ }
+
+ if(!m_script->Run(msg))
+ {
+ if(m_lastErrorMsg.empty())
+ {
+ m_lastErrorMsg = msg;
+ }
+ return RUNTIME_ERROR;
+ }
+
+ return NO_ERROR;
+}
+
+SqratVM::ERROR_STATE SqratVM::doFile(const Sqrat::string& file)
+{
+ Sqrat::string msg;
+ m_lastErrorMsg.clear();
+
+ if(!m_script->CompileFile(file, msg))
+ {
+ if(m_lastErrorMsg.empty())
+ {
+ m_lastErrorMsg = msg;
+ }
+ return COMPILE_ERROR;
+ }
+
+ if(!m_script->Run(msg))
+ {
+ if(m_lastErrorMsg.empty())
+ {
+ m_lastErrorMsg = msg;
+ }
+ return RUNTIME_ERROR;
+ }
+
+ return NO_ERROR;
+}
+}
+
+#endif