mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
1a9bad4e54
commit
29aa3e5eed
@ -96,6 +96,7 @@ const char* pk_opname(Opcode op);
|
||||
void pk_object__register();
|
||||
void pk_number__register();
|
||||
py_Type pk_str__register();
|
||||
py_Type pk_str_iterator__register();
|
||||
py_Type pk_bytes__register();
|
||||
py_Type pk_list__register();
|
||||
py_Type pk_function__register();
|
||||
|
@ -244,6 +244,8 @@ void py_formatexc(char* out);
|
||||
#define TypeError(...) py_exception("TypeError", __VA_ARGS__)
|
||||
#define ValueError(...) py_exception("ValueError", __VA_ARGS__)
|
||||
#define IndexError(...) py_exception("IndexError", __VA_ARGS__)
|
||||
#define StopIteration() py_exception("StopIteration", "")
|
||||
#define NotImplementedError() py_exception("NotImplementedError", "")
|
||||
#define AttributeError(self, n) \
|
||||
py_exception("AttributeError", "'%t' object has no attribute '%n'", (self)->type, (n))
|
||||
#define UnboundLocalError(n) \
|
||||
@ -264,6 +266,12 @@ int py_gt(const py_Ref, const py_Ref);
|
||||
|
||||
bool py_hash(const py_Ref, py_i64* out);
|
||||
|
||||
/// Get the iterator of the object.
|
||||
bool py_iter(const py_Ref);
|
||||
/// Get the next element from the iterator.
|
||||
/// 1: success, 0: StopIteration, -1: error
|
||||
int py_next(const py_Ref);
|
||||
|
||||
/// Python equivalent to `lhs is rhs`.
|
||||
bool py_isidentical(const py_Ref, const py_Ref);
|
||||
|
||||
@ -332,6 +340,9 @@ py_GlobalRef py_tpobject(py_Type type);
|
||||
/// Get the type name.
|
||||
const char* py_tpname(py_Type type);
|
||||
|
||||
/// Call a type to create a new instance.
|
||||
bool py_tpcall(py_Type type, int argc, py_Ref argv);
|
||||
|
||||
/// Check if the object is an instance of the given type.
|
||||
bool py_checktype(const py_Ref self, py_Type type);
|
||||
|
||||
@ -369,6 +380,7 @@ enum py_PredefinedTypes {
|
||||
tp_float,
|
||||
tp_bool,
|
||||
tp_str,
|
||||
tp_str_iterator,
|
||||
tp_list, // c11_vector
|
||||
tp_tuple, // N slots
|
||||
tp_slice, // 3 slots (start, stop, step)
|
||||
@ -390,7 +402,7 @@ enum py_PredefinedTypes {
|
||||
tp_not_implemented_type,
|
||||
tp_ellipsis,
|
||||
tp_syntax_error,
|
||||
tp_stop_iteration
|
||||
tp_stop_iteration,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -96,6 +96,7 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
pk_number__register();
|
||||
|
||||
validate(tp_str, pk_str__register());
|
||||
validate(tp_str_iterator, pk_str_iterator__register());
|
||||
|
||||
validate(tp_list, pk_list__register());
|
||||
validate(tp_tuple, pk_VM__new_type(self, "tuple", tp_object, NULL, false));
|
||||
|
@ -101,6 +101,32 @@ static bool _py_list__ne__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_list__new__(int argc, py_Ref argv) {
|
||||
if(argc == 1) {
|
||||
py_newlist(py_retval());
|
||||
return true;
|
||||
}
|
||||
if(argc == 2) {
|
||||
py_Ref iter = py_pushtmp();
|
||||
py_Ref list = py_pushtmp();
|
||||
if(!py_iter(py_arg(1))) return false;
|
||||
*iter = *py_retval();
|
||||
py_newlist(list);
|
||||
while(true) {
|
||||
int res = py_next(iter);
|
||||
if(res == -1) return false;
|
||||
if(res) {
|
||||
py_list__append(list, py_retval());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*py_retval() = *list;
|
||||
return true;
|
||||
}
|
||||
return TypeError("list() takes at most 1 argument");
|
||||
}
|
||||
|
||||
py_Type pk_list__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||
@ -110,5 +136,6 @@ py_Type pk_list__register() {
|
||||
py_bindmagic(type, __len__, _py_list__len__);
|
||||
py_bindmagic(type, __eq__, _py_list__eq__);
|
||||
py_bindmagic(type, __ne__, _py_list__ne__);
|
||||
py_bindmagic(type, __new__, _py_list__new__);
|
||||
return type;
|
||||
}
|
@ -60,6 +60,24 @@ bool py_hash(const py_Ref val, int64_t* out) {
|
||||
return TypeError("unhashable type: '%t'", val->type);
|
||||
}
|
||||
|
||||
bool py_iter(const py_Ref val) {
|
||||
py_Ref tmp = py_tpfindmagic(val->type, __iter__);
|
||||
if(!tmp) return TypeError("'%t' object is not iterable", val->type);
|
||||
return py_call(tmp, 1, val);
|
||||
}
|
||||
|
||||
int py_next(const py_Ref val) {
|
||||
py_Ref tmp = py_tpfindmagic(val->type, __next__);
|
||||
if(!tmp) return TypeError("'%t' object is not an iterator", val->type);
|
||||
bool ok = py_call(tmp, 1, val);
|
||||
if(ok) {
|
||||
py_Ref retval = py_retval();
|
||||
bool is_end = retval->type == tp_type && py_totype(retval) == tp_stop_iteration;
|
||||
return !is_end;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int py_getattr(const py_Ref self, py_Name name, py_Ref out) { return -1; }
|
||||
|
||||
bool py_setattr(py_Ref self, py_Name name, const py_Ref val) { return false; }
|
||||
|
@ -158,8 +158,7 @@ static bool _py_str__repr__(int argc, py_Ref argv) {
|
||||
|
||||
static bool _py_str__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
assert(false);
|
||||
return false;
|
||||
return py_tpcall(tp_str_iterator, 1, argv);
|
||||
}
|
||||
|
||||
static bool _py_str__getitem__(int argc, py_Ref argv) {
|
||||
@ -391,6 +390,52 @@ static bool _py_str__zfill(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__widthjust_impl(bool left, int argc, py_Ref argv) {
|
||||
if(argc > 1 + 2) return TypeError("expected at most 2 arguments");
|
||||
char pad;
|
||||
if(argc == 1 + 1) {
|
||||
pad = ' ';
|
||||
} else {
|
||||
if(!py_checkstr(&argv[2])) return false;
|
||||
c11_string* padstr = py_touserdata(&argv[2]);
|
||||
if(padstr->size != 1)
|
||||
return TypeError("The fill character must be exactly one character long");
|
||||
pad = padstr->data[0];
|
||||
}
|
||||
c11_sv self = c11_string__sv(py_touserdata(&argv[0]));
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
int width = py_toint(py_arg(1));
|
||||
if(width <= self.size) {
|
||||
*py_retval() = argv[0];
|
||||
return true;
|
||||
}
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
if(left) {
|
||||
c11_sbuf__write_sv(&buf, self);
|
||||
for(int i = 0; i < width - self.size; i++) {
|
||||
c11_sbuf__write_char(&buf, pad);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < width - self.size; i++) {
|
||||
c11_sbuf__write_char(&buf, pad);
|
||||
}
|
||||
c11_sbuf__write_sv(&buf, self);
|
||||
}
|
||||
c11_string* res = c11_sbuf__submit(&buf);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str__ljust(int argc, py_Ref argv) {
|
||||
return _py_str__widthjust_impl(true, argc, argv);
|
||||
}
|
||||
|
||||
static bool _py_str__rjust(int argc, py_Ref argv) {
|
||||
return _py_str__widthjust_impl(false, argc, argv);
|
||||
}
|
||||
|
||||
py_Type pk_str__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "str", tp_object, NULL, false);
|
||||
@ -427,6 +472,48 @@ py_Type pk_str__register() {
|
||||
py_bindmethod(tp_str, "lstrip", _py_str__lstrip);
|
||||
py_bindmethod(tp_str, "rstrip", _py_str__rstrip);
|
||||
py_bindmethod(tp_str, "zfill", _py_str__zfill);
|
||||
py_bindmethod(tp_str, "ljust", _py_str__ljust);
|
||||
py_bindmethod(tp_str, "rjust", _py_str__rjust);
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool _py_str_iterator__new__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
PY_CHECK_ARG_TYPE(1, tp_str);
|
||||
int* ud = py_newobject(py_retval(), tp_str_iterator, 1, sizeof(int));
|
||||
*ud = 0;
|
||||
py_setslot(py_retval(), 0, &argv[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str_iterator__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
*py_retval() = argv[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_str_iterator__next__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
int* ud = py_touserdata(&argv[0]);
|
||||
int size;
|
||||
const char* data = py_tostrn(py_getslot(argv, 0), &size);
|
||||
if(*ud == size) {
|
||||
*py_retval() = pk_current_vm->StopIteration;
|
||||
return true;
|
||||
}
|
||||
int start = *ud;
|
||||
int len = c11__u8_header(data[*ud], false);
|
||||
*ud += len;
|
||||
py_newstrn(py_retval(), data + start, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_str_iterator__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "str_iterator", tp_object, NULL, false);
|
||||
py_bindmagic(type, __new__, _py_str_iterator__new__);
|
||||
py_bindmagic(type, __iter__, _py_str_iterator__iter__);
|
||||
py_bindmagic(type, __next__, _py_str_iterator__next__);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,9 @@ bool py_call(py_Ref f, int argc, py_Ref argv) {
|
||||
py_pushnil();
|
||||
for(int i = 0; i < argc; i++)
|
||||
py_push(py_offset(argv, i));
|
||||
return pk_VM__vectorcall(vm, argc, 0, false) == RES_ERROR;
|
||||
pk_FrameResult res = pk_VM__vectorcall(vm, argc, 0, false);
|
||||
assert(res == RES_ERROR || res == RES_RETURN);
|
||||
return res == RES_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,6 +294,10 @@ const char* py_tpname(py_Type type) {
|
||||
return py_name2str(name);
|
||||
}
|
||||
|
||||
bool py_tpcall(py_Type type, int argc, py_Ref argv){
|
||||
return py_call(py_tpobject(type), argc, argv);
|
||||
}
|
||||
|
||||
bool py_callmagic(py_Name name, int argc, py_Ref argv) {
|
||||
assert(argc >= 1);
|
||||
assert(py_ismagicname(name));
|
||||
|
@ -116,14 +116,6 @@ assert a[2:5:2] == "lo"
|
||||
assert a[5:2:-1] == ",ol"
|
||||
assert a[5:2:-2] == ",l"
|
||||
|
||||
b = list(a)
|
||||
assert b == ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']
|
||||
assert b[::-1] == ['!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H']
|
||||
assert b[::2] == ['H', 'l', 'o', ' ', 'o', 'l', '!']
|
||||
assert b[2:5:2] == ['l', 'o']
|
||||
assert b[5:2:-1] == [',', 'o', 'l']
|
||||
assert b[5:2:-2] == [',', 'l']
|
||||
|
||||
a = '123'
|
||||
assert a.rjust(5) == ' 123'
|
||||
assert a.rjust(5, '0') == '00123'
|
||||
@ -134,6 +126,14 @@ assert '\x30\x31\x32' == '012'
|
||||
assert '\b\b\b' == '\x08\x08\x08'
|
||||
assert repr('\x1f\x1e\x1f') == '\'\\x1f\\x1e\\x1f\''
|
||||
|
||||
b = list("Hello, World!")
|
||||
assert b == ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']
|
||||
assert b[::-1] == ['!', 'd', 'l', 'r', 'o', 'W', ' ', ',', 'o', 'l', 'l', 'e', 'H']
|
||||
assert b[::2] == ['H', 'l', 'o', ' ', 'o', 'l', '!']
|
||||
assert b[2:5:2] == ['l', 'o']
|
||||
assert b[5:2:-1] == [',', 'o', 'l']
|
||||
assert b[5:2:-2] == [',', 'l']
|
||||
|
||||
assert hex(-42) == '-0x2a'
|
||||
assert hex(42) == '0x2a'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user