mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
redesign py_newstrn
and py_newstrv
This commit is contained in:
parent
24a7e6f060
commit
000fd1f087
@ -10,7 +10,7 @@
|
||||
typedef struct c11_string {
|
||||
// int size | char[] | '\0'
|
||||
int size;
|
||||
const char data[]; // flexible array member
|
||||
char data[]; // flexible array member
|
||||
} c11_string;
|
||||
|
||||
/* bytes */
|
||||
@ -33,6 +33,7 @@ c11_string* c11_string__new2(const char* data, int size);
|
||||
c11_string* c11_string__new3(const char* fmt, ...);
|
||||
void c11_string__ctor(c11_string* self, const char* data);
|
||||
void c11_string__ctor2(c11_string* self, const char* data, int size);
|
||||
void c11_string__ctor3(c11_string* self, 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);
|
||||
|
@ -153,8 +153,10 @@ PK_EXPORT void py_newfloat(py_OutRef, py_f64);
|
||||
PK_EXPORT void py_newbool(py_OutRef, bool);
|
||||
/// Create a `str` object from a null-terminated string (utf-8).
|
||||
PK_EXPORT void py_newstr(py_OutRef, const char*);
|
||||
/// Create a `str` object from a char array (utf-8).
|
||||
PK_EXPORT void py_newstrn(py_OutRef, const char*, int);
|
||||
/// Create a `str` object with `n` UNINITIALIZED bytes plus `'\0'`.
|
||||
PK_EXPORT char* py_newstrn(py_OutRef, int);
|
||||
/// Create a `str` object from a `c11_sv`.
|
||||
PK_EXPORT void py_newstrv(py_OutRef, c11_sv);
|
||||
/// Create a `bytes` object with `n` UNINITIALIZED bytes.
|
||||
PK_EXPORT unsigned char* py_newbytes(py_OutRef, int n);
|
||||
/// Create a `None` object.
|
||||
@ -504,6 +506,7 @@ PK_EXPORT void py_clearexc(py_StackRef p0);
|
||||
#define NameError(n) py_exception(tp_NameError, "name '%n' is not defined", (n))
|
||||
#define TypeError(...) py_exception(tp_TypeError, __VA_ARGS__)
|
||||
#define RuntimeError(...) py_exception(tp_RuntimeError, __VA_ARGS__)
|
||||
#define IOError(...) py_exception(tp_IOError, __VA_ARGS__)
|
||||
#define ValueError(...) py_exception(tp_ValueError, __VA_ARGS__)
|
||||
#define IndexError(...) py_exception(tp_IndexError, __VA_ARGS__)
|
||||
#define ImportError(...) py_exception(tp_ImportError, __VA_ARGS__)
|
||||
|
@ -136,7 +136,7 @@ iterator interface<Dervied>::end() const {
|
||||
class str : public object {
|
||||
PKBIND_TYPE_IMPL(object, str, tp_str);
|
||||
|
||||
str(const char* data, int size) : object(alloc_t{}) { py_newstrn(m_ptr, data, size); }
|
||||
str(const char* data, int size) : object(alloc_t{}) { py_newstrv(m_ptr, (c11_sv){data, size}); }
|
||||
|
||||
str(const char* data) : str(data, static_cast<int>(strlen(data))) {}
|
||||
|
||||
|
@ -148,7 +148,7 @@ c11_string* c11_sbuf__submit(c11_sbuf* self) {
|
||||
|
||||
void c11_sbuf__py_submit(c11_sbuf* self, py_Ref out) {
|
||||
c11_string* res = c11_sbuf__submit(self);
|
||||
py_newstrn(out, res->data, res->size);
|
||||
py_newstrv(out, (c11_sv){res->data, res->size});
|
||||
c11_string__delete(res);
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,12 @@ void c11_string__ctor2(c11_string* self, const char* data, int size) {
|
||||
p[size] = '\0';
|
||||
}
|
||||
|
||||
void c11_string__ctor3(c11_string* self, int size) {
|
||||
self->size = size;
|
||||
char* p = (char*)self->data;
|
||||
p[size] = '\0';
|
||||
}
|
||||
|
||||
c11_string* c11_string__copy(c11_string* self) {
|
||||
int total_size = sizeof(c11_string) + self->size + 1;
|
||||
c11_string* retval = malloc(total_size);
|
||||
|
@ -1209,7 +1209,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) {
|
||||
return *val;
|
||||
} else {
|
||||
py_TValue tmp;
|
||||
py_newstrn(&tmp, key.data, key.size);
|
||||
py_newstrv(&tmp, key);
|
||||
c11_vector__push(py_TValue, &self->co->consts, tmp);
|
||||
int index = self->co->consts.length - 1;
|
||||
c11_smallmap_s2n__set(&self->co_consts_string_dedup_map,
|
||||
|
@ -163,7 +163,7 @@ static bool vec2__repr__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
char buf[64];
|
||||
int size = snprintf(buf, 64, "vec2(%.4f, %.4f)", argv[0]._vec2.x, argv[0]._vec2.y);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ static bool mat3x3__repr__(int argc, py_Ref argv) {
|
||||
m->data[6],
|
||||
m->data[7],
|
||||
m->data[8]);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -660,7 +660,7 @@ static bool vec2i__repr__(int argc, py_Ref argv) {
|
||||
c11_vec2i data = py_tovec2i(argv);
|
||||
char buf[64];
|
||||
int size = snprintf(buf, 64, "vec2i(%d, %d)", data.x, data.y);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -693,7 +693,7 @@ static bool vec3i__repr__(int argc, py_Ref argv) {
|
||||
c11_vec3i data = py_tovec3i(argv);
|
||||
char buf[64];
|
||||
int size = snprintf(buf, 64, "vec3i(%d, %d, %d)", data.x, data.y, data.z);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -730,7 +730,7 @@ static bool vec3__repr__(int argc, py_Ref argv) {
|
||||
c11_vec3 data = py_tovec3(argv);
|
||||
char buf[64];
|
||||
int size = snprintf(buf, 64, "vec3(%.4f, %.4f, %.4f)", data.x, data.y, data.z);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ py_Ref py_newmodule(const char* path) {
|
||||
const char* start = path + last_dot + 1;
|
||||
py_newstr(r1, start);
|
||||
py_setdict(r0, __name__, r1);
|
||||
py_newstrn(r1, path, last_dot);
|
||||
py_newstrv(r1, (c11_sv){path, last_dot});
|
||||
py_setdict(r0, __package__, r1);
|
||||
}
|
||||
|
||||
@ -404,7 +404,8 @@ static bool builtins_chr(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
py_i64 val = py_toint(py_arg(0));
|
||||
if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
|
||||
py_newstrn(py_retval(), (const char*)&val, 1);
|
||||
char* data = py_newstrn(py_retval(), 1);
|
||||
data[0] = (char)val;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ static bool int__repr__(int argc, py_Ref argv) {
|
||||
py_i64 val = py_toint(&argv[0]);
|
||||
char buf[32];
|
||||
int size = snprintf(buf, sizeof(buf), "%lld", (long long)val);
|
||||
py_newstrn(py_retval(), buf, size);
|
||||
py_newstrv(py_retval(), (c11_sv){buf, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6,17 +6,23 @@
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
|
||||
void py_newstr(py_Ref out, const char* data) { py_newstrn(out, data, strlen(data)); }
|
||||
void py_newstr(py_Ref out, const char* data) { py_newstrv(out, (c11_sv){data, strlen(data)}); }
|
||||
|
||||
void py_newstrn(py_Ref out, const char* data, int size) {
|
||||
char* py_newstrn(py_Ref out, int size) {
|
||||
ManagedHeap* heap = &pk_current_vm->heap;
|
||||
int total_size = sizeof(c11_string) + size + 1;
|
||||
PyObject* obj = ManagedHeap__gcnew(heap, tp_str, 0, total_size);
|
||||
c11_string* ud = PyObject__userdata(obj);
|
||||
c11_string__ctor2(ud, data, size);
|
||||
c11_string__ctor3(ud, size);
|
||||
out->type = tp_str;
|
||||
out->is_ptr = true;
|
||||
out->_obj = obj;
|
||||
return ud->data;
|
||||
}
|
||||
|
||||
void py_newstrv(py_OutRef out, c11_sv sv) {
|
||||
char* data = py_newstrn(out, sv.size);
|
||||
memcpy(data, sv.data, sv.size);
|
||||
}
|
||||
|
||||
unsigned char* py_newbytes(py_Ref out, int size) {
|
||||
@ -97,7 +103,7 @@ static bool str__add__(int argc, py_Ref argv) {
|
||||
int total_size = sizeof(c11_string) + self->size + other->size + 1;
|
||||
c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
|
||||
res->size = self->size + other->size;
|
||||
char* p = (char*)res->data;
|
||||
char* p = res->data;
|
||||
memcpy(p, self->data, self->size);
|
||||
memcpy(p + self->size, other->data, other->size);
|
||||
p[res->size] = '\0';
|
||||
@ -118,7 +124,7 @@ static bool str__mul__(int argc, py_Ref argv) {
|
||||
int total_size = sizeof(c11_string) + self->size * n + 1;
|
||||
c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
|
||||
res->size = self->size * n;
|
||||
char* p = (char*)res->data;
|
||||
char* p = res->data;
|
||||
for(int i = 0; i < n; i++) {
|
||||
memcpy(p + i * self->size, self->data, self->size);
|
||||
}
|
||||
@ -174,14 +180,14 @@ static bool str__getitem__(int argc, py_Ref argv) {
|
||||
int index = py_toint(py_arg(1));
|
||||
if(!pk__normalize_index(&index, self.size)) return false;
|
||||
c11_sv res = c11_sv__u8_getitem(self, index);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
py_newstrv(py_retval(), res);
|
||||
return true;
|
||||
} else if(_1->type == tp_slice) {
|
||||
int start, stop, step;
|
||||
bool ok = pk__parse_int_slice(_1, c11_sv__u8_length(self), &start, &stop, &step);
|
||||
if(!ok) return false;
|
||||
c11_string* res = c11_sv__u8_slice(self, start, stop, step);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
py_newstrv(py_retval(), (c11_sv){res->data, res->size});
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
} else {
|
||||
@ -218,7 +224,7 @@ static bool str_lower(int argc, py_Ref argv) {
|
||||
int total_size = sizeof(c11_string) + self->size + 1;
|
||||
c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
|
||||
res->size = self->size;
|
||||
char* p = (char*)res->data;
|
||||
char* p = res->data;
|
||||
for(int i = 0; i < self->size; i++) {
|
||||
char c = self->data[i];
|
||||
p[i] = c >= 'A' && c <= 'Z' ? c + 32 : c;
|
||||
@ -233,7 +239,7 @@ static bool str_upper(int argc, py_Ref argv) {
|
||||
int total_size = sizeof(c11_string) + self->size + 1;
|
||||
c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
|
||||
res->size = self->size;
|
||||
char* p = (char*)res->data;
|
||||
char* p = res->data;
|
||||
for(int i = 0; i < self->size; i++) {
|
||||
char c = self->data[i];
|
||||
p[i] = c >= 'a' && c <= 'z' ? c - 32 : c;
|
||||
@ -303,7 +309,7 @@ static bool str_replace(int argc, py_Ref argv) {
|
||||
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);
|
||||
py_newstrv(py_retval(), (c11_sv){res->data, res->size});
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
@ -325,7 +331,7 @@ static bool str_split(int argc, py_Ref argv) {
|
||||
py_newlistn(py_retval(), res.length);
|
||||
for(int i = 0; i < res.length; i++) {
|
||||
c11_sv item = c11__getitem(c11_sv, &res, i);
|
||||
py_newstrn(py_list_getitem(py_retval(), i), item.data, item.size);
|
||||
py_newstrv(py_list_getitem(py_retval(), i), item);
|
||||
}
|
||||
c11_vector__dtor(&res);
|
||||
return true;
|
||||
@ -353,7 +359,7 @@ static bool str__strip_impl(bool left, bool right, int argc, py_Ref argv) {
|
||||
return TypeError("strip() takes at most 2 arguments");
|
||||
}
|
||||
c11_sv res = c11_sv__strip(self, chars, left, right);
|
||||
py_newstrn(py_retval(), res.data, res.size);
|
||||
py_newstrv(py_retval(), res);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -506,7 +512,7 @@ static bool str_iterator__next__(int argc, py_Ref argv) {
|
||||
int start = *ud;
|
||||
int len = c11__u8_header(data[*ud], false);
|
||||
*ud += len;
|
||||
py_newstrn(py_retval(), data + start, len);
|
||||
py_newstrv(py_retval(), (c11_sv){data + start, len});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -629,7 +635,7 @@ static bool bytes_decode(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
int size;
|
||||
unsigned char* data = py_tobytes(&argv[0], &size);
|
||||
py_newstrn(py_retval(), (const char*)data, size);
|
||||
py_newstrv(py_retval(), (c11_sv){(const char*)data, size});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user