mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
adjust buffer settings
This commit is contained in:
parent
b13009dc8b
commit
ad2a15a76c
@ -18,4 +18,5 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <iostream>
|
@ -941,12 +941,11 @@ _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(vm, e.what());
|
(*vm->_stderr) << e.what() << '\n';
|
||||||
}else{
|
}else{
|
||||||
auto ce = CompileError("UnexpectedError", e.what(), compiler.getLineSnapshot());
|
auto ce = CompileError("UnexpectedError", e.what(), compiler.getLineSnapshot());
|
||||||
vm->_stderr(vm, ce.what());
|
(*vm->_stderr) << ce.what() << '\n';
|
||||||
}
|
}
|
||||||
vm->_stderr(vm, "\n");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
30
src/main.cpp
30
src/main.cpp
@ -1,4 +1,3 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "pocketpy.h"
|
#include "pocketpy.h"
|
||||||
@ -19,25 +18,6 @@ struct Timer{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadedVM* new_tvm_with_callbacks(){
|
|
||||||
ThreadedVM* vm = pkpy_new_tvm([](const VM* vm, const char* str) {
|
|
||||||
std::cout << str; std::cout.flush();
|
|
||||||
}, [](const VM* vm, const char* str) {
|
|
||||||
std::cerr << str; std::cerr.flush();
|
|
||||||
});
|
|
||||||
return vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
VM* new_vm_with_callbacks(){
|
|
||||||
VM* vm = pkpy_new_vm([](const VM* vm, const char* str) {
|
|
||||||
std::cout << str; std::cout.flush();
|
|
||||||
}, [](const VM* vm, const char* str) {
|
|
||||||
std::cerr << str; std::cerr.flush();
|
|
||||||
});
|
|
||||||
return vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
// these code is for demo use, feel free to modify it
|
||||||
@ -47,7 +27,9 @@ REPL* _repl;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
__EXPORT
|
__EXPORT
|
||||||
void repl_start(){
|
void repl_start(){
|
||||||
_repl = pkpy_new_repl(new_vm_with_callbacks(), false);
|
VM* vm = pkpy_new_vm(true);
|
||||||
|
useStandardBuffer(vm);
|
||||||
|
_repl = pkpy_new_repl(vm, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
@ -58,10 +40,10 @@ extern "C" {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
if(argc == 1){
|
if(argc == 1){
|
||||||
REPL repl(new_vm_with_callbacks());
|
VM* vm = pkpy_new_vm(true);
|
||||||
|
REPL repl(vm);
|
||||||
while(true){
|
while(true){
|
||||||
std::string line;
|
std::string line;
|
||||||
std::getline(std::cin, line);
|
std::getline(std::cin, line);
|
||||||
@ -81,7 +63,7 @@ int main(int argc, char** argv){
|
|||||||
}
|
}
|
||||||
std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
ThreadedVM* vm = new_tvm_with_callbacks();
|
ThreadedVM* vm = pkpy_new_tvm(true);
|
||||||
_Code code;
|
_Code code;
|
||||||
Timer("Compile time").run([&]{
|
Timer("Compile time").run([&]{
|
||||||
code = compile(vm, src.c_str(), filename);
|
code = compile(vm, src.c_str(), filename);
|
||||||
|
@ -10,7 +10,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.3"
|
#define PK_VERSION "0.2.4"
|
||||||
|
|
||||||
class CodeObject;
|
class CodeObject;
|
||||||
class BasePointer;
|
class BasePointer;
|
||||||
|
@ -42,8 +42,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
_vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) {
|
_vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) {
|
||||||
_StrStream ss;
|
_StrStream ss;
|
||||||
for (auto& arg : args) ss << vm->PyStr_AS_C(vm->asStr(arg)) << " ";
|
for (auto& arg : args) ss << vm->PyStr_AS_C(vm->asStr(arg)) << " ";
|
||||||
vm->_stdout(vm, ss.str().c_str());
|
(*vm->_stdout) << ss.str() << '\n';
|
||||||
vm->_stdout(vm, "\n");
|
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -593,6 +592,22 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__EXPORT
|
||||||
|
struct PyOutputDump: public PkExportedResource{
|
||||||
|
const char* stdout;
|
||||||
|
const char* stderr;
|
||||||
|
|
||||||
|
PyOutputDump(const char* _stdout, const char* _stderr){
|
||||||
|
stdout = strdup(_stdout);
|
||||||
|
stderr = strdup(_stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PyOutputDump(){
|
||||||
|
delete[] stdout;
|
||||||
|
delete[] stderr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
void pkpy_delete(PkExportedResource* p){
|
void pkpy_delete(PkExportedResource* p){
|
||||||
delete p;
|
delete p;
|
||||||
@ -665,11 +680,8 @@ extern "C" {
|
|||||||
return vm->exec(code, _m) != nullptr;
|
return vm->exec(code, _m) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __vm_init(VM* vm, PrintFn _stdout, PrintFn _stderr){
|
void __vm_init(VM* vm){
|
||||||
__initializeBuiltinFunctions(vm);
|
__initializeBuiltinFunctions(vm);
|
||||||
vm->_stdout = _stdout;
|
|
||||||
vm->_stderr = _stderr;
|
|
||||||
|
|
||||||
_Code code = compile(vm, __BUILTINS_CODE, "<builtins>");
|
_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);
|
||||||
@ -680,19 +692,34 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
VM* pkpy_new_vm(PrintFn _stdout, PrintFn _stderr){
|
VM* pkpy_new_vm(bool use_stdio){
|
||||||
VM* vm = new VM();
|
VM* vm = new VM(use_stdio);
|
||||||
__vm_init(vm, _stdout, _stderr);
|
__vm_init(vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
ThreadedVM* pkpy_new_tvm(PrintFn _stdout, PrintFn _stderr){
|
ThreadedVM* pkpy_new_tvm(bool use_stdio){
|
||||||
ThreadedVM* vm = new ThreadedVM();
|
ThreadedVM* vm = new ThreadedVM(use_stdio);
|
||||||
__vm_init(vm, _stdout, _stderr);
|
__vm_init(vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__EXPORT
|
||||||
|
PyOutputDump* pkpy_vm_read_output(VM* vm){
|
||||||
|
if(vm->use_stdio) UNREACHABLE();
|
||||||
|
_StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout);
|
||||||
|
_StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr);
|
||||||
|
if(s_out == nullptr || s_err == nullptr) UNREACHABLE();
|
||||||
|
PyOutputDump* dump = new PyOutputDump(
|
||||||
|
s_out->str().c_str(),
|
||||||
|
s_out->str().c_str()
|
||||||
|
);
|
||||||
|
s_out->str("");
|
||||||
|
s_err->str("");
|
||||||
|
return dump;
|
||||||
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
int pkpy_tvm_get_state(ThreadedVM* vm){
|
int pkpy_tvm_get_state(ThreadedVM* vm){
|
||||||
return vm->getState();
|
return vm->getState();
|
||||||
|
@ -21,15 +21,15 @@ class REPL: public PkExportedResource {
|
|||||||
void _loop_start(){
|
void _loop_start(){
|
||||||
mode = SINGLE_MODE;
|
mode = SINGLE_MODE;
|
||||||
if(use_prompt){
|
if(use_prompt){
|
||||||
vm->_stdout(vm, need_more_lines ? "... " : ">>> ");
|
(*vm->_stdout) << (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(vm, "pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n");
|
(*vm->_stdout) << ("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ")\n");
|
||||||
vm->_stdout(vm, "https://github.com/blueloveTH/pocketpy" "\n");
|
(*vm->_stdout) << ("https://github.com/blueloveTH/pocketpy" "\n");
|
||||||
vm->_stdout(vm, "Type \"exit()\" to exit." "\n");
|
(*vm->_stdout) << ("Type \"exit()\" to exit." "\n");
|
||||||
_loop_start();
|
_loop_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
src/vm.h
42
src/vm.h
@ -48,7 +48,6 @@ class VM: public PkExportedResource{
|
|||||||
private:
|
private:
|
||||||
std::stack< std::unique_ptr<Frame> > callstack;
|
std::stack< std::unique_ptr<Frame> > callstack;
|
||||||
PyVarDict _modules; // 3rd modules
|
PyVarDict _modules; // 3rd modules
|
||||||
|
|
||||||
PyVar __py2py_call_signal;
|
PyVar __py2py_call_signal;
|
||||||
|
|
||||||
PyVar runFrame(Frame* frame){
|
PyVar runFrame(Frame* frame){
|
||||||
@ -155,8 +154,7 @@ private:
|
|||||||
{
|
{
|
||||||
const PyVar& expr = frame->topValue(this);
|
const PyVar& expr = frame->topValue(this);
|
||||||
if(expr == None) break;
|
if(expr == None) break;
|
||||||
_stdout(this, PyStr_AS_C(asRepr(expr)).c_str());
|
*_stdout << PyStr_AS_C(asRepr(expr)) << '\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:
|
||||||
@ -328,15 +326,26 @@ public:
|
|||||||
PyVarDict _types;
|
PyVarDict _types;
|
||||||
PyVar None, True, False;
|
PyVar None, True, False;
|
||||||
|
|
||||||
PrintFn _stdout = [](const VM* vm, auto s){};
|
bool use_stdio;
|
||||||
PrintFn _stderr = [](const VM* vm, auto s){};
|
std::ostream* _stdout;
|
||||||
|
std::ostream* _stderr;
|
||||||
|
|
||||||
PyVar builtins; // builtins module
|
PyVar builtins; // builtins module
|
||||||
PyVar _main; // __main__ module
|
PyVar _main; // __main__ module
|
||||||
|
|
||||||
int maxRecursionDepth = 1000;
|
int maxRecursionDepth = 1000;
|
||||||
|
|
||||||
VM(){
|
VM(bool use_stdio){
|
||||||
|
this->use_stdio = use_stdio;
|
||||||
|
if(use_stdio){
|
||||||
|
std::cout.setf(std::ios::unitbuf);
|
||||||
|
std::cerr.setf(std::ios::unitbuf);
|
||||||
|
this->_stdout = &std::cout;
|
||||||
|
this->_stderr = &std::cerr;
|
||||||
|
}else{
|
||||||
|
this->_stdout = new _StrStream();
|
||||||
|
this->_stderr = new _StrStream();
|
||||||
|
}
|
||||||
initializeBuiltinClasses();
|
initializeBuiltinClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,12 +471,11 @@ 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(this, e.what());
|
*_stderr << e.what() << '\n';
|
||||||
}else{
|
}else{
|
||||||
auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots());
|
auto re = RuntimeError("UnexpectedError", e.what(), _cleanErrorAndGetSnapshots());
|
||||||
_stderr(this, re.what());
|
*_stderr << re.what() << '\n';
|
||||||
}
|
}
|
||||||
_stderr(this, "\n");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -785,7 +793,12 @@ public:
|
|||||||
if (!val) _error("AssertionError", msg);
|
if (!val) _error("AssertionError", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~VM() = default;
|
virtual ~VM() {
|
||||||
|
if(!use_stdio){
|
||||||
|
delete _stdout;
|
||||||
|
delete _stderr;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** Pointers' Impl *****/
|
/***** Pointers' Impl *****/
|
||||||
@ -916,10 +929,11 @@ enum ThreadState {
|
|||||||
class ThreadedVM : public VM {
|
class ThreadedVM : public VM {
|
||||||
std::thread* _thread;
|
std::thread* _thread;
|
||||||
std::atomic<ThreadState> state = THREAD_READY;
|
std::atomic<ThreadState> state = THREAD_READY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ThreadedVM(bool use_stdio) : VM(use_stdio) {}
|
||||||
|
|
||||||
_Str _stdin;
|
_Str _stdin;
|
||||||
|
|
||||||
void suspend(){
|
void suspend(){
|
||||||
if(_thread == nullptr) UNREACHABLE();
|
if(_thread == nullptr) UNREACHABLE();
|
||||||
if(state != THREAD_RUNNING) UNREACHABLE();
|
if(state != THREAD_RUNNING) UNREACHABLE();
|
||||||
@ -938,8 +952,7 @@ public:
|
|||||||
/***** For outer use *****/
|
/***** For outer use *****/
|
||||||
|
|
||||||
ThreadState getState(){
|
ThreadState getState(){
|
||||||
if(_thread == nullptr) UNREACHABLE();
|
return state.load();
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resume(){
|
void resume(){
|
||||||
@ -950,6 +963,7 @@ public:
|
|||||||
|
|
||||||
void startExec(const _Code& code){
|
void startExec(const _Code& code){
|
||||||
if(_thread != nullptr) UNREACHABLE();
|
if(_thread != nullptr) UNREACHABLE();
|
||||||
|
if(state != THREAD_READY) UNREACHABLE();
|
||||||
_thread = new std::thread([this, code](){
|
_thread = new std::thread([this, code](){
|
||||||
this->state = THREAD_RUNNING;
|
this->state = THREAD_RUNNING;
|
||||||
this->exec(code);
|
this->exec(code);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user