mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
...
This commit is contained in:
parent
289ddab5f7
commit
88c80a2340
@ -21,7 +21,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#define PK_VERSION "1.1.7"
|
#define PK_VERSION "1.1.8"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
@ -74,7 +74,8 @@ struct Str{
|
|||||||
int index(const Str& sub, int start=0) const;
|
int index(const Str& sub, int start=0) const;
|
||||||
Str replace(char old, char new_) const;
|
Str replace(char old, char new_) const;
|
||||||
Str replace(const Str& old, const Str& new_, int count=-1) const;
|
Str replace(const Str& old, const Str& new_, int count=-1) const;
|
||||||
std::vector<std::string_view> split(const Str& sep, bool remove_empty) const;
|
std::vector<std::string_view> split(const Str& sep) const;
|
||||||
|
int count(const Str& sub) const;
|
||||||
|
|
||||||
/*************unicode*************/
|
/*************unicode*************/
|
||||||
int _unicode_index_to_byte(int i) const;
|
int _unicode_index_to_byte(int i) const;
|
||||||
|
@ -7,7 +7,9 @@ def print(*args, sep=' ', end='\n'):
|
|||||||
def abs(x):
|
def abs(x):
|
||||||
return -x if x < 0 else x
|
return -x if x < 0 else x
|
||||||
|
|
||||||
def max(*args):
|
def max(*args, key=None):
|
||||||
|
if key is None:
|
||||||
|
key = lambda x: x
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
raise TypeError('max expected 1 arguments, got 0')
|
raise TypeError('max expected 1 arguments, got 0')
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
@ -20,11 +22,13 @@ def max(*args):
|
|||||||
i = next(args)
|
i = next(args)
|
||||||
if i is StopIteration:
|
if i is StopIteration:
|
||||||
break
|
break
|
||||||
if i > res:
|
if key(i) > key(res):
|
||||||
res = i
|
res = i
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def min(*args):
|
def min(*args, key=None):
|
||||||
|
if key is None:
|
||||||
|
key = lambda x: x
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
raise TypeError('min expected 1 arguments, got 0')
|
raise TypeError('min expected 1 arguments, got 0')
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
@ -37,7 +41,7 @@ def min(*args):
|
|||||||
i = next(args)
|
i = next(args)
|
||||||
if i is StopIteration:
|
if i is StopIteration:
|
||||||
break
|
break
|
||||||
if i < res:
|
if key(i) < key(res):
|
||||||
res = i
|
res = i
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -95,42 +99,6 @@ def sorted(iterable, reverse=False, key=None):
|
|||||||
return a
|
return a
|
||||||
|
|
||||||
##### str #####
|
##### str #####
|
||||||
def __f(self, sep=None):
|
|
||||||
flag = sep is None
|
|
||||||
sep = sep or ' '
|
|
||||||
if sep == "":
|
|
||||||
return list(self)
|
|
||||||
res = []
|
|
||||||
i = 0
|
|
||||||
while i < len(self):
|
|
||||||
if self[i:i+len(sep)] == sep:
|
|
||||||
res.append(self[:i])
|
|
||||||
self = self[i+len(sep):]
|
|
||||||
i = 0
|
|
||||||
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):
|
def __f(self, *args):
|
||||||
if '{}' in self:
|
if '{}' in self:
|
||||||
for i in range(len(args)):
|
for i in range(len(args)):
|
||||||
|
@ -560,12 +560,18 @@ void init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind(_vm->_t(_vm->tp_str), "split(self, sep=' ')", [](VM* vm, ArgsView args) {
|
_vm->bind(_vm->_t(_vm->tp_str), "split(self, sep=' ')", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
std::vector<std::string_view> parts = self.split(CAST(Str&, args[1]), false);
|
std::vector<std::string_view> parts = self.split(CAST(Str&, args[1]));
|
||||||
List ret(parts.size());
|
List ret(parts.size());
|
||||||
for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
|
for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
|
||||||
return VAR(std::move(ret));
|
return VAR(std::move(ret));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_vm->bind(_vm->_t(_vm->tp_str), "count(self, s: str)", [](VM* vm, ArgsView args) {
|
||||||
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
|
const Str& s = CAST(Str&, args[1]);
|
||||||
|
return VAR(self.count(s));
|
||||||
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>("str", "index", [](VM* vm, ArgsView args) {
|
_vm->bind_method<1>("str", "index", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
const Str& sub = CAST(Str&, args[1]);
|
const Str& sub = CAST(Str&, args[1]);
|
||||||
|
19
src/str.cpp
19
src/str.cpp
@ -316,7 +316,7 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
return _byte_index_to_unicode(size);
|
return _byte_index_to_unicode(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string_view> Str::split(const Str& sep, bool remove_empty) const{
|
std::vector<std::string_view> Str::split(const Str& sep) const{
|
||||||
std::vector<std::string_view> result;
|
std::vector<std::string_view> result;
|
||||||
std::string_view tmp;
|
std::string_view tmp;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
@ -324,14 +324,27 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
int i = index(sep, start);
|
int i = index(sep, start);
|
||||||
if(i == -1) break;
|
if(i == -1) break;
|
||||||
tmp = sv().substr(start, i - start);
|
tmp = sv().substr(start, i - start);
|
||||||
if(!remove_empty || !tmp.empty()) result.push_back(tmp);
|
if(!tmp.empty()) result.push_back(tmp);
|
||||||
start = i + sep.size;
|
start = i + sep.size;
|
||||||
}
|
}
|
||||||
tmp = sv().substr(start, size - start);
|
tmp = sv().substr(start, size - start);
|
||||||
if(!remove_empty || !tmp.empty()) result.push_back(tmp);
|
if(!tmp.empty()) result.push_back(tmp);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Str::count(const Str& sub) const{
|
||||||
|
if(sub.empty()) return size + 1;
|
||||||
|
int cnt = 0;
|
||||||
|
int start = 0;
|
||||||
|
while(true){
|
||||||
|
int i = index(sub, start);
|
||||||
|
if(i == -1) break;
|
||||||
|
cnt++;
|
||||||
|
start = i + sub.size;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const StrName& sn){
|
std::ostream& operator<<(std::ostream& os, const StrName& sn){
|
||||||
return os << sn.sv();
|
return os << sn.sv();
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ namespace pkpy{
|
|||||||
Str curr_path = _import_context.pending.back();
|
Str curr_path = _import_context.pending.back();
|
||||||
bool curr_is_init = _import_context.pending_is_init.back();
|
bool curr_is_init = _import_context.pending_is_init.back();
|
||||||
// convert relative path to absolute path
|
// convert relative path to absolute path
|
||||||
std::vector<std::string_view> cpnts = curr_path.split(".", true);
|
std::vector<std::string_view> cpnts = curr_path.split(".");
|
||||||
int prefix = 0; // how many dots in the prefix
|
int prefix = 0; // how many dots in the prefix
|
||||||
for(int i=0; i<path.length(); i++){
|
for(int i=0; i<path.length(); i++){
|
||||||
if(path[i] == '.') prefix++;
|
if(path[i] == '.') prefix++;
|
||||||
@ -251,7 +251,7 @@ namespace pkpy{
|
|||||||
PK_ASSERT(path.begin()[0] != '.');
|
PK_ASSERT(path.begin()[0] != '.');
|
||||||
PK_ASSERT(path.end()[-1] != '.');
|
PK_ASSERT(path.end()[-1] != '.');
|
||||||
|
|
||||||
auto path_cpnts = path.split(".", true);
|
auto path_cpnts = path.split(".");
|
||||||
|
|
||||||
// check circular import
|
// check circular import
|
||||||
if(_import_context.pending.size() > 128){
|
if(_import_context.pending.size() > 128){
|
||||||
|
@ -42,10 +42,10 @@ assert t.startswith('this') == True;
|
|||||||
|
|
||||||
assert t.split('w') == ['this is string example....', 'o', '!!!']
|
assert t.split('w') == ['this is string example....', 'o', '!!!']
|
||||||
assert "a,b,c".split(',') == ['a', 'b', 'c']
|
assert "a,b,c".split(',') == ['a', 'b', 'c']
|
||||||
assert 'a,'.split(',') == ['a', '']
|
assert 'a,'.split(',') == ['a']
|
||||||
assert 'foo!!bar!!baz'.split('!!') == ['foo', 'bar', 'baz']
|
assert 'foo!!bar!!baz'.split('!!') == ['foo', 'bar', 'baz']
|
||||||
assert ' 4 3 '.split() == ['4', '3']
|
assert ' 4 3 '.split() == ['4', '3']
|
||||||
assert ' 4 3 '.split(' ') == ['', '', '4', '3', '', '']
|
assert ' 4 3 '.split(' ') == ['4', '3']
|
||||||
|
|
||||||
assert '111'.count('1') == 3
|
assert '111'.count('1') == 3
|
||||||
assert '111'.count('11') == 1
|
assert '111'.count('11') == 1
|
||||||
|
@ -1120,3 +1120,20 @@ import dis
|
|||||||
def aaa():
|
def aaa():
|
||||||
pass
|
pass
|
||||||
assert dis.dis(aaa) is None
|
assert dis.dis(aaa) is None
|
||||||
|
|
||||||
|
# test min/max
|
||||||
|
assert min(1, 2) == 1
|
||||||
|
assert min(1, 2, 3) == 1
|
||||||
|
assert min([1, 2]) == 1
|
||||||
|
assert min([1, 2], key=lambda x: -x) == 2
|
||||||
|
|
||||||
|
assert max(1, 2) == 2
|
||||||
|
assert max(1, 2, 3) == 3
|
||||||
|
assert max([1, 2]) == 2
|
||||||
|
assert max([1, 2], key=lambda x: -x) == 1
|
||||||
|
|
||||||
|
assert min([
|
||||||
|
(1, 2),
|
||||||
|
(1, 3),
|
||||||
|
(1, 4),
|
||||||
|
]) == (1, 2)
|
Loading…
x
Reference in New Issue
Block a user