add list.sort impl (quick sort)

This commit is contained in:
blueloveTH 2023-02-10 21:32:13 +08:00
parent 2362e88ea0
commit cb93e0ec25
11 changed files with 76 additions and 36 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 << "'";

View File

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

View File

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

View File

@ -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++){

View File

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

View File

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