This commit is contained in:
blueloveTH 2024-07-05 00:17:53 +08:00
parent 4569547161
commit c2944b7fd8
14 changed files with 94 additions and 78 deletions

View File

@ -15,7 +15,8 @@ extern "C" {
#define PK_REGION(name) 1 #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 // global constants
#define PK_HEX_TABLE "0123456789abcdef" #define PK_HEX_TABLE "0123456789abcdef"
@ -23,17 +24,21 @@ extern "C" {
extern const char* kPlatformStrings[]; extern const char* kPlatformStrings[];
#ifdef _MSC_VER #ifdef _MSC_VER
#define PK_UNREACHABLE() __assume(0); #define c11__unreachedable() __assume(0)
#else #else
#define PK_UNREACHABLE() __builtin_unreachable(); #define c11__unreachedable() __builtin_unreachable()
#endif #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 c11__min(a, b) ((a) < (b) ? (a) : (b))
#define PK_MAX(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 // NARGS
#define PK_NARGS_SEQ(_1, _2, _3, _4, N, ...) N #define PK_NARGS_SEQ(_1, _2, _3, _4, N, ...) N
@ -47,12 +52,13 @@ typedef struct RefCounted {
} RefCounted; } RefCounted;
#define PK_INCREF(obj) (obj)->rc.count++ #define PK_INCREF(obj) (obj)->rc.count++
#define PK_DECREF(obj) do { \ #define PK_DECREF(obj) \
if(--(obj)->rc.count == 0) { \ do { \
(obj)->rc.dtor(obj); \ if(--(obj)->rc.count == 0) { \
free(obj); \ (obj)->rc.dtor(obj); \
} \ free(obj); \
} while(0) } \
} while(0)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -87,7 +87,6 @@ c11_array c11_vector__submit(c11_vector* self);
} \ } \
} while(0) } while(0)
// NOTE: here we do an extra NULL check for it to avoid UB // NOTE: here we do an extra NULL check for it to avoid UB
#define c11__foreach(T, self, it) \ #define c11__foreach(T, self, it) \
for(T* it = (self)->data; it && it != (T*)(self)->data + (self)->count; it++) for(T* it = (self)->data; it && it != (T*)(self)->data + (self)->count; it++)

View File

@ -57,7 +57,6 @@ typedef struct pk_VM {
py_TValue reg[8]; // users' registers py_TValue reg[8]; // users' registers
py_TValue __curr_class; py_TValue __curr_class;
py_TValue __cached_object_new;
FuncDecl_ __dynamic_func_decl; FuncDecl_ __dynamic_func_decl;
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES]; py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];

View File

@ -115,10 +115,13 @@ bool py_isinstance(const py_Ref obj, py_Type type);
bool py_issubclass(py_Type derived, py_Type base); bool py_issubclass(py_Type derived, py_Type base);
/************* References *************/ /************* 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_offset(p, i) (py_Ref)((char*)p + ((i) << 4))
#define py_arg(i) py_offset(argv, i) #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); py_GlobalRef py_tpmagic(py_Type type, py_Name name);
#define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f)) #define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f))
@ -375,3 +378,13 @@ enum py_PredefinedTypes {
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #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.
*/

View File

@ -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 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; if(res != 0) return res;
return self.size - other.size; return self.size - other.size;
} }
int c11_sv__cmp2(c11_sv self, const char* other) { int c11_sv__cmp2(c11_sv self, const char* other) {
int size = strlen(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; if(res != 0) return res;
return self.size - size; 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 & 0b11111000) == 0b11110000) return 4;
if((c & 0b11111100) == 0b11111000) return 5; if((c & 0b11111100) == 0b11111000) return 5;
if((c & 0b11111110) == 0b11111100) return 6; 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; return 0;
} }
IntParsingResult c11__parse_uint(c11_sv text, int64_t* out, int base) { IntParsingResult c11__parse_uint(c11_sv text, int64_t* out, int base) {
*out = 0; *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(base == -1) {
if(c11__sveq(prefix, "0b")) if(c11__sveq(prefix, "0b"))
base = 2; base = 2;

View File

@ -31,16 +31,14 @@ void py_Name__finalize() {
c11_vector__dtor(&_r_interned); c11_vector__dtor(&_r_interned);
} }
py_Name py_name(const char* name) { py_Name py_name(const char* name) { return py_name2((c11_sv){name, strlen(name)}); }
return py_name2((c11_sv){name, strlen(name)});
}
py_Name py_name2(c11_sv name) { py_Name py_name2(c11_sv name) {
// TODO: PK_GLOBAL_SCOPE_LOCK() // TODO: PK_GLOBAL_SCOPE_LOCK()
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0); uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
if(index != 0) return index; if(index != 0) return index;
// generate new 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 // NOTE: we must allocate the string in the heap so iterators are not invalidated
char* p = malloc(name.size + 1); char* p = malloc(name.size + 1);
memcpy(p, name.data, name.size); memcpy(p, name.data, name.size);
@ -64,8 +62,4 @@ c11_sv py_name2sv(py_Name index) {
return (c11_sv){p, strlen(p)}; return (c11_sv){p, strlen(p)};
} }
bool py_ismagicname(py_Name name) { return name <= __missing__; }
bool py_ismagicname(py_Name name){
return name <= __missing__;
}

View File

@ -129,7 +129,7 @@ bool NameExpr__emit_del(Expr* self_, Ctx* ctx) {
break; break;
case NAME_GLOBAL: Ctx__emit_(ctx, OP_DELETE_GLOBAL, self->name, self->line); 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; case NAME_GLOBAL_UNKNOWN: Ctx__emit_(ctx, OP_DELETE_NAME, self->name, self->line); break;
default: PK_UNREACHABLE(); default: c11__unreachedable();
} }
return true; return true;
} }
@ -294,7 +294,7 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line); Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line);
break; 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_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: Ctx__emit_(self, OP_STORE_GLOBAL, name, line); break;
case NAME_GLOBAL_UNKNOWN: Ctx__emit_(self, OP_STORE_NAME, 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 #define SyntaxError(...) NULL
static Error* NeedMoreLines() { return NULL; } static Error* NeedMoreLines() { return NULL; }
/* Matchers */ /* Matchers */

View File

@ -52,7 +52,7 @@ static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
PUSH(&self->last_retval); \ PUSH(&self->last_retval); \
goto __NEXT_FRAME; \ goto __NEXT_FRAME; \
case RES_ERROR: goto __ERROR; \ case RES_ERROR: goto __ERROR; \
default: PK_UNREACHABLE(); \ default: c11__unreachedable(); \
} \ } \
} while(0) } while(0)
@ -671,7 +671,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
*TOP() = self->last_retval; *TOP() = self->last_retval;
DISPATCH(); DISPATCH();
} }
default: PK_UNREACHABLE(); default: c11__unreachedable();
} }
assert(false); // should never reach here assert(false); // should never reach here

View File

@ -5,7 +5,7 @@
#define DEF_NUM_BINARY_OP(name, op, rint, rfloat) \ #define DEF_NUM_BINARY_OP(name, op, rint, rfloat) \
static bool _py_int##name(int argc, py_Ref argv) { \ static bool _py_int##name(int argc, py_Ref argv) { \
py_checkargc(2); \ PY_CHECK_ARGC(2); \
if(py_isint(&argv[1])) { \ if(py_isint(&argv[1])) { \
int64_t lhs = py_toint(&argv[0]); \ int64_t lhs = py_toint(&argv[0]); \
int64_t rhs = py_toint(&argv[1]); \ int64_t rhs = py_toint(&argv[1]); \
@ -20,7 +20,7 @@
return true; \ return true; \
} \ } \
static bool _py_float##name(int argc, py_Ref argv) { \ static bool _py_float##name(int argc, py_Ref argv) { \
py_checkargc(2); \ PY_CHECK_ARGC(2); \
double lhs = py_tofloat(&argv[0]); \ double lhs = py_tofloat(&argv[0]); \
double rhs; \ double rhs; \
if(py_castfloat(&argv[1], &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 #undef DEF_NUM_BINARY_OP
static bool _py_int__neg__(int argc, py_Ref argv) { static bool _py_int__neg__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); int64_t val = py_toint(&argv[0]);
py_newint(py_retval(), -val); py_newint(py_retval(), -val);
return true; return true;
} }
static bool _py_float__neg__(int argc, py_Ref argv) { static bool _py_float__neg__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); double val = py_tofloat(&argv[0]);
py_newfloat(py_retval(), -val); py_newfloat(py_retval(), -val);
return true; return true;
} }
static bool _py_int__truediv__(int argc, py_Ref argv) { static bool _py_int__truediv__(int argc, py_Ref argv) {
py_checkargc(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); int64_t lhs = py_toint(&argv[0]);
double rhs; double rhs;
if(py_castfloat(&argv[1], &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) { static bool _py_float__truediv__(int argc, py_Ref argv) {
py_checkargc(2); PY_CHECK_ARGC(2);
double lhs = py_tofloat(&argv[0]); double lhs = py_tofloat(&argv[0]);
double rhs; double rhs;
if(py_castfloat(&argv[1], &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 #define ZeroDivisionError(msg) false
static bool _py_number__pow__(int argc, py_Ref argv) { 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])) { if(py_isint(&argv[0]) && py_isint(&argv[1])) {
int64_t lhs = py_toint(&argv[0]); int64_t lhs = py_toint(&argv[0]);
int64_t rhs = py_toint(&argv[1]); int64_t rhs = py_toint(&argv[1]);
@ -98,11 +98,11 @@ static bool _py_number__pow__(int argc, py_Ref argv) {
} else { } else {
// rhs >= 0 // rhs >= 0
int64_t ret = 1; int64_t ret = 1;
while(true){ while(true) {
if(rhs & 1) ret *= lhs; if(rhs & 1) ret *= lhs;
rhs >>= 1; rhs >>= 1;
if(!rhs) break; if(!rhs) break;
lhs *= lhs; // place this here to avoid overflow lhs *= lhs; // place this here to avoid overflow
} }
py_newint(py_retval(), ret); 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) { static bool _py_int__floordiv__(int argc, py_Ref argv) {
py_checkargc(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); int64_t lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) { if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&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) { static bool _py_int__mod__(int argc, py_Ref argv) {
py_checkargc(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); int64_t lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) { if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&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) { static bool _py_int__invert__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); int64_t val = py_toint(&argv[0]);
py_newint(py_retval(), ~val); py_newint(py_retval(), ~val);
return true; return true;
} }
static bool _py_int__bit_length(int argc, py_Ref argv) { 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)); int64_t x = py_toint(py_arg(0));
if(x < 0) x = -x; if(x < 0) x = -x;
int bits = 0; 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) \ #define DEF_INT_BITWISE_OP(name, op) \
static bool _py_int##name(int argc, py_Ref argv) { \ static bool _py_int##name(int argc, py_Ref argv) { \
py_checkargc(2); \ PY_CHECK_ARGC(2); \
int64_t lhs = py_toint(&argv[0]); \ int64_t lhs = py_toint(&argv[0]); \
if(py_isint(&argv[1])) { \ if(py_isint(&argv[1])) { \
int64_t rhs = py_toint(&argv[1]); \ int64_t rhs = py_toint(&argv[1]); \
@ -186,7 +186,7 @@ DEF_INT_BITWISE_OP(__rshift__, >>)
#undef DEF_INT_BITWISE_OP #undef DEF_INT_BITWISE_OP
static bool _py_int__repr__(int argc, py_Ref argv) { static bool _py_int__repr__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); int64_t val = py_toint(&argv[0]);
char buf[32]; char buf[32];
int size = snprintf(buf, sizeof(buf), "%lld", (long long)val); 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) { static bool _py_float__repr__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); double val = py_tofloat(&argv[0]);
char buf[32]; char buf[32];
int size = snprintf(buf, sizeof(buf), "%f", val); 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) { static bool _py_int__hash__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); int64_t val = py_toint(&argv[0]);
union c11_8bytes u = {._i64 = val}; union c11_8bytes u = {._i64 = val};
py_newint(py_retval(), c11_8bytes__hash(u)); 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) { static bool _py_float__hash__(int argc, py_Ref argv) {
py_checkargc(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); double val = py_tofloat(&argv[0]);
union c11_8bytes u = {._f64 = val}; union c11_8bytes u = {._f64 = val};
py_newint(py_retval(), c11_8bytes__hash(u)); 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 // 1 or 2 args with str
int base = 10; int base = 10;
if(argc == 1 + 2) { 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)); 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; int size;
const char* data = py_tostrn(py_arg(1), &size); const char* data = py_tostrn(py_arg(1), &size);
bool negative = false; bool negative = false;
@ -322,20 +323,18 @@ static bool _py_float__new__(int argc, py_Ref argv) {
int size; int size;
const char* data = py_tostrn(py_arg(1), &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); py_newfloat(py_retval(), INFINITY);
return true; return true;
} }
if(c11__streq(data, "-inf")){ if(c11__streq(data, "-inf")) {
py_newfloat(py_retval(), -INFINITY); py_newfloat(py_retval(), -INFINITY);
return true; return true;
} }
char* p_end; char* p_end;
py_f64 float_out = strtod(data, &p_end); py_f64 float_out = strtod(data, &p_end);
if(p_end != data + size){ if(p_end != data + size) { return ValueError("invalid literal for float(): %q", data); }
return ValueError("invalid literal for float(): %q", data);
}
py_newfloat(py_retval(), float_out); py_newfloat(py_retval(), float_out);
return true; return true;
} }

View File

@ -82,7 +82,6 @@ void pk_VM__ctor(pk_VM* self) {
self->has_error = false; self->has_error = false;
self->__curr_class = PY_NIL; self->__curr_class = PY_NIL;
self->__cached_object_new = PY_NIL;
self->__dynamic_func_decl = NULL; self->__dynamic_func_decl = NULL;
pk_ManagedHeap__ctor(&self->heap, self); 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_int, pk_VM__new_type(self, "int", tp_object, NULL, false));
validate(tp_float, pk_VM__new_type(self, "float", 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_bool, pk_VM__new_type(self, "bool", tp_object, NULL, false));
validate(tp_str, pk_str__register()); validate(tp_str, pk_str__register());
@ -155,7 +155,7 @@ void pk_VM__ctor(pk_VM* self) {
tp_stop_iteration, tp_stop_iteration,
tp_syntax_error}; 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]; py_Type t = public_types[i];
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t); pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t);
py_setdict(&self->builtins, ti->name, py_tpobject(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); py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
/* Do Buildin Bindings*/ /* Do Buildin Bindings*/
pk_number__register();
// object.__new__ // object.__new__
py_bindmagic(tp_object, __new__, _py_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( return __py_generator(
callstack.popx(), callstack.popx(),
ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals)); ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals));
default: PK_UNREACHABLE() default: c11__unreachedable()
}; };
// simple or normal // 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); TypeError("'%t' object is not callable", p0->type);
PK_UNREACHABLE(); c11__unreachedable();
} }
/****************************************/ /****************************************/

View File

@ -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); struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, idx);
if(pkpy_Var__is_null(&entry->key)) return h; 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) { 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(pkpy_Var__is_null(&entry->key)) continue;
if(py_eq(&entry->key, &key)) return h; if(py_eq(&entry->key, &key)) return h;
} }
PK_UNREACHABLE(); c11__unreachedable();
} }
static void pkpy_Dict__extendht(pkpy_Dict* self) { static void pkpy_Dict__extendht(pkpy_Dict* self) {

View File

@ -6,13 +6,6 @@
typedef c11_vector List; 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) { void py_newlist(py_Ref out) {
pk_VM* vm = pk_current_vm; 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){ static bool _py_list__len__(int argc, py_Ref argv){
py_checkargc(1); PY_CHECK_ARGC(1);
py_i64 res = py_list__len(py_arg(0)); py_i64 res = py_list__len(py_arg(0));
py_newint(py_retval(), res); py_newint(py_retval(), res);
return true; 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;
}

View File

@ -177,7 +177,7 @@ static bool
PK_DECREF(src); PK_DECREF(src);
if(res == RES_ERROR) return false; if(res == RES_ERROR) return false;
if(res == RES_RETURN) return true; 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); } 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 = *py_getslot(cls_var, 0);
*out_self = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self; *out_self = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
break; break;
default: PK_UNREACHABLE(); default: c11__unreachedable();
} }
return true; return true;
} }

View File

@ -98,3 +98,6 @@ assert (-4)**13 == -67108864
assert ~3 == -4 assert ~3 == -4
assert ~-3 == 2 assert ~-3 == 2
assert ~0 == -1 assert ~0 == -1
# tmp code
assert [1, 2].__len__() == 2