From 644b0766b83abf9183f85b507c8d6c740a23a41a Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 21 May 2023 18:58:33 +0800 Subject: [PATCH] ... --- python/builtins.py | 52 ----------------------- src/pocketpy.h | 101 +++++++++++++++++++++++++++++++++++++++++++++ src/vm.h | 5 +++ 3 files changed, 106 insertions(+), 52 deletions(-) diff --git a/python/builtins.py b/python/builtins.py index 6df3b7c9..44b652b9 100644 --- a/python/builtins.py +++ b/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 diff --git a/src/pocketpy.h b/src/pocketpy.h index 5ee1fd72..8559057f 100644 --- a/src/pocketpy.h +++ b/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; ipy_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; ipy_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; ipy_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); diff --git a/src/vm.h b/src/vm.h index 374ec315..c39a861d 100644 --- a/src/vm.h +++ b/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(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; }