Browse Source

fix https://github.com/blueloveTH/pocketpy/issues/65

blueloveTH 2 năm trước cách đây
mục cha
commit
cb36966464
4 tập tin đã thay đổi với 31 bổ sung13 xóa
  1. 8 5
      python/builtins.py
  2. 12 2
      src/pocketpy.h
  3. 4 5
      src/str.h
  4. 7 1
      tests/04_str.py

+ 8 - 5
python/builtins.py

@@ -86,11 +86,14 @@ def str::split(self, sep):
     res.append(self)
     return res
 
-def str::index(self, sub):
-    for i in range(len(self)):
-        if self[i:i+len(sub)] == sub:
-            return i
-    return -1
+def str::format(self, *args):
+    if '{}' in self:
+        for i in range(len(args)):
+            self = self.replace('{}', str(args[i]), 1)
+    else:
+        for i in range(len(args)):
+            self = self.replace('{'+str(i)+'}', str(args[i]))
+    return self
 
 def str::strip(self, chars=None):
     chars = chars or ' \t\n\r'

+ 12 - 2
src/pocketpy.h

@@ -390,11 +390,21 @@ inline void init_builtins(VM* _vm) {
         return VAR(self < obj);
     });
 
-    _vm->bind_method<2>("str", "replace", [](VM* vm, ArgsView args) {
+    _vm->bind_method<-1>("str", "replace", [](VM* vm, ArgsView args) {
+        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]);
         const Str& new_ = CAST(Str&, args[2]);
-        return VAR(self.replace(old, new_));
+        int count = args.size()==1+3 ? CAST(int, args[3]) : -1;
+        return VAR(self.replace(old, new_, count));
+    });
+
+    _vm->bind_method<1>("str", "index", [](VM* vm, ArgsView args) {
+        const Str& self = CAST(Str&, args[0]);
+        const Str& sub = CAST(Str&, args[1]);
+        int index = self.index(sub);
+        if(index == -1) vm->ValueError("substring not found");
+        return VAR(index);
     });
 
     _vm->bind_method<1>("str", "startswith", [](VM* vm, ArgsView args) {

+ 4 - 5
src/str.h

@@ -224,19 +224,18 @@ struct Str{
         return p - data;
     }
 
-    Str replace(const Str& old, const Str& new_) const {
+    Str replace(const Str& old, const Str& new_, int count=-1) const {
         std::stringstream ss;
         int start = 0;
         while(true){
             int i = index(old, start);
-            if(i == -1){
-                ss << substr(start, size - start);
-                break;
-            }
+            if(i == -1) break;
             ss << substr(start, i - start);
             ss << new_;
             start = i + old.size;
+            if(count != -1 && --count == 0) break;
         }
+        ss << substr(start, size - start);
         return ss.str();
     }
 

+ 7 - 1
tests/04_str.py

@@ -75,4 +75,10 @@ assert str(num) == '6'
 # test Lo group names
 
 测试 = "test"
-assert 测试 == "test"
+assert 测试 == "test"
+
+assert "Hello, {}!".format("World") == "Hello, World!"
+assert "{} {} {}".format("I", "love", "Python") == "I love Python"
+assert "{0} {1} {2}".format("I", "love", "Python") == "I love Python"
+assert "{2} {1} {0}".format("I", "love", "Python") == "Python love I"
+assert "{0}{1}{0}".format("abra", "cad") == "abracadabra"