This commit is contained in:
blueloveTH 2022-11-11 13:49:23 +08:00
parent a7266c9388
commit 478ff9ab8d
6 changed files with 104 additions and 47 deletions

View File

@ -4,7 +4,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f:
pipeline = [
["__stl__.h", "str.h", "builtins.h", "error.h"],
["obj.h", "iter.h", "parser.h", "pointer.h", "codeobject.h"],
["vm.h", "compiler.h"],
["vm.h", "compiler.h", "repl.h"],
["pocketpy.h"]
]

View File

@ -1,3 +1,3 @@
rm -rf build/wasm/
mkdir -p build/wasm/
emcc src/main.cpp -fexceptions -o build/wasm/index.html
emcc src/main.cpp -fexceptions -sEXIT_RUNTIME -sEXPORTED_FUNCTIONS=_repl_input,_repl_start -sEXPORTED_RUNTIME_METHODS=ccall -o build/wasm/pocketpy.js

View File

@ -20,65 +20,44 @@ struct Timer{
};
VM* newVM(){
// disable buff of std::cout and std::cerr
std::cout.setf(std::ios::unitbuf);
std::cerr.setf(std::ios::unitbuf);
VM* vm = createVM([](const char* str) {
std::cout << str;
std::cout.flush();
}, [](const char* str) {
std::cerr << str;
std::cerr.flush();
});
return vm;
}
void REPL(){
std::cout << "pocketpy " PK_VERSION << std::endl;
std::cout << "https://github.com/blueloveTH/pocketpy" << std::endl;
int need_more_lines = 0;
std::string buffer;
VM* vm = newVM();
#if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__)
while(true){
CompileMode mode = SINGLE_MODE;
vm->_stdout(need_more_lines ? "... " : ">>> ");
std::string line;
std::getline(std::cin, line);
REPL* _repl;
if(need_more_lines){
buffer += line;
buffer += '\n';
int n = buffer.size();
if(n>=need_more_lines){
for(int i=buffer.size()-need_more_lines; i<buffer.size(); i++){
if(buffer[i] != '\n') goto __NOT_ENOUGH_LINES;
}
need_more_lines = 0;
line = buffer;
mode = EXEC_MODE; // tmp set to EXEC_MODE
buffer.clear();
}else{
__NOT_ENOUGH_LINES:
continue;
}
}else{
if(line == "exit()") break;
if(line.empty()) continue;
}
extern "C" {
__EXPORT
void repl_start(){
_repl = new REPL(newVM(), false);
}
try{
_Code code = compile(vm, line.c_str(), "<stdin>", mode);
if(code != nullptr) vm->exec(code);
}catch(NeedMoreLines& ne){
buffer += line;
buffer += '\n';
need_more_lines = ne.isClassDef ? 3 : 2;
}
__EXPORT
bool repl_input(const char* line){
return _repl->input(line);
}
}
#else
int main(int argc, char** argv){
if(argc == 1){
REPL();
REPL repl(newVM());
while(true){
std::string line;
std::getline(std::cin, line);
repl.input(line);
}
return 0;
}
@ -109,4 +88,6 @@ int main(int argc, char** argv){
__HELP:
std::cout << "Usage: pocketpy [filename]" << std::endl;
return 0;
}
}
#endif

View File

@ -11,6 +11,8 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
const _Float _FLOAT_INF_POS = INFINITY;
const _Float _FLOAT_INF_NEG = -INFINITY;
#define PK_VERSION "0.2.0"
class PyObject;
class CodeObject;
class BasePointer;

View File

@ -2,8 +2,7 @@
#include "vm.h"
#include "compiler.h"
#define PK_VERSION "0.2.0"
#include "repl.h"
#define BIND_NUM_ARITH_OPT(name, op) \
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, PyVarList args){ \

75
src/repl.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include "compiler.h"
#include "vm.h"
class REPL {
int need_more_lines = 0;
std::string buffer;
CompileMode mode;
VM* vm;
bool use_prompt;
bool exited = false;
void _exit(){
exited = true;
exit(0);
}
void _loop_start(){
mode = SINGLE_MODE;
if(use_prompt){
vm->_stdout(need_more_lines ? "... " : ">>> ");
}
}
public:
REPL(VM* vm, bool use_prompt=true) : vm(vm), use_prompt(use_prompt) {
vm->_stdout("pocketpy " PK_VERSION "\n");
vm->_stdout("https://github.com/blueloveTH/pocketpy" "\n");
vm->_stdout("Type \"exit()\" to exit." "\n");
_loop_start();
}
bool input(const char* line){
return input(std::string(line));
}
bool input(std::string line){
if(exited) return false;
if(need_more_lines){
buffer += line;
buffer += '\n';
int n = buffer.size();
if(n>=need_more_lines){
for(int i=buffer.size()-need_more_lines; i<buffer.size(); i++){
if(buffer[i] != '\n') goto __NOT_ENOUGH_LINES;
}
need_more_lines = 0;
line = buffer;
mode = EXEC_MODE; // tmp set to EXEC_MODE
buffer.clear();
}else{
__NOT_ENOUGH_LINES:
goto __LOOP_CONTINUE;
}
}else{
if(line == "exit()") _exit();
if(line.empty()) goto __LOOP_CONTINUE;
}
try{
_Code code = compile(vm, line.c_str(), "<stdin>", mode);
if(code != nullptr) vm->exec(code);
}catch(NeedMoreLines& ne){
buffer += line;
buffer += '\n';
need_more_lines = ne.isClassDef ? 3 : 2;
}
__LOOP_CONTINUE:
_loop_start();
return need_more_lines > 0;
}
};