blueloveTH hace 3 años
padre
commit
478ff9ab8d
Se han modificado 6 ficheros con 104 adiciones y 47 borrados
  1. 1 1
      amalgamate.py
  2. 1 1
      build_wasm.sh
  3. 24 43
      src/main.cpp
  4. 2 0
      src/obj.h
  5. 1 2
      src/pocketpy.h
  6. 75 0
      src/repl.h

+ 1 - 1
amalgamate.py

@@ -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"]
 ]
 

+ 1 - 1
build_wasm.sh

@@ -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

+ 24 - 43
src/main.cpp

@@ -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

+ 2 - 0
src/obj.h

@@ -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;

+ 1 - 2
src/pocketpy.h

@@ -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 - 0
src/repl.h

@@ -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;
+    }
+};