mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
79012a6b08
commit
a4718a00b2
@ -42,7 +42,6 @@ void c11_string__ctor2(c11_string* self, const char* data, int size);
|
||||
c11_string* c11_string__copy(c11_string* self);
|
||||
void c11_string__delete(c11_string* self);
|
||||
c11_sv c11_string__sv(c11_string* self);
|
||||
c11_string* c11_string__replace(c11_string* self, char old, char new_);
|
||||
|
||||
int c11_string__u8_length(c11_string* self);
|
||||
c11_sv c11_string__u8_getitem(c11_string* self, int i);
|
||||
@ -56,6 +55,9 @@ int c11_sv__index(c11_sv self, char c);
|
||||
int c11_sv__index2(c11_sv self, c11_sv sub, int start);
|
||||
int c11_sv__count(c11_sv self, c11_sv sub);
|
||||
|
||||
c11_string* c11_sv__replace(c11_sv self, char old, char new_);
|
||||
c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_);
|
||||
|
||||
c11_vector/* T=c11_sv */ c11_sv__split(c11_sv self, char sep);
|
||||
c11_vector/* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep);
|
||||
|
||||
|
@ -70,6 +70,9 @@ void pk_VM__dtor(pk_VM* self);
|
||||
void pk_VM__push_frame(pk_VM* self, Frame* frame);
|
||||
void pk_VM__pop_frame(pk_VM* self);
|
||||
|
||||
bool pk__parse_int_slice(const py_Ref slice, int length, int* start, int* stop, int* step);
|
||||
bool pk__normalize_index(int* index, int length);
|
||||
|
||||
typedef enum pk_FrameResult {
|
||||
RES_RETURN,
|
||||
RES_CALL,
|
||||
|
@ -296,6 +296,7 @@ bool py_str(py_Ref val);
|
||||
py_GlobalRef py_retval();
|
||||
|
||||
#define py_isnil(self) ((self)->type == 0)
|
||||
#define py_isnone(self) ((self)->type == tp_none_type)
|
||||
|
||||
/* tuple */
|
||||
|
||||
@ -334,6 +335,11 @@ const char* py_tpname(py_Type type);
|
||||
/// Check if the object is an instance of the given type.
|
||||
bool py_checktype(const py_Ref self, py_Type type);
|
||||
|
||||
#define py_checkint(self) py_checktype(self, tp_int)
|
||||
#define py_checkfloat(self) py_checktype(self, tp_float)
|
||||
#define py_checkbool(self) py_checktype(self, tp_bool)
|
||||
#define py_checkstr(self) py_checktype(self, tp_str)
|
||||
|
||||
int py_replinput(char* buf);
|
||||
|
||||
/// Python favored string formatting.
|
||||
|
@ -38,8 +38,8 @@ void c11_string__delete(c11_string* self) { free(self); }
|
||||
|
||||
c11_sv c11_string__sv(c11_string* self) { return (c11_sv){self->data, self->size}; }
|
||||
|
||||
c11_string* c11_string__replace(c11_string* self, char old, char new_) {
|
||||
c11_string* retval = c11_string__copy(self);
|
||||
c11_string* c11_sv__replace(c11_sv self, char old, char new_) {
|
||||
c11_string* retval = c11_string__new2(self.data, self.size);
|
||||
char* p = (char*)retval->data;
|
||||
for(int i = 0; i < retval->size; i++) {
|
||||
if(p[i] == old) p[i] = new_;
|
||||
@ -47,6 +47,23 @@ c11_string* c11_string__replace(c11_string* self, char old, char new_) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_){
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
int start = 0;
|
||||
while(true) {
|
||||
int i = c11_sv__index2(self, old, start);
|
||||
if(i == -1) break;
|
||||
c11_sv tmp = c11_sv__slice2(self, start, i);
|
||||
c11_sbuf__write_sv(&buf, tmp);
|
||||
c11_sbuf__write_sv(&buf, new_);
|
||||
start = i + old.size;
|
||||
}
|
||||
c11_sv tmp = c11_sv__slice2(self, start, self.size);
|
||||
c11_sbuf__write_sv(&buf, tmp);
|
||||
return c11_sbuf__submit(&buf);
|
||||
}
|
||||
|
||||
int c11_string__u8_length(c11_string* self) {
|
||||
return c11__byte_index_to_unicode(self->data, self->size);
|
||||
}
|
||||
|
@ -753,5 +753,7 @@ bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
|
||||
pk_VM* self = pk_current_vm;
|
||||
PUSH(lhs);
|
||||
PUSH(rhs);
|
||||
return stack_binaryop(self, op, rop);
|
||||
bool ok = stack_binaryop(self, op, rop);
|
||||
STACK_SHRINK(2);
|
||||
return ok;
|
||||
}
|
@ -189,6 +189,70 @@ void pk_VM__pop_frame(pk_VM* self) {
|
||||
Frame__delete(frame);
|
||||
}
|
||||
|
||||
static void _clip_int(int* value, int min, int max) {
|
||||
if(*value < min) *value = min;
|
||||
if(*value > max) *value = max;
|
||||
}
|
||||
|
||||
bool pk__parse_int_slice(const py_Ref slice, int length, int* start, int* stop, int* step) {
|
||||
py_Ref s_start = py_getslot(slice, 0);
|
||||
py_Ref s_stop = py_getslot(slice, 1);
|
||||
py_Ref s_step = py_getslot(slice, 2);
|
||||
|
||||
if(py_isnone(s_step))
|
||||
*step = 1;
|
||||
else {
|
||||
if(!py_checkint(s_step)) return false;
|
||||
*step = py_toint(s_step);
|
||||
}
|
||||
if(*step == 0) return ValueError("slice step cannot be zero");
|
||||
|
||||
if(*step > 0) {
|
||||
if(py_isnone(s_start))
|
||||
*start = 0;
|
||||
else {
|
||||
if(!py_checkint(s_start)) return false;
|
||||
*start = py_toint(s_start);
|
||||
if(*start < 0) *start += length;
|
||||
_clip_int(start, 0, length);
|
||||
}
|
||||
if(py_isnone(s_stop))
|
||||
*stop = length;
|
||||
else {
|
||||
if(!py_checkint(s_stop)) return false;
|
||||
*stop = py_toint(s_stop);
|
||||
if(*stop < 0) *stop += length;
|
||||
_clip_int(stop, 0, length);
|
||||
}
|
||||
} else {
|
||||
if(py_isnone(s_start))
|
||||
*start = length - 1;
|
||||
else {
|
||||
if(!py_checkint(s_start)) return false;
|
||||
*start = py_toint(s_start);
|
||||
if(*start < 0) *start += length;
|
||||
_clip_int(start, -1, length - 1);
|
||||
}
|
||||
if(py_isnone(s_stop))
|
||||
*stop = -1;
|
||||
else {
|
||||
if(!py_checkint(s_stop)) return false;
|
||||
*stop = py_toint(s_stop);
|
||||
if(*stop < 0) *stop += length;
|
||||
_clip_int(stop, -1, length - 1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pk__normalize_index(int *index, int length){
|
||||
if(*index < 0) *index += length;
|
||||
if(*index < 0 || *index >= length){
|
||||
return IndexError("index out of range");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_VM__new_type(pk_VM* self,
|
||||
const char* name,
|
||||
py_Type base,
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
typedef c11_vector List;
|
||||
|
||||
|
||||
void py_newlist(py_Ref out) {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_list, 0, sizeof(List));
|
||||
@ -60,13 +59,48 @@ void py_list__insert(py_Ref self, int i, const py_Ref val) {
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
static bool _py_list__len__(int argc, py_Ref argv){
|
||||
static bool _py_list__len__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_i64 res = py_list__len(py_arg(0));
|
||||
py_newint(py_retval(), res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_list__eq__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
py_Ref _0 = py_arg(0);
|
||||
py_Ref _1 = py_arg(1);
|
||||
if(py_istype(_1, tp_list)) {
|
||||
int length = py_list__len(_0);
|
||||
if(length != py_list__len(_1)) {
|
||||
py_newbool(py_retval(), false);
|
||||
return true;
|
||||
}
|
||||
for(int i = 0; i < length; i++) {
|
||||
py_Ref a = py_list__getitem(_0, i);
|
||||
py_Ref b = py_list__getitem(_1, i);
|
||||
int res = py_eq(a, b);
|
||||
if(res == -1) return false;
|
||||
if(res == 0) {
|
||||
py_newbool(py_retval(), false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
py_newbool(py_retval(), true);
|
||||
} else {
|
||||
py_newnotimplemented(py_retval());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_list__ne__(int argc, py_Ref argv) {
|
||||
bool ok = _py_list__eq__(argc, argv);
|
||||
if(!ok) return false;
|
||||
py_Ref retval = py_retval();
|
||||
py_newbool(retval, !py_tobool(retval));
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_list__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||
@ -74,5 +108,7 @@ py_Type pk_list__register() {
|
||||
ti->dtor = (void (*)(void*))c11_vector__dtor;
|
||||
|
||||
py_bindmagic(type, __len__, _py_list__len__);
|
||||
py_bindmagic(type, __eq__, _py_list__eq__);
|
||||
py_bindmagic(type, __ne__, _py_list__ne__);
|
||||
return type;
|
||||
}
|
@ -165,9 +165,23 @@ static bool _py_str__iter__(int argc, py_Ref argv) {
|
||||
static bool _py_str__getitem__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
c11_sv res = c11_string__u8_getitem(self, py_toint(py_arg(1)));
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
py_Ref _1 = py_arg(1);
|
||||
if(_1->type == tp_int) {
|
||||
int index = py_toint(py_arg(1));
|
||||
pk__normalize_index(&index, self->size);
|
||||
c11_sv res = c11_string__u8_getitem(self, index);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
} else if(_1->type == tp_slice) {
|
||||
int start, stop, step;
|
||||
bool ok = pk__parse_int_slice(_1, c11_string__u8_length(self), &start, &stop, &step);
|
||||
if(!ok) return false;
|
||||
c11_string* res = c11_string__u8_slice(self, start, stop, step);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
} else {
|
||||
return TypeError("str indices must be integers");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -257,6 +271,77 @@ static bool _py_str__join(int argc, py_Ref argv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _py_str__replace(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(3);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
PY_CHECK_ARG_TYPE(1, tp_str);
|
||||
PY_CHECK_ARG_TYPE(2, tp_str);
|
||||
c11_string* old = py_touserdata(&argv[1]);
|
||||
c11_string* new_ = py_touserdata(&argv[2]);
|
||||
c11_string* res =
|
||||
c11_sv__replace2(c11_string__sv(self), c11_string__sv(old), c11_string__sv(new_));
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__split(int argc, py_Ref argv) {
|
||||
c11_sv self = c11_string__sv(py_touserdata(&argv[0]));
|
||||
c11_vector res;
|
||||
if(argc > 2) return TypeError("split() takes at most 2 arguments");
|
||||
if(argc == 1) {
|
||||
// sep = ' '
|
||||
res = c11_sv__split(self, ' ');
|
||||
}
|
||||
if(argc == 2) {
|
||||
// sep = argv[1]
|
||||
if(!py_checkstr(&argv[1])) return false;
|
||||
c11_sv sep = c11_string__sv(py_touserdata(&argv[1]));
|
||||
res = c11_sv__split2(self, sep);
|
||||
}
|
||||
py_newlistn(py_retval(), res.count);
|
||||
for(int i = 0; i < res.count; i++) {
|
||||
c11_sv item = c11__getitem(c11_sv, &res, i);
|
||||
py_newstrn(py_list__getitem(py_retval(), i), item.data, item.size);
|
||||
}
|
||||
c11_vector__dtor(&res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__count(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
PY_CHECK_ARG_TYPE(1, tp_str);
|
||||
c11_string* sub = py_touserdata(&argv[1]);
|
||||
int res = c11_sv__count(c11_string__sv(self), c11_string__sv(sub));
|
||||
py_newint(py_retval(), res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__strip(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
c11_sv res = c11_sv__strip(c11_string__sv(self), true, true);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__lstrip(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
c11_sv res = c11_sv__strip(c11_string__sv(self), true, false);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__rstrip(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
c11_string* self = py_touserdata(&argv[0]);
|
||||
c11_sv res = c11_sv__strip(c11_string__sv(self), false, true);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_str__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "str", tp_object, NULL, false);
|
||||
@ -286,6 +371,12 @@ py_Type pk_str__register() {
|
||||
py_bindmethod(tp_str, "startswith", _py_str__startswith);
|
||||
py_bindmethod(tp_str, "endswith", _py_str__endswith);
|
||||
py_bindmethod(tp_str, "join", _py_str__join);
|
||||
py_bindmethod(tp_str, "replace", _py_str__replace);
|
||||
py_bindmethod(tp_str, "split", _py_str__split);
|
||||
py_bindmethod(tp_str, "count", _py_str__count);
|
||||
py_bindmethod(tp_str, "strip", _py_str__strip);
|
||||
py_bindmethod(tp_str, "lstrip", _py_str__lstrip);
|
||||
py_bindmethod(tp_str, "rstrip", _py_str__rstrip);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user