blueloveTH vor 2 Jahren
Ursprung
Commit
d70b7653f2
4 geänderte Dateien mit 53 neuen und 6 gelöschten Zeilen
  1. 7 0
      src/obj.h
  2. 39 1
      src/pocketpy.h
  3. 3 4
      src/str.h
  4. 4 1
      src/vm.h

+ 7 - 0
src/obj.h

@@ -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

+ 39 - 1
src/pocketpy.h

@@ -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

+ 3 - 4
src/str.h

@@ -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;
                     }
             }
         }

+ 4 - 1
src/vm.h

@@ -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();