add bytes

This commit is contained in:
blueloveTH 2023-04-22 21:34:31 +08:00
parent 5faac18935
commit d70b7653f2
4 changed files with 53 additions and 6 deletions

View File

@ -57,6 +57,13 @@ struct Range {
i64 step = 1;
};
struct Bytes{
std::string _data;
int size() const noexcept { return _data.size(); }
int operator[](int i) const noexcept { return (int)(uint8_t)_data[i]; }
};
using Super = std::pair<PyObject*, Type>;
// TODO: re-examine the design of Slice

View File

@ -412,6 +412,11 @@ inline void init_builtins(VM* _vm) {
return VAR(ok);
});
_vm->bind_method<0>("str", "encode", [](VM* vm, ArgsView args) {
const Str& self = CAST(Str&, args[0]);
return VAR(Bytes{self.str()});
});
_vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
const Str& self = CAST(Str&, args[0]);
FastStrStream ss;
@ -551,7 +556,7 @@ inline void init_builtins(VM* _vm) {
return VAR(self.size());
});
/************ PyBool ************/
/************ bool ************/
_vm->bind_static_method<1>("bool", "__new__", CPP_LAMBDA(VAR(vm->asBool(args[0]))));
_vm->bind_method<0>("bool", "__repr__", [](VM* vm, ArgsView args) {
@ -571,6 +576,39 @@ inline void init_builtins(VM* _vm) {
});
_vm->bind_method<0>("ellipsis", "__repr__", CPP_LAMBDA(VAR("Ellipsis")));
/************ bytes ************/
_vm->bind_static_method<1>("bytes", "__new__", CPP_NOT_IMPLEMENTED());
_vm->bind_method<1>("bytes", "__getitem__", [](VM* vm, ArgsView args) {
const Bytes& self = CAST(Bytes&, args[0]);
int index = CAST(int, args[1]);
index = vm->normalized_index(index, self.size());
return VAR(self[index]);
});
_vm->bind_method<0>("bytes", "__repr__", [](VM* vm, ArgsView args) {
const Bytes& self = CAST(Bytes&, args[0]);
std::stringstream ss;
ss << "b'";
for(int i=0; i<self.size(); i++){
ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << self[i];
}
ss << "'";
return VAR(ss.str());
});
_vm->bind_method<0>("bytes", "__len__", [](VM* vm, ArgsView args) {
const Bytes& self = CAST(Bytes&, args[0]);
return VAR(self.size());
});
_vm->bind_method<0>("bytes", "decode", [](VM* vm, ArgsView args) {
const Bytes& self = CAST(Bytes&, args[0]);
// TODO: check encoding is utf-8
return VAR(Str(self._data));
});
}
#ifdef _WIN32

View File

@ -207,11 +207,10 @@ struct Str{
case '\r': ss << "\\r"; break;
case '\t': ss << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f') {
ss << "\\u"
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c);
} else {
if (c >= 32 && c <= 126) {
ss << c;
} else {
ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << (int)(uint8_t)c;
}
}
}

View File

@ -102,7 +102,7 @@ public:
Type tp_list, tp_tuple;
Type tp_function, tp_native_func, tp_iterator, tp_bound_method;
Type tp_slice, tp_range, tp_module;
Type tp_super, tp_exception;
Type tp_super, tp_exception, tp_bytes;
VM(bool use_stdio) : heap(this){
this->vm = this;
@ -412,6 +412,7 @@ DEF_NATIVE_2(BoundMethod, tp_bound_method)
DEF_NATIVE_2(Range, tp_range)
DEF_NATIVE_2(Slice, tp_slice)
DEF_NATIVE_2(Exception, tp_exception)
DEF_NATIVE_2(Bytes, tp_bytes)
#define PY_CAST_INT(T) \
template<> inline T py_cast<T>(VM* vm, PyObject* obj){ \
@ -737,6 +738,7 @@ inline void VM::init_builtin_types(){
tp_bound_method = _new_type_object("bound_method");
tp_super = _new_type_object("super");
tp_exception = _new_type_object("Exception");
tp_bytes = _new_type_object("bytes");
this->None = heap._new<Dummy>(_new_type_object("NoneType"), {});
this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"), {});
@ -757,6 +759,7 @@ inline void VM::init_builtin_types(){
builtins->attr().set("list", _t(tp_list));
builtins->attr().set("tuple", _t(tp_tuple));
builtins->attr().set("range", _t(tp_range));
builtins->attr().set("bytes", _t(tp_bytes));
builtins->attr().set("StopIteration", StopIteration);
post_init();