From 181e7eb298baae6d054d1d7cd6d725f4973f455a Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 12 Nov 2022 22:18:49 +0800 Subject: [PATCH] add exports --- src/compiler.h | 6 +++--- src/main.cpp | 31 ++++++------------------------- src/obj.h | 2 +- src/pocketpy.h | 41 +++++++++++++++++++++++++++++++++-------- src/repl.h | 10 +++++----- src/vm.h | 16 ++++++++-------- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index c6055b7a..36e13cc9 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -899,12 +899,12 @@ _Code compile(VM* vm, const char* source, _Str filename, CompileMode mode=EXEC_M return compiler.__fillCode(); }catch(std::exception& e){ if(const _Error* _ = dynamic_cast(&e)){ - vm->_stderr(e.what()); + vm->_stderr(vm, e.what()); }else{ auto ce = CompileError("UnexpectedError", e.what(), compiler.getLineSnapshot()); - vm->_stderr(ce.what()); + vm->_stderr(vm, ce.what()); } - vm->_stderr("\n"); + vm->_stderr(vm, "\n"); return nullptr; } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index cbb34eba..91a1738e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,6 @@ #include "pocketpy.h" //#define PK_DEBUG_TIME -//#define PK_DEBUG_STACK struct Timer{ const char* title; @@ -21,10 +20,10 @@ struct Timer{ }; VM* newVM(){ - VM* vm = createVM([](const char* str) { + VM* vm = pkpy_new_vm([](const VM* vm, const char* str) { std::cout << str; std::cout.flush(); - }, [](const char* str) { + }, [](const VM* vm, const char* str) { std::cerr << str; std::cerr.flush(); }); @@ -34,44 +33,26 @@ VM* newVM(){ #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__) +// these code is for demo use, feel free to modify it + REPL* _repl; extern "C" { __EXPORT void repl_start(){ - _repl = new REPL(newVM(), false); + _repl = pkpy_new_repl(newVM(), false); } __EXPORT bool repl_input(const char* line){ - return _repl->input(line); + return pkpy_input_repl(_repl, line); } } #else -#ifdef PK_DEBUG_STACK -#include - -void setStackSize(_Float mb){ - const rlim_t kStackSize = (_Int)(mb * 1024 * 1024); - struct rlimit rl; - int result; - result = getrlimit(RLIMIT_STACK, &rl); - rl.rlim_cur = kStackSize; - result = setrlimit(RLIMIT_STACK, &rl); - if (result != 0){ - std::cerr << "setrlimit returned result = " << result << std::endl; - } -} -#endif - int main(int argc, char** argv){ -#ifdef PK_DEBUG_STACK - setStackSize(0.5); -#endif - if(argc == 1){ REPL repl(newVM()); while(true){ diff --git a/src/obj.h b/src/obj.h index 2102b0fb..a70b23ee 100644 --- a/src/obj.h +++ b/src/obj.h @@ -11,7 +11,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL; const _Float _FLOAT_INF_POS = INFINITY; const _Float _FLOAT_INF_NEG = -INFINITY; -#define PK_VERSION "0.2.1" +#define PK_VERSION "0.2.2" class PyObject; class CodeObject; diff --git a/src/pocketpy.h b/src/pocketpy.h index e6c9ce8f..2b6d82e0 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -42,9 +42,9 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) { for (auto& arg : args){ _Str s = vm->PyStr_AS_C(vm->asStr(arg)) + " "; - vm->_stdout(s.c_str()); + vm->_stdout(vm, s.c_str()); } - vm->_stdout("\n"); + vm->_stdout(vm, "\n"); return vm->None; }); @@ -547,15 +547,22 @@ void __addModuleSys(VM* vm){ vm->setAttr(mod, "version", vm->PyStr(PK_VERSION)); } +enum ExportType { + PKPY_VM, + PKPY_REPL +}; +static std::unordered_map __pkpy_allocations; + extern "C" { __EXPORT - VM* createVM(PrintFn _stdout, PrintFn _stderr){ + VM* pkpy_new_vm(PrintFn _stdout, PrintFn _stderr){ VM* vm = new VM(); + __pkpy_allocations[vm] = PKPY_VM; __initializeBuiltinFunctions(vm); vm->_stdout = _stdout; vm->_stderr = _stderr; - _Code code = compile(vm, __BUILTINS_CODE, "builtins.py"); + _Code code = compile(vm, __BUILTINS_CODE, ""); if(code == nullptr) exit(1); vm->_exec(code, vm->builtins); @@ -565,18 +572,36 @@ extern "C" { } __EXPORT - void destroyVM(VM* vm){ - delete vm; + bool pkpy_delete(void* p){ + auto it = __pkpy_allocations.find(p); + if(it == __pkpy_allocations.end()) return false; + switch(it->second){ + case PKPY_VM: delete (VM*)p; __pkpy_allocations.erase(it); return true; + case PKPY_REPL: delete (REPL*)p; __pkpy_allocations.erase(it); return true; + } + return false; } __EXPORT - void exec(VM* vm, const char* source){ + void pkpy_exec(VM* vm, const char* source){ _Code code = compile(vm, source, "main.py"); if(code != nullptr) vm->exec(code); } __EXPORT - void registerModule(VM* vm, const char* name, const char* source){ + REPL* pkpy_new_repl(VM* vm, bool use_prompt){ + REPL* repl = new REPL(vm, use_prompt); + __pkpy_allocations[repl] = PKPY_REPL; + return repl; + } + + __EXPORT + bool pkpy_input_repl(REPL* r, const char* line){ + return r->input(line); + } + + __EXPORT + void pkpy_add_module(VM* vm, const char* name, const char* source){ _Code code = compile(vm, source, name + _Str(".py")); if(code != nullptr){ PyVar _m = vm->newModule(name); diff --git a/src/repl.h b/src/repl.h index fad4c58a..0ff92824 100644 --- a/src/repl.h +++ b/src/repl.h @@ -9,7 +9,7 @@ class REPL { CompileMode mode; VM* vm; - bool use_prompt; + bool use_prompt; // whether to print >>> or ... bool exited = false; @@ -21,15 +21,15 @@ class REPL { void _loop_start(){ mode = SINGLE_MODE; if(use_prompt){ - vm->_stdout(need_more_lines ? "... " : ">>> "); + vm->_stdout(vm, need_more_lines ? "... " : ">>> "); } } public: REPL(VM* vm, bool use_prompt=true) : vm(vm), use_prompt(use_prompt) { - vm->_stdout("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n"); - vm->_stdout("https://github.com/blueloveTH/pocketpy" "\n"); - vm->_stdout("Type \"exit()\" to exit." "\n"); + vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n"); + vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n"); + vm->_stdout(vm, "Type \"exit()\" to exit." "\n"); _loop_start(); } diff --git a/src/vm.h b/src/vm.h index e2bdeca3..27628739 100644 --- a/src/vm.h +++ b/src/vm.h @@ -42,7 +42,7 @@ return obj; \ } -typedef void(*PrintFn)(const char*); +typedef void(*PrintFn)(const VM*, const char*); class VM{ private: @@ -154,8 +154,8 @@ private: { const PyVar& expr = frame->topValue(this); if(expr == None) break; - _stdout(PyStr_AS_C(asRepr(expr)).c_str()); - _stdout("\n"); + _stdout(this, PyStr_AS_C(asRepr(expr)).c_str()); + _stdout(this, "\n"); } break; case OP_POP_TOP: frame->popValue(this); break; case OP_BINARY_OP: @@ -311,8 +311,8 @@ public: PyVarDict _types; // builtin types PyVar None, True, False; - PrintFn _stdout = [](auto s){}; - PrintFn _stderr = [](auto s){}; + PrintFn _stdout = [](const VM* vm, auto s){}; + PrintFn _stderr = [](const VM* vm, auto s){}; PyVar builtins; // builtins module PyVar _main; // __main__ module @@ -441,12 +441,12 @@ public: return _exec(code, _module); } catch (const std::exception& e) { if(const _Error* _ = dynamic_cast(&e)){ - _stderr(e.what()); + _stderr(this, e.what()); }else{ auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots()); - _stderr(re.what()); + _stderr(this, re.what()); } - _stderr("\n"); + _stderr(this, "\n"); return None; } }