blueloveTH 2 лет назад
Родитель
Сommit
644b0766b8
3 измененных файлов с 106 добавлено и 52 удалено
  1. 0 52
      python/builtins.py
  2. 101 0
      src/pocketpy.h
  3. 5 0
      src/vm.h

+ 0 - 52
python/builtins.py

@@ -70,9 +70,6 @@ def sorted(iterable, reverse=False):
     return a
 
 ##### str #####
-
-str.__mul__ = lambda self, n: ''.join([self for _ in range(n)])
-
 def str@split(self, sep):
     if sep == "":
         return list(self)
@@ -132,55 +129,6 @@ def list@sort(self, reverse=False):
     if reverse:
         self.reverse()
 
-def list@remove(self, value):
-    for i in range(len(self)):
-        if self[i] == value:
-            del self[i]
-            return
-    value = repr(value)
-    raise ValueError(f'{value} is not in list')
-
-def list@index(self, value):
-    for i in range(len(self)):
-        if self[i] == value:
-            return i
-    value = repr(value)
-    raise ValueError(f'{value} is not in list')
-
-def list@pop(self, i=-1):
-    res = self[i]
-    del self[i]
-    return res
-
-def list@__eq__(self, other):
-    if type(self) is not type(other):
-        return False
-    if len(self) != len(other):
-        return False
-    for i in range(len(self)):
-        if self[i] != other[i]:
-            return False
-    return True
-tuple.__eq__ = list.__eq__
-list.__ne__ = lambda self, other: not self.__eq__(other)
-tuple.__ne__ = lambda self, other: not self.__eq__(other)
-
-def list@count(self, x):
-    res = 0
-    for i in self:
-        if i == x:
-            res += 1
-    return res
-tuple.count = list.count
-
-def list@__contains__(self, item):
-    for i in self:
-        if i == item:
-            return True
-    return False
-tuple.__contains__ = list.__contains__
-
-
 class property:
     def __init__(self, fget, fset=None):
         self.fget = fget

+ 101 - 0
src/pocketpy.h

@@ -364,6 +364,13 @@ inline void init_builtins(VM* _vm) {
     _vm->bind__len__(_vm->tp_str, [](VM* vm, PyObject* obj) {
         return (i64)_CAST(Str&, obj).u8_length();
     });
+    _vm->bind__mul__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
+        const Str& self = _CAST(Str&, lhs);
+        i64 n = CAST(i64, rhs);
+        std::stringstream ss;
+        for(i64 i = 0; i < n; i++) ss << self.sv();
+        return VAR(ss.str());
+    });
     _vm->bind__contains__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
         const Str& self = _CAST(Str&, lhs);
         const Str& other = CAST(Str&, rhs);
@@ -481,6 +488,73 @@ inline void init_builtins(VM* _vm) {
         return vm->py_list(args[1]);
     });
 
+    _vm->bind__contains__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* item) {
+        List& self = _CAST(List&, obj);
+        for(PyObject* i: self) if(vm->py_equals(i, item)) return true;
+        return false;
+    });
+
+    _vm->bind_method<1>("list", "count", [](VM* vm, ArgsView args) {
+        List& self = _CAST(List&, args[0]);
+        int count = 0;
+        for(PyObject* i: self) if(vm->py_equals(i, args[1])) count++;
+        return VAR(count);
+    });
+
+    _vm->bind__eq__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
+        List& a = _CAST(List&, lhs);
+        List& b = _CAST(List&, rhs);
+        if(a.size() != b.size()) return false;
+        for(int i=0; i<a.size(); i++){
+            if(vm->py_not_equals(a[i], b[i])) return false;
+        }
+        return true;
+    });
+
+    _vm->bind__ne__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
+        return !vm->py_equals(lhs, rhs);
+    });
+
+    _vm->bind_method<1>("list", "index", [](VM* vm, ArgsView args) {
+        List& self = _CAST(List&, args[0]);
+        PyObject* obj = args[1];
+        for(int i=0; i<self.size(); i++){
+            if(vm->py_equals(self[i], obj)) return VAR(i);
+        }
+        vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
+        return vm->None;
+    });
+
+    _vm->bind_method<1>("list", "remove", [](VM* vm, ArgsView args) {
+        List& self = _CAST(List&, args[0]);
+        PyObject* obj = args[1];
+        for(int i=0; i<self.size(); i++){
+            if(vm->py_equals(self[i], obj)){
+                self.erase(i);
+                return vm->None;
+            }
+        }
+        vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
+        return vm->None;
+    });
+
+    _vm->bind_method<-1>("list", "pop", [](VM* vm, ArgsView args) {
+        List& self = _CAST(List&, args[0]);
+        if(args.size() == 1+0){
+            if(self.empty()) vm->IndexError("pop from empty list");
+            return self.popx_back();
+        }
+        if(args.size() == 1+1){
+            int index = CAST(int, args[1]);
+            index = vm->normalized_index(index, self.size());
+            PyObject* ret = self[index];
+            self.erase(index);
+            return ret;
+        }
+        vm->TypeError("pop() takes at most 1 argument");
+        return vm->None;
+    });
+
     _vm->bind_method<1>("list", "append", [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         self.push_back(args[1]);
@@ -571,6 +645,33 @@ inline void init_builtins(VM* _vm) {
         return VAR(Tuple(std::move(list)));
     });
 
+    _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
+        Tuple& self = _CAST(Tuple&, obj);
+        for(PyObject* i: self) if(vm->py_equals(i, item)) return true;
+        return false;
+    });
+
+    _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
+        Tuple& self = _CAST(Tuple&, args[0]);
+        int count = 0;
+        for(PyObject* i: self) if(vm->py_equals(i, args[1])) count++;
+        return VAR(count);
+    });
+
+    _vm->bind__eq__(_vm->tp_tuple, [](VM* vm, PyObject* lhs, PyObject* rhs) {
+        const Tuple& self = _CAST(Tuple&, lhs);
+        const Tuple& other = CAST(Tuple&, rhs);
+        if(self.size() != other.size()) return false;
+        for(int i = 0; i < self.size(); i++) {
+            if(vm->py_not_equals(self[i], other[i])) return false;
+        }
+        return true;
+    });
+
+    _vm->bind__ne__(_vm->tp_tuple, [](VM* vm, PyObject* lhs, PyObject* rhs) {
+        return !vm->py_equals(lhs, rhs);
+    });
+
     _vm->bind__hash__(_vm->tp_tuple, [](VM* vm, PyObject* obj) {
         i64 x = 1000003;
         const Tuple& items = CAST(Tuple&, obj);

+ 5 - 0
src/vm.h

@@ -613,6 +613,8 @@ DEF_NATIVE_2(Bytes, tp_bytes)
 DEF_NATIVE_2(MappingProxy, tp_mappingproxy)
 DEF_NATIVE_2(Dict, tp_dict)
 
+#undef DEF_NATIVE_2
+
 #define PY_CAST_INT(T)                                  \
 template<> inline T py_cast<T>(VM* vm, PyObject* obj){  \
     vm->check_int(obj);                                 \
@@ -691,6 +693,9 @@ PY_VAR_INT(unsigned long long)
 PY_VAR_FLOAT(float)
 PY_VAR_FLOAT(double)
 
+#undef PY_VAR_INT
+#undef PY_VAR_FLOAT
+
 inline PyObject* py_var(VM* vm, bool val){
     return val ? vm->True : vm->False;
 }