add exports

This commit is contained in:
blueloveTH 2022-11-12 22:18:49 +08:00
parent b15066f458
commit 181e7eb298
6 changed files with 56 additions and 50 deletions

View File

@ -899,12 +899,12 @@ _Code compile(VM* vm, const char* source, _Str filename, CompileMode mode=EXEC_M
return compiler.__fillCode(); return compiler.__fillCode();
}catch(std::exception& e){ }catch(std::exception& e){
if(const _Error* _ = dynamic_cast<const _Error*>(&e)){ if(const _Error* _ = dynamic_cast<const _Error*>(&e)){
vm->_stderr(e.what()); vm->_stderr(vm, e.what());
}else{ }else{
auto ce = CompileError("UnexpectedError", e.what(), compiler.getLineSnapshot()); 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; return nullptr;
} }
} }

View File

@ -4,7 +4,6 @@
#include "pocketpy.h" #include "pocketpy.h"
//#define PK_DEBUG_TIME //#define PK_DEBUG_TIME
//#define PK_DEBUG_STACK
struct Timer{ struct Timer{
const char* title; const char* title;
@ -21,10 +20,10 @@ struct Timer{
}; };
VM* newVM(){ VM* newVM(){
VM* vm = createVM([](const char* str) { VM* vm = pkpy_new_vm([](const VM* vm, const char* str) {
std::cout << str; std::cout << str;
std::cout.flush(); std::cout.flush();
}, [](const char* str) { }, [](const VM* vm, const char* str) {
std::cerr << str; std::cerr << str;
std::cerr.flush(); std::cerr.flush();
}); });
@ -34,44 +33,26 @@ VM* newVM(){
#if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__) #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__)
// these code is for demo use, feel free to modify it
REPL* _repl; REPL* _repl;
extern "C" { extern "C" {
__EXPORT __EXPORT
void repl_start(){ void repl_start(){
_repl = new REPL(newVM(), false); _repl = pkpy_new_repl(newVM(), false);
} }
__EXPORT __EXPORT
bool repl_input(const char* line){ bool repl_input(const char* line){
return _repl->input(line); return pkpy_input_repl(_repl, line);
} }
} }
#else #else
#ifdef PK_DEBUG_STACK
#include <sys/resource.h>
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){ int main(int argc, char** argv){
#ifdef PK_DEBUG_STACK
setStackSize(0.5);
#endif
if(argc == 1){ if(argc == 1){
REPL repl(newVM()); REPL repl(newVM());
while(true){ while(true){

View File

@ -11,7 +11,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
const _Float _FLOAT_INF_POS = INFINITY; const _Float _FLOAT_INF_POS = INFINITY;
const _Float _FLOAT_INF_NEG = -INFINITY; const _Float _FLOAT_INF_NEG = -INFINITY;
#define PK_VERSION "0.2.1" #define PK_VERSION "0.2.2"
class PyObject; class PyObject;
class CodeObject; class CodeObject;

View File

@ -42,9 +42,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) { _vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) {
for (auto& arg : args){ for (auto& arg : args){
_Str s = vm->PyStr_AS_C(vm->asStr(arg)) + " "; _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; return vm->None;
}); });
@ -547,15 +547,22 @@ void __addModuleSys(VM* vm){
vm->setAttr(mod, "version", vm->PyStr(PK_VERSION)); vm->setAttr(mod, "version", vm->PyStr(PK_VERSION));
} }
enum ExportType {
PKPY_VM,
PKPY_REPL
};
static std::unordered_map<void*, ExportType> __pkpy_allocations;
extern "C" { extern "C" {
__EXPORT __EXPORT
VM* createVM(PrintFn _stdout, PrintFn _stderr){ VM* pkpy_new_vm(PrintFn _stdout, PrintFn _stderr){
VM* vm = new VM(); VM* vm = new VM();
__pkpy_allocations[vm] = PKPY_VM;
__initializeBuiltinFunctions(vm); __initializeBuiltinFunctions(vm);
vm->_stdout = _stdout; vm->_stdout = _stdout;
vm->_stderr = _stderr; vm->_stderr = _stderr;
_Code code = compile(vm, __BUILTINS_CODE, "builtins.py"); _Code code = compile(vm, __BUILTINS_CODE, "<builtins>");
if(code == nullptr) exit(1); if(code == nullptr) exit(1);
vm->_exec(code, vm->builtins); vm->_exec(code, vm->builtins);
@ -565,18 +572,36 @@ extern "C" {
} }
__EXPORT __EXPORT
void destroyVM(VM* vm){ bool pkpy_delete(void* p){
delete vm; 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 __EXPORT
void exec(VM* vm, const char* source){ void pkpy_exec(VM* vm, const char* source){
_Code code = compile(vm, source, "main.py"); _Code code = compile(vm, source, "main.py");
if(code != nullptr) vm->exec(code); if(code != nullptr) vm->exec(code);
} }
__EXPORT __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")); _Code code = compile(vm, source, name + _Str(".py"));
if(code != nullptr){ if(code != nullptr){
PyVar _m = vm->newModule(name); PyVar _m = vm->newModule(name);

View File

@ -9,7 +9,7 @@ class REPL {
CompileMode mode; CompileMode mode;
VM* vm; VM* vm;
bool use_prompt; bool use_prompt; // whether to print >>> or ...
bool exited = false; bool exited = false;
@ -21,15 +21,15 @@ class REPL {
void _loop_start(){ void _loop_start(){
mode = SINGLE_MODE; mode = SINGLE_MODE;
if(use_prompt){ if(use_prompt){
vm->_stdout(need_more_lines ? "... " : ">>> "); vm->_stdout(vm, need_more_lines ? "... " : ">>> ");
} }
} }
public: public:
REPL(VM* vm, bool use_prompt=true) : vm(vm), use_prompt(use_prompt) { REPL(VM* vm, bool use_prompt=true) : vm(vm), use_prompt(use_prompt) {
vm->_stdout("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n"); vm->_stdout(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n");
vm->_stdout("https://github.com/blueloveTH/pocketpy" "\n"); vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n");
vm->_stdout("Type \"exit()\" to exit." "\n"); vm->_stdout(vm, "Type \"exit()\" to exit." "\n");
_loop_start(); _loop_start();
} }

View File

@ -42,7 +42,7 @@
return obj; \ return obj; \
} }
typedef void(*PrintFn)(const char*); typedef void(*PrintFn)(const VM*, const char*);
class VM{ class VM{
private: private:
@ -154,8 +154,8 @@ private:
{ {
const PyVar& expr = frame->topValue(this); const PyVar& expr = frame->topValue(this);
if(expr == None) break; if(expr == None) break;
_stdout(PyStr_AS_C(asRepr(expr)).c_str()); _stdout(this, PyStr_AS_C(asRepr(expr)).c_str());
_stdout("\n"); _stdout(this, "\n");
} break; } break;
case OP_POP_TOP: frame->popValue(this); break; case OP_POP_TOP: frame->popValue(this); break;
case OP_BINARY_OP: case OP_BINARY_OP:
@ -311,8 +311,8 @@ public:
PyVarDict _types; // builtin types PyVarDict _types; // builtin types
PyVar None, True, False; PyVar None, True, False;
PrintFn _stdout = [](auto s){}; PrintFn _stdout = [](const VM* vm, auto s){};
PrintFn _stderr = [](auto s){}; PrintFn _stderr = [](const VM* vm, auto s){};
PyVar builtins; // builtins module PyVar builtins; // builtins module
PyVar _main; // __main__ module PyVar _main; // __main__ module
@ -441,12 +441,12 @@ public:
return _exec(code, _module); return _exec(code, _module);
} catch (const std::exception& e) { } catch (const std::exception& e) {
if(const _Error* _ = dynamic_cast<const _Error*>(&e)){ if(const _Error* _ = dynamic_cast<const _Error*>(&e)){
_stderr(e.what()); _stderr(this, e.what());
}else{ }else{
auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots()); auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots());
_stderr(re.what()); _stderr(this, re.what());
} }
_stderr("\n"); _stderr(this, "\n");
return None; return None;
} }
} }