mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
add list.sort
impl (quick sort)
This commit is contained in:
parent
2362e88ea0
commit
cb93e0ec25
@ -46,18 +46,13 @@ def zip(a, b):
|
|||||||
|
|
||||||
def reversed(iterable):
|
def reversed(iterable):
|
||||||
a = list(iterable)
|
a = list(iterable)
|
||||||
return [a[i] for i in range(len(a)-1, -1, -1)]
|
a.reverse()
|
||||||
|
return a
|
||||||
|
|
||||||
def sorted(iterable, key=None, reverse=False):
|
def sorted(iterable, reverse=False):
|
||||||
b = list(iterable)
|
a = list(iterable)
|
||||||
a = (key is None) ? b : [key(i) for i in iterable]
|
a.sort(reverse=reverse)
|
||||||
for i in range(len(a)):
|
return a
|
||||||
for j in range(i+1, len(a)):
|
|
||||||
if (a[i] > a[j]) ^ reverse:
|
|
||||||
if a is not b:
|
|
||||||
a[i], a[j] = a[j], a[i]
|
|
||||||
b[i], b[j] = b[j], b[i]
|
|
||||||
return b
|
|
||||||
|
|
||||||
##### str #####
|
##### str #####
|
||||||
|
|
||||||
@ -107,6 +102,45 @@ tuple.__repr__ = lambda self: '(' + ', '.join([repr(i) for i in self]) + ')'
|
|||||||
list.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
|
list.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
|
||||||
tuple.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
|
tuple.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
|
||||||
|
|
||||||
|
def __qsort(a: list, i: int, j: int):
|
||||||
|
if i>=j:
|
||||||
|
return
|
||||||
|
d1, d2 = i, j
|
||||||
|
mid = (i+j) // 2
|
||||||
|
a[mid], a[i] = a[i], a[mid]
|
||||||
|
u = a[i];
|
||||||
|
while i < j:
|
||||||
|
while i<j and a[j]>u:
|
||||||
|
j -= 1
|
||||||
|
if i<j:
|
||||||
|
a[i] = a[j]
|
||||||
|
i += 1
|
||||||
|
while i<j and a[i]<u:
|
||||||
|
i += 1
|
||||||
|
if i<j:
|
||||||
|
a[j] = a[i]
|
||||||
|
j -= 1
|
||||||
|
a[i] = u;
|
||||||
|
__qsort(a, d1, i-1)
|
||||||
|
__qsort(a, i+1, d2)
|
||||||
|
|
||||||
|
def __list4reverse(self):
|
||||||
|
i, j = 0, len(self)-1
|
||||||
|
while i < j:
|
||||||
|
self[i], self[j] = self[j], self[i]
|
||||||
|
i += 1
|
||||||
|
j -= 1
|
||||||
|
list.reverse = __list4reverse
|
||||||
|
del __list4reverse
|
||||||
|
|
||||||
|
def __list4sort(self, reverse=False):
|
||||||
|
__qsort(self, 0, len(self)-1)
|
||||||
|
if reverse:
|
||||||
|
self.reverse()
|
||||||
|
|
||||||
|
list.sort = __list4sort
|
||||||
|
del __list4sort
|
||||||
|
|
||||||
def __list4extend(self, other):
|
def __list4extend(self, other):
|
||||||
for i in other:
|
for i in other:
|
||||||
self.append(i)
|
self.append(i)
|
||||||
|
@ -139,7 +139,7 @@ struct Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Str stack_info(){
|
Str stack_info(){
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << "[";
|
ss << "[";
|
||||||
for(int i=0; i<_data.size(); i++){
|
for(int i=0; i<_data.size(); i++){
|
||||||
ss << OBJ_TP_NAME(_data[i]);
|
ss << OBJ_TP_NAME(_data[i]);
|
||||||
|
@ -31,13 +31,12 @@
|
|||||||
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PK_VERSION "0.8.4"
|
#define PK_VERSION "0.8.5"
|
||||||
|
|
||||||
typedef int64_t i64;
|
typedef int64_t i64;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
||||||
struct Dummy { char _; };
|
struct Dummy { char _; };
|
||||||
|
|
||||||
#define DUMMY_VAL Dummy()
|
#define DUMMY_VAL Dummy()
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -319,7 +319,7 @@ private:
|
|||||||
|
|
||||||
void consume(TokenIndex expected) {
|
void consume(TokenIndex expected) {
|
||||||
if (!match(expected)){
|
if (!match(expected)){
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << "expected '" << TK_STR(expected) << "', but got '" << TK_STR(peek()) << "'";
|
ss << "expected '" << TK_STR(expected) << "', but got '" << TK_STR(peek()) << "'";
|
||||||
SyntaxError(ss.str());
|
SyntaxError(ss.str());
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ struct SourceData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Str snapshot(int lineno, const char* cursor=nullptr){
|
Str snapshot(int lineno, const char* cursor=nullptr){
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
|
ss << " " << "File \"" << filename << "\", line " << lineno << '\n';
|
||||||
std::pair<const char*,const char*> pair = get_line(lineno);
|
std::pair<const char*,const char*> pair = get_line(lineno);
|
||||||
Str line = "<?>";
|
Str line = "<?>";
|
||||||
@ -83,7 +83,7 @@ public:
|
|||||||
|
|
||||||
Str summary() const {
|
Str summary() const {
|
||||||
std::stack<Str> st(stacktrace);
|
std::stack<Str> st(stacktrace);
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
if(is_re) ss << "Traceback (most recent call last):\n";
|
if(is_re) ss << "Traceback (most recent call last):\n";
|
||||||
while(!st.empty()) { ss << st.top() << '\n'; st.pop(); }
|
while(!st.empty()) { ss << st.top() << '\n'; st.pop(); }
|
||||||
ss << type << ": " << msg;
|
ss << type << ": " << msg;
|
||||||
|
@ -56,7 +56,7 @@ struct Token{
|
|||||||
const Str str() const { return Str(start, length);}
|
const Str str() const { return Str(start, length);}
|
||||||
|
|
||||||
const Str info() const {
|
const Str info() const {
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
Str raw = str();
|
Str raw = str();
|
||||||
if (raw == Str("\n")) raw = "\\n";
|
if (raw == Str("\n")) raw = "\\n";
|
||||||
ss << line << ": " << TK_STR(type) << " '" << raw << "'";
|
ss << line << ": " << TK_STR(type) << " '" << raw << "'";
|
||||||
|
@ -256,7 +256,7 @@ void init_builtins(VM* _vm) {
|
|||||||
_vm->bind_method<0>("float", "__repr__", [](VM* vm, const pkpy::Args& args) {
|
_vm->bind_method<0>("float", "__repr__", [](VM* vm, const pkpy::Args& args) {
|
||||||
f64 val = vm->PyFloat_AS_C(args[0]);
|
f64 val = vm->PyFloat_AS_C(args[0]);
|
||||||
if(std::isinf(val) || std::isnan(val)) return vm->PyStr(std::to_string(val));
|
if(std::isinf(val) || std::isnan(val)) return vm->PyStr(std::to_string(val));
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << std::setprecision(std::numeric_limits<f64>::max_digits10-1) << val;
|
ss << std::setprecision(std::numeric_limits<f64>::max_digits10-1) << val;
|
||||||
std::string s = ss.str();
|
std::string s = ss.str();
|
||||||
if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0";
|
if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0";
|
||||||
@ -371,7 +371,7 @@ void init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind_method<1>("str", "join", [](VM* vm, const pkpy::Args& args) {
|
_vm->bind_method<1>("str", "join", [](VM* vm, const pkpy::Args& args) {
|
||||||
const Str& self = vm->PyStr_AS_C(args[0]);
|
const Str& self = vm->PyStr_AS_C(args[0]);
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
if(args[1]->is_type(vm->tp_list)){
|
if(args[1]->is_type(vm->tp_list)){
|
||||||
const pkpy::List& a = vm->PyList_AS_C(args[1]);
|
const pkpy::List& a = vm->PyList_AS_C(args[1]);
|
||||||
for(int i = 0; i < a.size(); i++){
|
for(int i = 0; i < a.size(); i++){
|
||||||
@ -793,11 +793,11 @@ extern "C" {
|
|||||||
/// Return a json representing the result.
|
/// Return a json representing the result.
|
||||||
char* pkpy_vm_read_output(VM* vm){
|
char* pkpy_vm_read_output(VM* vm){
|
||||||
if(vm->use_stdio) return nullptr;
|
if(vm->use_stdio) return nullptr;
|
||||||
_StrStream* s_out = (_StrStream*)(vm->_stdout);
|
StrStream* s_out = (StrStream*)(vm->_stdout);
|
||||||
_StrStream* s_err = (_StrStream*)(vm->_stderr);
|
StrStream* s_err = (StrStream*)(vm->_stderr);
|
||||||
Str _stdout = s_out->str();
|
Str _stdout = s_out->str();
|
||||||
Str _stderr = s_err->str();
|
Str _stderr = s_err->str();
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << '{' << "\"stdout\": " << _stdout.escape(false);
|
ss << '{' << "\"stdout\": " << _stdout.escape(false);
|
||||||
ss << ", " << "\"stderr\": " << _stderr.escape(false) << '}';
|
ss << ", " << "\"stderr\": " << _stderr.escape(false) << '}';
|
||||||
s_out->str(""); s_err->str("");
|
s_out->str(""); s_err->str("");
|
||||||
@ -836,7 +836,7 @@ extern "C" {
|
|||||||
std::string f_header = std::string(mod) + '.' + name + '#' + std::to_string(kGlobalBindId++);
|
std::string f_header = std::string(mod) + '.' + name + '#' + std::to_string(kGlobalBindId++);
|
||||||
PyVar obj = vm->_modules.contains(mod) ? vm->_modules[mod] : vm->new_module(mod);
|
PyVar obj = vm->_modules.contains(mod) ? vm->_modules[mod] : vm->new_module(mod);
|
||||||
vm->bind_func<-1>(obj, name, [ret_code, f_header](VM* vm, const pkpy::Args& args){
|
vm->bind_func<-1>(obj, name, [ret_code, f_header](VM* vm, const pkpy::Args& args){
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << f_header;
|
ss << f_header;
|
||||||
for(int i=0; i<args.size(); i++){
|
for(int i=0; i<args.size(); i++){
|
||||||
ss << ' ';
|
ss << ' ';
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
typedef std::stringstream _StrStream;
|
typedef std::stringstream StrStream;
|
||||||
|
|
||||||
class Str : public std::string {
|
class Str : public std::string {
|
||||||
mutable std::vector<uint16_t>* _u8_index = nullptr;
|
mutable std::vector<uint16_t>* _u8_index = nullptr;
|
||||||
@ -85,7 +85,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Str escape(bool single_quote) const {
|
Str escape(bool single_quote) const {
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << (single_quote ? '\'' : '"');
|
ss << (single_quote ? '\'' : '"');
|
||||||
for (int i=0; i<length(); i++) {
|
for (int i=0; i<length(); i++) {
|
||||||
char c = this->operator[](i);
|
char c = this->operator[](i);
|
||||||
|
14
src/vm.h
14
src/vm.h
@ -78,7 +78,7 @@ class VM {
|
|||||||
case OP_BUILD_STRING:
|
case OP_BUILD_STRING:
|
||||||
{
|
{
|
||||||
pkpy::Args items = frame->pop_n_values_reversed(this, byte.arg);
|
pkpy::Args items = frame->pop_n_values_reversed(this, byte.arg);
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
for(int i=0; i<items.size(); i++) ss << PyStr_AS_C(asStr(items[i]));
|
for(int i=0; i<items.size(); i++) ss << PyStr_AS_C(asStr(items[i]));
|
||||||
frame->push(PyStr(ss.str()));
|
frame->push(PyStr(ss.str()));
|
||||||
} break;
|
} break;
|
||||||
@ -347,13 +347,11 @@ public:
|
|||||||
VM(bool use_stdio){
|
VM(bool use_stdio){
|
||||||
this->use_stdio = use_stdio;
|
this->use_stdio = use_stdio;
|
||||||
if(use_stdio){
|
if(use_stdio){
|
||||||
std::cout.setf(std::ios::unitbuf);
|
|
||||||
std::cerr.setf(std::ios::unitbuf);
|
|
||||||
this->_stdout = &std::cout;
|
this->_stdout = &std::cout;
|
||||||
this->_stderr = &std::cerr;
|
this->_stderr = &std::cerr;
|
||||||
}else{
|
}else{
|
||||||
this->_stdout = new _StrStream();
|
this->_stdout = new StrStream();
|
||||||
this->_stderr = new _StrStream();
|
this->_stderr = new StrStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_builtin_types();
|
init_builtin_types();
|
||||||
@ -731,7 +729,7 @@ public:
|
|||||||
jumpTargets.push_back(byte.arg);
|
jumpTargets.push_back(byte.arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_StrStream ss;
|
StrStream ss;
|
||||||
ss << std::string(54, '-') << '\n';
|
ss << std::string(54, '-') << '\n';
|
||||||
ss << co->name << ":\n";
|
ss << co->name << ":\n";
|
||||||
int prev_line = -1;
|
int prev_line = -1;
|
||||||
@ -764,11 +762,11 @@ public:
|
|||||||
ss << co->blocks[byte.block].to_string();
|
ss << co->blocks[byte.block].to_string();
|
||||||
if(i != co->codes.size() - 1) ss << '\n';
|
if(i != co->codes.size() - 1) ss << '\n';
|
||||||
}
|
}
|
||||||
_StrStream consts;
|
StrStream consts;
|
||||||
consts << "co_consts: ";
|
consts << "co_consts: ";
|
||||||
consts << PyStr_AS_C(asRepr(PyList(co->consts)));
|
consts << PyStr_AS_C(asRepr(PyList(co->consts)));
|
||||||
|
|
||||||
_StrStream names;
|
StrStream names;
|
||||||
names << "co_names: ";
|
names << "co_names: ";
|
||||||
pkpy::List list;
|
pkpy::List list;
|
||||||
for(int i=0; i<co->names.size(); i++){
|
for(int i=0; i<co->names.size(); i++){
|
||||||
|
@ -180,8 +180,7 @@ assert result == [1, 'a', 2, 'b', 3, 'c']
|
|||||||
|
|
||||||
a = [1,2,3,-1]
|
a = [1,2,3,-1]
|
||||||
assert sorted(a) == [-1,1,2,3]
|
assert sorted(a) == [-1,1,2,3]
|
||||||
assert sorted(a, lambda x:-x) == [3,2,1,-1]
|
assert sorted(a, reverse=True) == [3,2,1,-1]
|
||||||
assert sorted(a, None, True) == [3,2,1,-1]
|
|
||||||
|
|
||||||
assert abs(0) == 0
|
assert abs(0) == 0
|
||||||
assert abs(1.0) == 1.0
|
assert abs(1.0) == 1.0
|
||||||
|
@ -15,6 +15,16 @@ assert a == [2, 3]
|
|||||||
assert a.pop(-2) == 2
|
assert a.pop(-2) == 2
|
||||||
assert a == [3]
|
assert a == [3]
|
||||||
|
|
||||||
|
a = []
|
||||||
|
a.sort()
|
||||||
|
assert len(a) == 0
|
||||||
|
assert a == []
|
||||||
|
|
||||||
|
a = [1]
|
||||||
|
a.sort()
|
||||||
|
assert len(a) == 1
|
||||||
|
assert a == [1]
|
||||||
|
|
||||||
a = [1, 2, 3, 4]
|
a = [1, 2, 3, 4]
|
||||||
assert reversed(a) == [4, 3, 2, 1]
|
assert reversed(a) == [4, 3, 2, 1]
|
||||||
assert a == [1, 2, 3, 4]
|
assert a == [1, 2, 3, 4]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user