blueloveTH 1 год назад
Родитель
Сommit
651bf997fc
3 измененных файлов с 42 добавлено и 7 удалено
  1. 0 1
      python/collections.py
  2. 4 1
      src/compiler/compiler.c
  3. 38 5
      src/public/modules.c

+ 0 - 1
python/collections.py

@@ -1,4 +1,3 @@
-from pkpy import _enable_instance_dict
 from typing import Generic, TypeVar, Iterable
 
 T = TypeVar('T')

+ 4 - 1
src/compiler/compiler.c

@@ -1833,7 +1833,10 @@ static Error* exprName(Compiler* self) {
     py_Name name = py_namev(Token__sv(prev()));
     NameScope scope = name_scope(self);
     // promote this name to global scope if needed
-    if(c11_smallmap_n2i__contains(&ctx()->global_names, name)) { scope = NAME_GLOBAL; }
+    if(c11_smallmap_n2i__contains(&ctx()->global_names, name)) {
+        if(scope == NAME_GLOBAL_UNKNOWN) return SyntaxError(self, "cannot use global keyword here");
+        scope = NAME_GLOBAL;
+    }
     NameExpr* e = NameExpr__new(prev()->line, name, scope);
     Ctx__s_push(ctx(), (Expr*)e);
     return NULL;

+ 38 - 5
src/public/modules.c

@@ -5,6 +5,7 @@
 #include "pocketpy/common/sstream.h"
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/common/_generated.h"
+#include <math.h>
 
 py_Ref py_getmodule(const char* path) {
     VM* vm = pk_current_vm;
@@ -231,6 +232,37 @@ static bool builtins_divmod(int argc, py_Ref argv) {
     return pk_callmagic(__divmod__, 2, argv);
 }
 
+static bool builtins_round(int argc, py_Ref argv) {
+    py_i64 ndigits;
+
+    if(argc == 1) {
+        ndigits = -1;
+    } else if(argc == 2) {
+        PY_CHECK_ARG_TYPE(1, tp_int);
+        ndigits = py_toint(py_arg(1));
+        if(ndigits < 0) return ValueError("ndigits should be non-negative");
+    } else {
+        return TypeError("round() takes 1 or 2 arguments");
+    }
+
+    if(py_isint(py_arg(0))) {
+        py_assign(py_retval(), py_arg(0));
+        return true;
+    }
+
+    PY_CHECK_ARG_TYPE(0, tp_float);
+    py_f64 x = py_tofloat(py_arg(0));
+    py_f64 offset = x >= 0 ? 0.5 : -0.5;
+    if(ndigits == -1) {
+        py_newint(py_retval(), (py_i64)(x + offset));
+        return true;
+    }
+
+    py_f64 factor = pow(10, ndigits);
+    py_newfloat(py_retval(), (py_i64)(x * factor + offset) / factor);
+    return true;
+}
+
 static bool builtins_print(int argc, py_Ref argv) {
     int length;
     py_TValue* args = pk_arrayview(argv, &length);
@@ -355,7 +387,7 @@ static bool builtins_ord(int argc, py_Ref argv) {
 
 static bool builtins_globals(int argc, py_Ref argv) {
     Frame* frame = pk_current_vm->top_frame;
-    if(frame->is_dynamic){
+    if(frame->is_dynamic) {
         py_assign(py_retval(), &frame->p0[0]);
         return true;
     }
@@ -363,9 +395,9 @@ static bool builtins_globals(int argc, py_Ref argv) {
     return true;
 }
 
-static bool builtins_locals(int argc, py_Ref argv){
+static bool builtins_locals(int argc, py_Ref argv) {
     Frame* frame = pk_current_vm->top_frame;
-    if(frame->is_dynamic){
+    if(frame->is_dynamic) {
         py_assign(py_retval(), &frame->p0[1]);
         return true;
     }
@@ -377,7 +409,7 @@ static bool builtins_locals(int argc, py_Ref argv){
 static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_CompileMode mode) {
     PY_CHECK_ARG_TYPE(0, tp_str);
     Frame* frame = pk_current_vm->top_frame;
-    switch(argc){
+    switch(argc) {
         case 1: {
             // system globals + system locals
             if(!builtins_globals(0, NULL)) return false;
@@ -403,7 +435,7 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_
     return py_execdyn(py_tostr(argv), "<string>", mode, frame->module);
 }
 
-static bool builtins_exec(int argc, py_Ref argv){
+static bool builtins_exec(int argc, py_Ref argv) {
     return _builtins_execdyn("exec", argc, argv, EXEC_MODE);
 }
 
@@ -437,6 +469,7 @@ py_TValue pk_builtins__register() {
     py_bindfunc(builtins, "hash", builtins_hash);
     py_bindfunc(builtins, "abs", builtins_abs);
     py_bindfunc(builtins, "divmod", builtins_divmod);
+    py_bindfunc(builtins, "round", builtins_round);
 
     py_bind(builtins, "print(*args, sep=' ', end='\\n')", builtins_print);