This commit is contained in:
blueloveTH 2023-06-25 01:59:40 +08:00
parent 610635b93a
commit 2fddde4f9c
6 changed files with 88 additions and 44 deletions

View File

@ -105,6 +105,7 @@ def sorted(iterable, reverse=False, key=None):
##### str #####
def __f(self, sep=None):
flag = sep is None
sep = sep or ' '
if sep == "":
return list(self)
@ -118,9 +119,27 @@ def __f(self, sep=None):
else:
++i
res.append(self)
if flag:
return [i for i in res if i != '']
return res
str.split = __f
def __f(self, s: str):
if type(s) is not str:
raise TypeError('must be str, not ' + type(s).__name__)
if s == '':
return len(self) + 1
res = 0
i = 0
while i < len(self):
if self[i:i+len(s)] == s:
++res
i += len(s)
else:
++i
return res
str.count = __f
def __f(self, *args):
if '{}' in self:
for i in range(len(args)):

View File

@ -108,7 +108,7 @@ struct Type {
operator int() const noexcept { return this->index; }
};
#define CPP_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
#ifdef POCKETPY_H
#define FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!");

View File

@ -88,7 +88,7 @@ struct FileIO {
return vm->None;
});
vm->bind_method<0>(type, "__enter__", CPP_LAMBDA(vm->None));
vm->bind_method<0>(type, "__enter__", PK_LAMBDA(vm->None));
}
};

View File

@ -96,6 +96,15 @@ inline void init_builtins(VM* _vm) {
return VAR(MappingProxy(mod));
});
_vm->bind_builtin_func<3>("pow", [](VM* vm, ArgsView args) {
i64 lhs = CAST(i64, args[0]); // assume lhs>=0
i64 rhs = CAST(i64, args[1]); // assume rhs>=0
i64 mod = CAST(i64, args[2]); // assume mod>0, mod*mod should not overflow
if(rhs <= 0){
vm->ValueError("pow(): rhs should be positive");
}
static const auto _mul = [](i64 a, i64 b, i64 c){
if(c < 16384) return (a%c) * (b%c) % c;
i64 res = 0;
@ -107,10 +116,6 @@ inline void init_builtins(VM* _vm) {
return res;
};
_vm->bind_builtin_func<3>("pow", [](VM* vm, ArgsView args) {
i64 lhs = CAST(i64, args[0]); // assume lhs>=0
i64 rhs = CAST(i64, args[1]); // assume rhs>=0
i64 mod = CAST(i64, args[2]); // assume mod>0, mod*mod should not overflow
i64 res = 1;
lhs %= mod;
while(rhs){
@ -167,7 +172,7 @@ inline void init_builtins(VM* _vm) {
return vm->None;
});
_vm->bind_builtin_func<1>("repr", CPP_LAMBDA(vm->py_repr(args[0])));
_vm->bind_builtin_func<1>("repr", PK_LAMBDA(vm->py_repr(args[0])));
_vm->bind_builtin_func<1>("len", [](VM* vm, ArgsView args){
const PyTypeInfo* ti = vm->_inst_type_info(args[0]);
@ -268,7 +273,7 @@ inline void init_builtins(VM* _vm) {
return vm->heap.gcnew<DummyInstance>(t, {});
});
_vm->bind_constructor<2>("type", CPP_LAMBDA(vm->_t(args[1])));
_vm->bind_constructor<2>("type", PK_LAMBDA(vm->_t(args[1])));
_vm->bind_constructor<-1>("range", [](VM* vm, ArgsView args) {
args._begin += 1; // skip cls
@ -424,7 +429,7 @@ inline void init_builtins(VM* _vm) {
});
/************ str ************/
_vm->bind_constructor<2>("str", CPP_LAMBDA(vm->py_str(args[1])));
_vm->bind_constructor<2>("str", PK_LAMBDA(vm->py_str(args[1])));
_vm->bind__hash__(_vm->tp_str, [](VM* vm, PyObject* obj) {
return (i64)_CAST(Str&, obj).hash();
@ -488,6 +493,7 @@ inline void init_builtins(VM* _vm) {
if(args.size() != 1+2 && args.size() != 1+3) vm->TypeError("replace() takes 2 or 3 arguments");
const Str& self = _CAST(Str&, args[0]);
const Str& old = CAST(Str&, args[1]);
if(old.empty()) vm->ValueError("empty substring");
const Str& new_ = CAST(Str&, args[2]);
int count = args.size()==1+3 ? CAST(int, args[3]) : -1;
return VAR(self.replace(old, new_, count));
@ -652,7 +658,17 @@ inline void init_builtins(VM* _vm) {
_vm->bind__mul__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
const List& self = _CAST(List&, lhs);
int n = CAST(int, rhs);
if(!is_int(rhs)) return vm->NotImplemented;
int n = _CAST(int, rhs);
List result;
result.reserve(self.size() * n);
for(int i = 0; i < n; i++) result.extend(self);
return VAR(std::move(result));
});
_vm->bind_method<1>("list", "__rmul__", [](VM* vm, ArgsView args) {
const List& self = _CAST(List&, args[0]);
if(!is_int(args[1])) return vm->NotImplemented;
int n = _CAST(int, args[1]);
List result;
result.reserve(self.size() * n);
for(int i = 0; i < n; i++) result.extend(self);
@ -674,7 +690,7 @@ inline void init_builtins(VM* _vm) {
return vm->None;
});
_vm->bind_method<0>("list", "copy", CPP_LAMBDA(VAR(_CAST(List, args[0]))));
_vm->bind_method<0>("list", "copy", PK_LAMBDA(VAR(_CAST(List, args[0]))));
_vm->bind__hash__(_vm->tp_list, [](VM* vm, PyObject* obj) {
vm->TypeError("unhashable type: 'list'");
@ -761,7 +777,7 @@ inline void init_builtins(VM* _vm) {
});
/************ bool ************/
_vm->bind_constructor<2>("bool", CPP_LAMBDA(VAR(vm->py_bool(args[1]))));
_vm->bind_constructor<2>("bool", PK_LAMBDA(VAR(vm->py_bool(args[1]))));
_vm->bind__hash__(_vm->tp_bool, [](VM* vm, PyObject* obj) {
return (i64)_CAST(bool, obj);
});
@ -1251,9 +1267,9 @@ inline void add_module_math(VM* vm){
mod->attr().set("inf", VAR(std::numeric_limits<double>::infinity()));
mod->attr().set("nan", VAR(std::numeric_limits<double>::quiet_NaN()));
vm->bind_func<1>(mod, "ceil", CPP_LAMBDA(VAR((i64)std::ceil(CAST_F(args[0])))));
vm->bind_func<1>(mod, "fabs", CPP_LAMBDA(VAR(std::fabs(CAST_F(args[0])))));
vm->bind_func<1>(mod, "floor", CPP_LAMBDA(VAR((i64)std::floor(CAST_F(args[0])))));
vm->bind_func<1>(mod, "ceil", PK_LAMBDA(VAR((i64)std::ceil(CAST_F(args[0])))));
vm->bind_func<1>(mod, "fabs", PK_LAMBDA(VAR(std::fabs(CAST_F(args[0])))));
vm->bind_func<1>(mod, "floor", PK_LAMBDA(VAR((i64)std::floor(CAST_F(args[0])))));
vm->bind_func<1>(mod, "fsum", [](VM* vm, ArgsView args) {
List& list = CAST(List&, args[0]);
double sum = 0;
@ -1280,29 +1296,29 @@ inline void add_module_math(VM* vm){
return VAR(a);
});
vm->bind_func<1>(mod, "isfinite", CPP_LAMBDA(VAR(std::isfinite(CAST_F(args[0])))));
vm->bind_func<1>(mod, "isinf", CPP_LAMBDA(VAR(std::isinf(CAST_F(args[0])))));
vm->bind_func<1>(mod, "isnan", CPP_LAMBDA(VAR(std::isnan(CAST_F(args[0])))));
vm->bind_func<1>(mod, "isfinite", PK_LAMBDA(VAR(std::isfinite(CAST_F(args[0])))));
vm->bind_func<1>(mod, "isinf", PK_LAMBDA(VAR(std::isinf(CAST_F(args[0])))));
vm->bind_func<1>(mod, "isnan", PK_LAMBDA(VAR(std::isnan(CAST_F(args[0])))));
vm->bind_func<1>(mod, "exp", CPP_LAMBDA(VAR(std::exp(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log", CPP_LAMBDA(VAR(std::log(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log2", CPP_LAMBDA(VAR(std::log2(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log10", CPP_LAMBDA(VAR(std::log10(CAST_F(args[0])))));
vm->bind_func<1>(mod, "exp", PK_LAMBDA(VAR(std::exp(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log", PK_LAMBDA(VAR(std::log(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log2", PK_LAMBDA(VAR(std::log2(CAST_F(args[0])))));
vm->bind_func<1>(mod, "log10", PK_LAMBDA(VAR(std::log10(CAST_F(args[0])))));
vm->bind_func<2>(mod, "pow", CPP_LAMBDA(VAR(std::pow(CAST_F(args[0]), CAST_F(args[1])))));
vm->bind_func<1>(mod, "sqrt", CPP_LAMBDA(VAR(std::sqrt(CAST_F(args[0])))));
vm->bind_func<2>(mod, "pow", PK_LAMBDA(VAR(std::pow(CAST_F(args[0]), CAST_F(args[1])))));
vm->bind_func<1>(mod, "sqrt", PK_LAMBDA(VAR(std::sqrt(CAST_F(args[0])))));
vm->bind_func<1>(mod, "acos", CPP_LAMBDA(VAR(std::acos(CAST_F(args[0])))));
vm->bind_func<1>(mod, "asin", CPP_LAMBDA(VAR(std::asin(CAST_F(args[0])))));
vm->bind_func<1>(mod, "atan", CPP_LAMBDA(VAR(std::atan(CAST_F(args[0])))));
vm->bind_func<2>(mod, "atan2", CPP_LAMBDA(VAR(std::atan2(CAST_F(args[0]), CAST_F(args[1])))));
vm->bind_func<1>(mod, "acos", PK_LAMBDA(VAR(std::acos(CAST_F(args[0])))));
vm->bind_func<1>(mod, "asin", PK_LAMBDA(VAR(std::asin(CAST_F(args[0])))));
vm->bind_func<1>(mod, "atan", PK_LAMBDA(VAR(std::atan(CAST_F(args[0])))));
vm->bind_func<2>(mod, "atan2", PK_LAMBDA(VAR(std::atan2(CAST_F(args[0]), CAST_F(args[1])))));
vm->bind_func<1>(mod, "cos", CPP_LAMBDA(VAR(std::cos(CAST_F(args[0])))));
vm->bind_func<1>(mod, "sin", CPP_LAMBDA(VAR(std::sin(CAST_F(args[0])))));
vm->bind_func<1>(mod, "tan", CPP_LAMBDA(VAR(std::tan(CAST_F(args[0])))));
vm->bind_func<1>(mod, "cos", PK_LAMBDA(VAR(std::cos(CAST_F(args[0])))));
vm->bind_func<1>(mod, "sin", PK_LAMBDA(VAR(std::sin(CAST_F(args[0])))));
vm->bind_func<1>(mod, "tan", PK_LAMBDA(VAR(std::tan(CAST_F(args[0])))));
vm->bind_func<1>(mod, "degrees", CPP_LAMBDA(VAR(CAST_F(args[0]) * 180 / 3.1415926535897932384)));
vm->bind_func<1>(mod, "radians", CPP_LAMBDA(VAR(CAST_F(args[0]) * 3.1415926535897932384 / 180)));
vm->bind_func<1>(mod, "degrees", PK_LAMBDA(VAR(CAST_F(args[0]) * 180 / 3.1415926535897932384)));
vm->bind_func<1>(mod, "radians", PK_LAMBDA(VAR(CAST_F(args[0]) * 3.1415926535897932384 / 180)));
vm->bind_func<1>(mod, "modf", [](VM* vm, ArgsView args) {
f64 i;
@ -1354,13 +1370,13 @@ inline void add_module_dis(VM* vm){
inline void add_module_gc(VM* vm){
PyObject* mod = vm->new_module("gc");
vm->bind_func<0>(mod, "collect", CPP_LAMBDA(VAR(vm->heap.collect())));
vm->bind_func<0>(mod, "collect", PK_LAMBDA(VAR(vm->heap.collect())));
}
inline void VM::post_init(){
init_builtins(this);
_t(tp_object)->attr().set("__class__", property(CPP_LAMBDA(vm->_t(args[0]))));
_t(tp_object)->attr().set("__class__", property(PK_LAMBDA(vm->_t(args[0]))));
_t(tp_type)->attr().set("__base__", property([](VM* vm, ArgsView args){
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj;

View File

@ -18,8 +18,8 @@ struct ReMatch {
static void _register(VM* vm, PyObject* mod, PyObject* type){
vm->bind_notimplemented_constructor<ReMatch>(type);
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end)));
vm->bind_method<0>(type, "start", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
vm->bind_method<0>(type, "end", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end)));
vm->bind_method<0>(type, "span", [](VM* vm, ArgsView args) {
auto& self = _CAST(ReMatch&, args[0]);

View File

@ -42,6 +42,15 @@ assert t.split('w') == ['this is string example....', 'o', '!!!']
assert "a,b,c".split(',') == ['a', 'b', 'c']
assert 'a,'.split(',') == ['a', '']
assert 'foo!!bar!!baz'.split('!!') == ['foo', 'bar', 'baz']
assert ' 4 3 '.split() == ['4', '3']
assert ' 4 3 '.split(' ') == ['', '', '4', '3', '', '']
assert '111'.count('1') == 3
assert '111'.count('11') == 1
assert '1111'.count('11') == 2
assert '11'.count('') == 3
assert ''.count('1') == 0
assert ''.count('') == 1
t = "*****this is **string** example....wow!!!*****"
s = "123abcrunoob321"