mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
some fix
This commit is contained in:
parent
4569547161
commit
c2944b7fd8
@ -15,7 +15,8 @@ extern "C" {
|
||||
|
||||
#define PK_REGION(name) 1
|
||||
|
||||
#define PK_SLICE_LOOP(i, start, stop, step) for(int i = start; step > 0 ? i < stop : i > stop; i += step)
|
||||
#define PK_SLICE_LOOP(i, start, stop, step) \
|
||||
for(int i = start; step > 0 ? i < stop : i > stop; i += step)
|
||||
|
||||
// global constants
|
||||
#define PK_HEX_TABLE "0123456789abcdef"
|
||||
@ -23,17 +24,21 @@ extern "C" {
|
||||
extern const char* kPlatformStrings[];
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PK_UNREACHABLE() __assume(0);
|
||||
#define c11__unreachedable() __assume(0)
|
||||
#else
|
||||
#define PK_UNREACHABLE() __builtin_unreachable();
|
||||
#define c11__unreachedable() __builtin_unreachable()
|
||||
#endif
|
||||
|
||||
#define PK_FATAL_ERROR(...) { fprintf(stderr, __VA_ARGS__); abort(); }
|
||||
#define PK_FATAL_ERROR(...) \
|
||||
do { \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
#define PK_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define PK_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define c11__min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define c11__max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#define PK_ARRAY_COUNT(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define c11__count_array(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
// NARGS
|
||||
#define PK_NARGS_SEQ(_1, _2, _3, _4, N, ...) N
|
||||
@ -47,12 +52,13 @@ typedef struct RefCounted {
|
||||
} RefCounted;
|
||||
|
||||
#define PK_INCREF(obj) (obj)->rc.count++
|
||||
#define PK_DECREF(obj) do { \
|
||||
if(--(obj)->rc.count == 0) { \
|
||||
(obj)->rc.dtor(obj); \
|
||||
free(obj); \
|
||||
} \
|
||||
} while(0)
|
||||
#define PK_DECREF(obj) \
|
||||
do { \
|
||||
if(--(obj)->rc.count == 0) { \
|
||||
(obj)->rc.dtor(obj); \
|
||||
free(obj); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ c11_array c11_vector__submit(c11_vector* self);
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
// NOTE: here we do an extra NULL check for it to avoid UB
|
||||
#define c11__foreach(T, self, it) \
|
||||
for(T* it = (self)->data; it && it != (T*)(self)->data + (self)->count; it++)
|
||||
|
@ -57,7 +57,6 @@ typedef struct pk_VM {
|
||||
py_TValue reg[8]; // users' registers
|
||||
|
||||
py_TValue __curr_class;
|
||||
py_TValue __cached_object_new;
|
||||
FuncDecl_ __dynamic_func_decl;
|
||||
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
||||
|
||||
|
@ -115,10 +115,13 @@ bool py_isinstance(const py_Ref obj, py_Type type);
|
||||
bool py_issubclass(py_Type derived, py_Type base);
|
||||
|
||||
/************* References *************/
|
||||
#define PY_CHECK_ARGC(n) \
|
||||
if(argc != n) return TypeError("expected %d arguments, got %d", n, argc)
|
||||
|
||||
#define PY_CHECK_ARG_TYPE(i, type) if(!py_checktype(py_arg(i), type)) return false
|
||||
|
||||
#define py_offset(p, i) (py_Ref)((char*)p + ((i) << 4))
|
||||
#define py_arg(i) py_offset(argv, i)
|
||||
#define py_checkargc(n) \
|
||||
if(argc != n) return TypeError("expected %d arguments, got %d", n, argc)
|
||||
|
||||
py_GlobalRef py_tpmagic(py_Type type, py_Name name);
|
||||
#define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f))
|
||||
@ -375,3 +378,13 @@ enum py_PredefinedTypes {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Some notes:
|
||||
|
||||
## Macros
|
||||
1. Function macros are partial functions. They can be used as normal expressions. Use the same naming convention as functions.
|
||||
2. Snippet macros are `do {...} while(0)` blocks. They cannot be used as expressions. Use `UPPER_CASE` naming convention.
|
||||
3. Constant macros are used for global constants. Use `UPPER_CASE` or k-prefix naming convention.
|
||||
*/
|
@ -197,14 +197,14 @@ int c11__byte_index_to_unicode(const char* data, int n) {
|
||||
//////////////
|
||||
|
||||
int c11_sv__cmp(c11_sv self, c11_sv other) {
|
||||
int res = strncmp(self.data, other.data, PK_MIN(self.size, other.size));
|
||||
int res = strncmp(self.data, other.data, c11__min(self.size, other.size));
|
||||
if(res != 0) return res;
|
||||
return self.size - other.size;
|
||||
}
|
||||
|
||||
int c11_sv__cmp2(c11_sv self, const char* other) {
|
||||
int size = strlen(other);
|
||||
int res = strncmp(self.data, other, PK_MIN(self.size, size));
|
||||
int res = strncmp(self.data, other, c11__min(self.size, size));
|
||||
if(res != 0) return res;
|
||||
return self.size - size;
|
||||
}
|
||||
@ -241,14 +241,14 @@ int c11__u8_header(unsigned char c, bool suppress) {
|
||||
if((c & 0b11111000) == 0b11110000) return 4;
|
||||
if((c & 0b11111100) == 0b11111000) return 5;
|
||||
if((c & 0b11111110) == 0b11111100) return 6;
|
||||
if(!suppress) PK_FATAL_ERROR("invalid utf8 char\n")
|
||||
if(!suppress) PK_FATAL_ERROR("invalid utf8 char\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IntParsingResult c11__parse_uint(c11_sv text, int64_t* out, int base) {
|
||||
*out = 0;
|
||||
|
||||
c11_sv prefix = {.data = text.data, .size = PK_MIN(2, text.size)};
|
||||
c11_sv prefix = {.data = text.data, .size = c11__min(2, text.size)};
|
||||
if(base == -1) {
|
||||
if(c11__sveq(prefix, "0b"))
|
||||
base = 2;
|
||||
|
@ -31,16 +31,14 @@ void py_Name__finalize() {
|
||||
c11_vector__dtor(&_r_interned);
|
||||
}
|
||||
|
||||
py_Name py_name(const char* name) {
|
||||
return py_name2((c11_sv){name, strlen(name)});
|
||||
}
|
||||
py_Name py_name(const char* name) { return py_name2((c11_sv){name, strlen(name)}); }
|
||||
|
||||
py_Name py_name2(c11_sv name) {
|
||||
// TODO: PK_GLOBAL_SCOPE_LOCK()
|
||||
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
|
||||
if(index != 0) return index;
|
||||
// generate new index
|
||||
if(_interned.count > 65530) { PK_FATAL_ERROR("py_Name index overflow\n"); }
|
||||
if(_interned.count > 65530) PK_FATAL_ERROR("py_Name index overflow\n");
|
||||
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
||||
char* p = malloc(name.size + 1);
|
||||
memcpy(p, name.data, name.size);
|
||||
@ -64,8 +62,4 @@ c11_sv py_name2sv(py_Name index) {
|
||||
return (c11_sv){p, strlen(p)};
|
||||
}
|
||||
|
||||
|
||||
bool py_ismagicname(py_Name name){
|
||||
return name <= __missing__;
|
||||
}
|
||||
|
||||
bool py_ismagicname(py_Name name) { return name <= __missing__; }
|
||||
|
@ -129,7 +129,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) {
|
||||
break;
|
||||
case NAME_GLOBAL: Ctx__emit_(ctx, OP_DELETE_GLOBAL, self->name, self->line); break;
|
||||
case NAME_GLOBAL_UNKNOWN: Ctx__emit_(ctx, OP_DELETE_NAME, self->name, self->line); break;
|
||||
default: PK_UNREACHABLE();
|
||||
default: c11__unreachedable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -294,7 +294,7 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line);
|
||||
break;
|
||||
}
|
||||
default: PK_UNREACHABLE();
|
||||
default: c11__unreachedable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1376,7 +1376,7 @@ static void Ctx__emit_store_name(Ctx* self, NameScope scope, py_Name name, int l
|
||||
case NAME_LOCAL: Ctx__emit_(self, OP_STORE_FAST, Ctx__add_varname(self, name), line); break;
|
||||
case NAME_GLOBAL: Ctx__emit_(self, OP_STORE_GLOBAL, name, line); break;
|
||||
case NAME_GLOBAL_UNKNOWN: Ctx__emit_(self, OP_STORE_NAME, name, line); break;
|
||||
default: PK_UNREACHABLE();
|
||||
default: c11__unreachedable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1478,6 +1478,7 @@ static NameScope name_scope(Compiler* self) {
|
||||
}
|
||||
|
||||
#define SyntaxError(...) NULL
|
||||
|
||||
static Error* NeedMoreLines() { return NULL; }
|
||||
|
||||
/* Matchers */
|
||||
|
@ -52,7 +52,7 @@ static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
|
||||
PUSH(&self->last_retval); \
|
||||
goto __NEXT_FRAME; \
|
||||
case RES_ERROR: goto __ERROR; \
|
||||
default: PK_UNREACHABLE(); \
|
||||
default: c11__unreachedable(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
@ -671,7 +671,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
*TOP() = self->last_retval;
|
||||
DISPATCH();
|
||||
}
|
||||
default: PK_UNREACHABLE();
|
||||
default: c11__unreachedable();
|
||||
}
|
||||
|
||||
assert(false); // should never reach here
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#define DEF_NUM_BINARY_OP(name, op, rint, rfloat) \
|
||||
static bool _py_int##name(int argc, py_Ref argv) { \
|
||||
py_checkargc(2); \
|
||||
PY_CHECK_ARGC(2); \
|
||||
if(py_isint(&argv[1])) { \
|
||||
int64_t lhs = py_toint(&argv[0]); \
|
||||
int64_t rhs = py_toint(&argv[1]); \
|
||||
@ -20,7 +20,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool _py_float##name(int argc, py_Ref argv) { \
|
||||
py_checkargc(2); \
|
||||
PY_CHECK_ARGC(2); \
|
||||
double lhs = py_tofloat(&argv[0]); \
|
||||
double rhs; \
|
||||
if(py_castfloat(&argv[1], &rhs)) { \
|
||||
@ -45,21 +45,21 @@ DEF_NUM_BINARY_OP(__ge__, >=, py_newbool, py_newbool)
|
||||
#undef DEF_NUM_BINARY_OP
|
||||
|
||||
static bool _py_int__neg__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
int64_t val = py_toint(&argv[0]);
|
||||
py_newint(py_retval(), -val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_float__neg__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
double val = py_tofloat(&argv[0]);
|
||||
py_newfloat(py_retval(), -val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_int__truediv__(int argc, py_Ref argv) {
|
||||
py_checkargc(2);
|
||||
PY_CHECK_ARGC(2);
|
||||
int64_t lhs = py_toint(&argv[0]);
|
||||
double rhs;
|
||||
if(py_castfloat(&argv[1], &rhs)) {
|
||||
@ -71,7 +71,7 @@ static bool _py_int__truediv__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_float__truediv__(int argc, py_Ref argv) {
|
||||
py_checkargc(2);
|
||||
PY_CHECK_ARGC(2);
|
||||
double lhs = py_tofloat(&argv[0]);
|
||||
double rhs;
|
||||
if(py_castfloat(&argv[1], &rhs)) {
|
||||
@ -85,7 +85,7 @@ static bool _py_float__truediv__(int argc, py_Ref argv) {
|
||||
#define ZeroDivisionError(msg) false
|
||||
|
||||
static bool _py_number__pow__(int argc, py_Ref argv) {
|
||||
py_checkargc(2);
|
||||
PY_CHECK_ARGC(2);
|
||||
if(py_isint(&argv[0]) && py_isint(&argv[1])) {
|
||||
int64_t lhs = py_toint(&argv[0]);
|
||||
int64_t rhs = py_toint(&argv[1]);
|
||||
@ -98,11 +98,11 @@ static bool _py_number__pow__(int argc, py_Ref argv) {
|
||||
} else {
|
||||
// rhs >= 0
|
||||
int64_t ret = 1;
|
||||
while(true){
|
||||
while(true) {
|
||||
if(rhs & 1) ret *= lhs;
|
||||
rhs >>= 1;
|
||||
if(!rhs) break;
|
||||
lhs *= lhs; // place this here to avoid overflow
|
||||
lhs *= lhs; // place this here to avoid overflow
|
||||
}
|
||||
py_newint(py_retval(), ret);
|
||||
}
|
||||
@ -119,7 +119,7 @@ static bool _py_number__pow__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_int__floordiv__(int argc, py_Ref argv) {
|
||||
py_checkargc(2);
|
||||
PY_CHECK_ARGC(2);
|
||||
int64_t lhs = py_toint(&argv[0]);
|
||||
if(py_isint(&argv[1])) {
|
||||
int64_t rhs = py_toint(&argv[1]);
|
||||
@ -132,7 +132,7 @@ static bool _py_int__floordiv__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_int__mod__(int argc, py_Ref argv) {
|
||||
py_checkargc(2);
|
||||
PY_CHECK_ARGC(2);
|
||||
int64_t lhs = py_toint(&argv[0]);
|
||||
if(py_isint(&argv[1])) {
|
||||
int64_t rhs = py_toint(&argv[1]);
|
||||
@ -145,14 +145,14 @@ static bool _py_int__mod__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_int__invert__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
int64_t val = py_toint(&argv[0]);
|
||||
py_newint(py_retval(), ~val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_int__bit_length(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
int64_t x = py_toint(py_arg(0));
|
||||
if(x < 0) x = -x;
|
||||
int bits = 0;
|
||||
@ -166,7 +166,7 @@ static bool _py_int__bit_length(int argc, py_Ref argv) {
|
||||
|
||||
#define DEF_INT_BITWISE_OP(name, op) \
|
||||
static bool _py_int##name(int argc, py_Ref argv) { \
|
||||
py_checkargc(2); \
|
||||
PY_CHECK_ARGC(2); \
|
||||
int64_t lhs = py_toint(&argv[0]); \
|
||||
if(py_isint(&argv[1])) { \
|
||||
int64_t rhs = py_toint(&argv[1]); \
|
||||
@ -186,7 +186,7 @@ DEF_INT_BITWISE_OP(__rshift__, >>)
|
||||
#undef DEF_INT_BITWISE_OP
|
||||
|
||||
static bool _py_int__repr__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
int64_t val = py_toint(&argv[0]);
|
||||
char buf[32];
|
||||
int size = snprintf(buf, sizeof(buf), "%lld", (long long)val);
|
||||
@ -195,7 +195,7 @@ static bool _py_int__repr__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_float__repr__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
double val = py_tofloat(&argv[0]);
|
||||
char buf[32];
|
||||
int size = snprintf(buf, sizeof(buf), "%f", val);
|
||||
@ -222,7 +222,7 @@ static py_i64 c11_8bytes__hash(union c11_8bytes u) {
|
||||
}
|
||||
|
||||
static bool _py_int__hash__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
int64_t val = py_toint(&argv[0]);
|
||||
union c11_8bytes u = {._i64 = val};
|
||||
py_newint(py_retval(), c11_8bytes__hash(u));
|
||||
@ -230,7 +230,7 @@ static bool _py_int__hash__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool _py_float__hash__(int argc, py_Ref argv) {
|
||||
py_checkargc(1);
|
||||
PY_CHECK_ARGC(1);
|
||||
double val = py_tofloat(&argv[0]);
|
||||
union c11_8bytes u = {._f64 = val};
|
||||
py_newint(py_retval(), c11_8bytes__hash(u));
|
||||
@ -270,11 +270,12 @@ static bool _py_int__new__(int argc, py_Ref argv) {
|
||||
// 1 or 2 args with str
|
||||
int base = 10;
|
||||
if(argc == 1 + 2) {
|
||||
if(!py_checktype(py_arg(2), tp_int)) return false;
|
||||
PY_CHECK_ARG_TYPE(2, tp_int);
|
||||
base = py_toint(py_arg(2));
|
||||
}
|
||||
|
||||
if(!py_checktype(py_arg(1), tp_str)) return false;
|
||||
PY_CHECK_ARG_TYPE(1, tp_str);
|
||||
|
||||
int size;
|
||||
const char* data = py_tostrn(py_arg(1), &size);
|
||||
bool negative = false;
|
||||
@ -322,20 +323,18 @@ static bool _py_float__new__(int argc, py_Ref argv) {
|
||||
int size;
|
||||
const char* data = py_tostrn(py_arg(1), &size);
|
||||
|
||||
if(c11__streq(data, "inf")){
|
||||
if(c11__streq(data, "inf")) {
|
||||
py_newfloat(py_retval(), INFINITY);
|
||||
return true;
|
||||
}
|
||||
if(c11__streq(data, "-inf")){
|
||||
if(c11__streq(data, "-inf")) {
|
||||
py_newfloat(py_retval(), -INFINITY);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* p_end;
|
||||
py_f64 float_out = strtod(data, &p_end);
|
||||
if(p_end != data + size){
|
||||
return ValueError("invalid literal for float(): %q", data);
|
||||
}
|
||||
if(p_end != data + size) { return ValueError("invalid literal for float(): %q", data); }
|
||||
py_newfloat(py_retval(), float_out);
|
||||
return true;
|
||||
}
|
||||
|
@ -82,7 +82,6 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
self->has_error = false;
|
||||
|
||||
self->__curr_class = PY_NIL;
|
||||
self->__cached_object_new = PY_NIL;
|
||||
self->__dynamic_func_decl = NULL;
|
||||
|
||||
pk_ManagedHeap__ctor(&self->heap, self);
|
||||
@ -99,6 +98,7 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
|
||||
validate(tp_int, pk_VM__new_type(self, "int", tp_object, NULL, false));
|
||||
validate(tp_float, pk_VM__new_type(self, "float", tp_object, NULL, false));
|
||||
pk_number__register();
|
||||
validate(tp_bool, pk_VM__new_type(self, "bool", tp_object, NULL, false));
|
||||
validate(tp_str, pk_str__register());
|
||||
|
||||
@ -155,7 +155,7 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
tp_stop_iteration,
|
||||
tp_syntax_error};
|
||||
|
||||
for(int i = 0; i < PK_ARRAY_COUNT(public_types); i++) {
|
||||
for(int i = 0; i < c11__count_array(public_types); i++) {
|
||||
py_Type t = public_types[i];
|
||||
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
|
||||
py_setdict(&self->builtins, ti->name, py_tpobject(t));
|
||||
@ -166,7 +166,6 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
|
||||
|
||||
/* Do Buildin Bindings*/
|
||||
pk_number__register();
|
||||
// object.__new__
|
||||
py_bindmagic(tp_object, __new__, _py_object__new__);
|
||||
|
||||
@ -286,7 +285,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
||||
return __py_generator(
|
||||
callstack.popx(),
|
||||
ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals));
|
||||
default: PK_UNREACHABLE()
|
||||
default: c11__unreachedable()
|
||||
};
|
||||
|
||||
// simple or normal
|
||||
@ -373,7 +372,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
||||
}
|
||||
|
||||
TypeError("'%t' object is not callable", p0->type);
|
||||
PK_UNREACHABLE();
|
||||
c11__unreachedable();
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
|
@ -89,7 +89,7 @@ static int pkpy_Dict__probe0(const pkpy_Dict* self, py_TValue key, int hash) {
|
||||
struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, idx);
|
||||
if(pkpy_Var__is_null(&entry->key)) return h;
|
||||
}
|
||||
PK_UNREACHABLE();
|
||||
c11__unreachedable();
|
||||
}
|
||||
|
||||
static int pkpy_Dict__probe1(const pkpy_Dict* self, py_TValue key, int hash) {
|
||||
@ -103,7 +103,7 @@ static int pkpy_Dict__probe1(const pkpy_Dict* self, py_TValue key, int hash) {
|
||||
if(pkpy_Var__is_null(&entry->key)) continue;
|
||||
if(py_eq(&entry->key, &key)) return h;
|
||||
}
|
||||
PK_UNREACHABLE();
|
||||
c11__unreachedable();
|
||||
}
|
||||
|
||||
static void pkpy_Dict__extendht(pkpy_Dict* self) {
|
||||
|
@ -6,13 +6,6 @@
|
||||
|
||||
typedef c11_vector List;
|
||||
|
||||
py_Type pk_list__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &vm->types, type);
|
||||
ti->dtor = (void (*)(void*))c11_vector__dtor;
|
||||
return type;
|
||||
}
|
||||
|
||||
void py_newlist(py_Ref out) {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
@ -67,9 +60,19 @@ void py_list__insert(py_Ref self, int i, const py_Ref val) {
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
bool _py_list__len__(int argc, py_Ref argv){
|
||||
py_checkargc(1);
|
||||
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;
|
||||
}
|
||||
|
||||
py_Type pk_list__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &vm->types, type);
|
||||
ti->dtor = (void (*)(void*))c11_vector__dtor;
|
||||
|
||||
py_bindmagic(type, __len__, _py_list__len__);
|
||||
return type;
|
||||
}
|
@ -177,7 +177,7 @@ static bool
|
||||
PK_DECREF(src);
|
||||
if(res == RES_ERROR) return false;
|
||||
if(res == RES_RETURN) return true;
|
||||
PK_UNREACHABLE();
|
||||
c11__unreachedable();
|
||||
}
|
||||
|
||||
bool py_exec(const char* source) { return pk_VM__exec(pk_current_vm, source, "<exec>", EXEC_MODE); }
|
||||
@ -225,7 +225,7 @@ bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self)
|
||||
*out = *py_getslot(cls_var, 0);
|
||||
*out_self = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
|
||||
break;
|
||||
default: PK_UNREACHABLE();
|
||||
default: c11__unreachedable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -98,3 +98,6 @@ assert (-4)**13 == -67108864
|
||||
assert ~3 == -4
|
||||
assert ~-3 == 2
|
||||
assert ~0 == -1
|
||||
|
||||
# tmp code
|
||||
assert [1, 2].__len__() == 2
|
Loading…
x
Reference in New Issue
Block a user