blueloveTH 3 лет назад
Родитель
Сommit
8d152c225f
4 измененных файлов с 23 добавлено и 5 удалено
  1. 2 1
      src/error.h
  2. 1 1
      src/obj.h
  3. 10 0
      src/pocketpy.h
  4. 10 3
      src/vm.h

+ 2 - 1
src/error.h

@@ -22,7 +22,8 @@ struct SourceMetadata {
 
     _Str getLine(int lineno) const {
         if(lineno == -1) return "<?>";
-        const char* _start = lineStarts.at(lineno-1);
+        lineno -= 1;
+        const char* _start = lineStarts.at(lineno < 0 ? 0 : lineno);
         const char* i = _start;
         while(*i != '\n' && *i != '\0') i++;
         return _Str(_start, i-_start);

+ 1 - 1
src/obj.h

@@ -5,7 +5,7 @@
 typedef int64_t _Int;
 typedef double _Float;
 
-#define PK_VERSION "0.3.8"
+#define PK_VERSION "0.3.9"
 
 class CodeObject;
 class BasePointer;

+ 10 - 0
src/pocketpy.h

@@ -597,6 +597,16 @@ void __addModuleTime(VM* vm){
         auto now = std::chrono::high_resolution_clock::now();
         return vm->PyFloat(std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count() / 1000000.0);
     });
+
+    vm->bindFunc(mod, "sleep", [](VM* vm, const pkpy::ArgList& args) {
+        vm->__checkArgSize(args, 1);
+        if(!vm->isIntOrFloat(args[0])){
+            vm->typeError("time.sleep() argument must be int or float");
+        }
+        double sec = vm->numToFloat(args[0]);
+        vm->sleepForSecs(sec);
+        return vm->None;
+    });
 }
 
 void __addModuleSys(VM* vm){

+ 10 - 3
src/vm.h

@@ -49,7 +49,7 @@ protected:
     PyVarDict _modules;                     // loaded modules
     std::map<_Str, _Code> _lazyModules;     // lazy loaded modules
     PyVar __py2py_call_signal;
-    bool _stopFlag = false;
+    std::atomic<bool> _stopFlag = false;
 
     void _checkStopFlag(){
         if(_stopFlag){
@@ -412,6 +412,14 @@ public:
         _stopFlag = true;
     }
 
+    void sleepForSecs(_Float sec){
+        _Int ms = (_Int)(sec * 1000);
+        for(_Int i=0; i<ms; i+=20){
+            _checkStopFlag();
+            std::this_thread::sleep_for(std::chrono::milliseconds(20));
+        }
+    }
+
     PyVar asStr(const PyVar& obj){
         PyVarOrNull str_fn = getAttr(obj, __str__, false);
         if(str_fn != nullptr) return call(str_fn, {});
@@ -941,7 +949,6 @@ public:
     }
 
     virtual ~VM() {
-        callstack.clear();
         if(!use_stdio){
             delete _stdout;
             delete _stderr;
@@ -1107,7 +1114,7 @@ class ThreadedVM : public VM {
 
     void __deleteThread(){
         if(_thread != nullptr){
-            keyboardInterrupt();
+            if(_state == THREAD_RUNNING || _state == THREAD_SUSPENDED) keyboardInterrupt();
             _thread->join();
             delete _thread;
             _thread = nullptr;