redesign py_newstrn and py_newstrv

This commit is contained in:
blueloveTH 2024-09-08 18:42:34 +08:00
parent 24a7e6f060
commit 000fd1f087
10 changed files with 51 additions and 34 deletions

View File

@ -7,16 +7,16 @@
#include <stdarg.h>
/* string */
typedef struct c11_string{
typedef struct c11_string {
// int size | char[] | '\0'
int size;
const char data[]; // flexible array member
char data[]; // flexible array member
} c11_string;
/* bytes */
typedef struct c11_bytes{
typedef struct c11_bytes {
int size;
unsigned char data[]; // flexible array member
unsigned char data[]; // flexible array member
} c11_bytes;
bool c11_bytes__eq(c11_bytes* self, c11_bytes* other);
@ -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);
@ -55,8 +56,8 @@ bool c11_sv__endswith(c11_sv self, c11_sv suffix);
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);
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);
// misc
int c11__unicode_index_to_byte(const char* data, int i);
@ -65,7 +66,7 @@ int c11__byte_index_to_unicode(const char* data, int n);
bool c11__is_unicode_Lo_char(int c);
int c11__u8_header(unsigned char c, bool suppress);
typedef enum IntParsingResult{
typedef enum IntParsingResult {
IntParsing_SUCCESS,
IntParsing_FAILURE,
IntParsing_OVERFLOW,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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