diff --git a/include/pocketpy/interpreter/modules.h b/include/pocketpy/interpreter/modules.h index 4ea78a0c..bf2ac302 100644 --- a/include/pocketpy/interpreter/modules.h +++ b/include/pocketpy/interpreter/modules.h @@ -7,4 +7,5 @@ void pk__add_module_math(); void pk__add_module_dis(); void pk__add_module_random(); void pk__add_module_json(); -void pk__add_module_gc(); \ No newline at end of file +void pk__add_module_gc(); +void pk__add_module_time(); diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index b5334138..7c3a48f3 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -360,6 +360,8 @@ void py_push(py_Ref src); void py_pushnil(); /// Push a `None` object to the stack. void py_pushnone(); +/// Push a `py_Name` to the stack. This is used for keyword arguments. +void py_pushname(py_Name name); /// Pop an object from the stack. void py_pop(); /// Shrink the stack by n. diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 8714fc69..08691348 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -202,6 +202,7 @@ void VM__ctor(VM* self) { pk__add_module_random(); pk__add_module_json(); pk__add_module_gc(); + pk__add_module_time(); // add python builtins do { diff --git a/src/modules/time.c b/src/modules/time.c new file mode 100644 index 00000000..f03d5e2b --- /dev/null +++ b/src/modules/time.c @@ -0,0 +1,60 @@ +#include "pocketpy/pocketpy.h" +#include "time.h" +#include + +#define NANOS_PER_SEC 1000000000 + +static bool get_ns(int64_t* out) { + struct timespec tms; + /* The C11 way */ + if(!timespec_get(&tms, TIME_UTC)) { + return py_exception(tp_OSError, "%s", "timespec_get() failed"); + } + /* seconds, multiplied with 1 billion */ + int64_t nanos = tms.tv_sec * NANOS_PER_SEC; + /* Add full nanoseconds */ + nanos += tms.tv_nsec; + *out = nanos; + return true; +} + +static bool time_time(int argc, py_Ref argv) { + PY_CHECK_ARGC(0); + int64_t nanos; + if(!get_ns(&nanos)) return false; + py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC); + return true; +} + +static bool time_time_ns(int argc, py_Ref argv) { + PY_CHECK_ARGC(0); + int64_t nanos; + if(!get_ns(&nanos)) return false; + py_newint(py_retval(), nanos); + return true; +} + +static bool time_sleep(int argc, py_Ref argv) { + PY_CHECK_ARGC(1); + py_f64 secs; + if(!py_castfloat(argv, &secs)) return false; + + int64_t start; + if(!get_ns(&start)) return false; + const int64_t end = start + secs * 1000000000; + while(true) { + int64_t now; + if(!get_ns(&now)) return false; + if(now >= end) break; + } + py_newnone(py_retval()); + return true; +} + +void pk__add_module_time() { + py_Ref mod = py_newmodule("time"); + + py_bindfunc(mod, "time", time_time); + py_bindfunc(mod, "time_ns", time_time_ns); + py_bindfunc(mod, "sleep", time_sleep); +} \ No newline at end of file diff --git a/src/public/stack_ops.c b/src/public/stack_ops.c index e95e44ed..92b53709 100644 --- a/src/public/stack_ops.c +++ b/src/public/stack_ops.c @@ -100,8 +100,12 @@ void py_pushnone() { py_newnone(vm->stack.sp++); } +void py_pushname(py_Name name){ + VM* vm = pk_current_vm; + py_newint(vm->stack.sp++, name); +} + py_Ref py_pushtmp() { VM* vm = pk_current_vm; - py_newnil(vm->stack.sp++); - return py_peek(-1); + return vm->stack.sp++; } \ No newline at end of file