This commit is contained in:
blueloveTH 2024-07-06 14:10:03 +08:00
parent 6e1550213c
commit 7feb3047e9
7 changed files with 143 additions and 76 deletions

View File

@ -90,6 +90,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
const char* pk_opname(Opcode op); const char* pk_opname(Opcode op);
// type registration // type registration
void pk_object__register();
void pk_number__register(); void pk_number__register();
py_Type pk_str__register(); py_Type pk_str__register();
py_Type pk_bytes__register(); py_Type pk_bytes__register();

View File

@ -272,24 +272,29 @@ ImagExpr* ImagExpr__new(int line, double value) {
typedef struct LiteralExpr { typedef struct LiteralExpr {
EXPR_COMMON_HEADER EXPR_COMMON_HEADER
const TokenValue* value; const TokenValue* value;
bool negated;
} LiteralExpr; } LiteralExpr;
void LiteralExpr__emit_(Expr* self_, Ctx* ctx) { void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
LiteralExpr* self = (LiteralExpr*)self_; LiteralExpr* self = (LiteralExpr*)self_;
switch(self->value->index) { switch(self->value->index) {
case TokenValue_I64: { case TokenValue_I64: {
int64_t val = self->value->_i64; py_i64 val = self->value->_i64;
if(self->negated) val = -val;
Ctx__emit_int(ctx, val, self->line); Ctx__emit_int(ctx, val, self->line);
break; break;
} }
case TokenValue_F64: { case TokenValue_F64: {
py_TValue value; py_TValue value;
py_newfloat(&value, self->value->_f64); py_f64 val = self->value->_f64;
if(self->negated) val = -val;
py_newfloat(&value, val);
int index = Ctx__add_const(ctx, &value); int index = Ctx__add_const(ctx, &value);
Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line); Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line);
break; break;
} }
case TokenValue_STR: { case TokenValue_STR: {
assert(!self->negated);
c11_sv sv = c11_string__sv(self->value->_str); c11_sv sv = c11_string__sv(self->value->_str);
int index = Ctx__add_const_string(ctx, sv); int index = Ctx__add_const_string(ctx, sv);
Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line); Ctx__emit_(ctx, OP_LOAD_CONST, index, self->line);
@ -308,6 +313,7 @@ LiteralExpr* LiteralExpr__new(int line, const TokenValue* value) {
self->vt = &Vt; self->vt = &Vt;
self->line = line; self->line = line;
self->value = value; self->value = value;
self->negated = false;
return self; return self;
} }
@ -330,9 +336,7 @@ void Literal0Expr__emit_(Expr* self_, Ctx* ctx) {
} }
Literal0Expr* Literal0Expr__new(int line, TokenIndex token) { Literal0Expr* Literal0Expr__new(int line, TokenIndex token) {
const static ExprVt Vt = {.emit_ = Literal0Expr__emit_, const static ExprVt Vt = {.emit_ = Literal0Expr__emit_, .is_json_object = true};
.is_literal = true,
.is_json_object = true};
static_assert_expr_size(Literal0Expr); static_assert_expr_size(Literal0Expr);
Literal0Expr* self = PoolExpr_alloc(); Literal0Expr* self = PoolExpr_alloc();
self->vt = &Vt; self->vt = &Vt;
@ -1771,7 +1775,19 @@ static Error* exprUnaryOp(Compiler* self) {
check(parse_expression(self, PREC_UNARY + 1, false)); check(parse_expression(self, PREC_UNARY + 1, false));
Expr* e = Ctx__s_popx(ctx()); Expr* e = Ctx__s_popx(ctx());
switch(op) { switch(op) {
case TK_SUB: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_NEGATIVE)); break; case TK_SUB: {
// constant fold
if(e->vt->is_literal) {
LiteralExpr* le = (LiteralExpr*)e;
if(le->value->index == TokenValue_I64 || le->value->index == TokenValue_F64) {
le->negated = true;
}
Ctx__s_push(ctx(), e);
} else {
Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_NEGATIVE));
}
break;
}
case TK_INVERT: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_INVERT)); break; case TK_INVERT: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_INVERT)); break;
case TK_MUL: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 1)); break; case TK_MUL: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 1)); break;
case TK_POW: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 2)); break; case TK_POW: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 2)); break;

View File

@ -86,7 +86,27 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
c11_sbuf buf; c11_sbuf buf;
c11_sbuf__ctor(&buf); c11_sbuf__ctor(&buf);
for(py_Ref p = self->stack.begin; p != SP(); p++) { for(py_Ref p = self->stack.begin; p != SP(); p++) {
c11_sbuf__write_cstr(&buf, py_tpname(p->type)); switch(p->type){
case 0: c11_sbuf__write_cstr(&buf, "nil"); break;
case tp_int: c11_sbuf__write_i64(&buf, p->_i64); break;
case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break;
case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break;
case tp_none_type: c11_sbuf__write_cstr(&buf, "None"); break;
case tp_type: {
pk_sprintf(&buf, "<class '%t'>", py_totype(p));
break;
}
case tp_str: {
int size;
const char* data = py_tostrn(p, &size);
pk_sprintf(&buf, "%q", (c11_sv){data, size});
break;
}
default:{
pk_sprintf(&buf, "(%t)", p->type);
break;
}
}
if(p != TOP()) c11_sbuf__write_cstr(&buf, ", "); if(p != TOP()) c11_sbuf__write_cstr(&buf, ", ");
} }
c11_string* stack_str = c11_sbuf__submit(&buf); c11_string* stack_str = c11_sbuf__submit(&buf);
@ -694,17 +714,10 @@ static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
// [a, b] // [a, b]
py_Ref magic = py_tpfindmagic(SECOND()->type, op); py_Ref magic = py_tpfindmagic(SECOND()->type, op);
if(magic) { if(magic) {
if(magic->type == tp_nativefunc) {
bool ok = magic->_cfunc(2, SECOND());
if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) return true;
} else {
// standard call
bool ok = py_call(magic, 2, SECOND()); bool ok = py_call(magic, 2, SECOND());
if(!ok) return false; if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) return true; if(self->last_retval.type != tp_not_implemented_type) return true;
} }
}
// try reverse operation // try reverse operation
if(rop) { if(rop) {
// [a, b] -> [b, a] // [a, b] -> [b, a]
@ -713,18 +726,11 @@ static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
*SECOND() = tmp; *SECOND() = tmp;
magic = py_tpfindmagic(SECOND()->type, rop); magic = py_tpfindmagic(SECOND()->type, rop);
if(magic) { if(magic) {
if(magic->type == tp_nativefunc) {
bool ok = magic->_cfunc(2, SECOND());
if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) return true;
} else {
// standard call
bool ok = py_call(magic, 2, SECOND()); bool ok = py_call(magic, 2, SECOND());
if(!ok) return false; if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) return true; if(self->last_retval.type != tp_not_implemented_type) return true;
} }
} }
}
// eq/ne op never fails due to object.__eq__ // eq/ne op never fails due to object.__eq__
return py_exception("TypeError", "unsupported operand type(s) for '%n'", op); return py_exception("TypeError", "unsupported operand type(s) for '%n'", op);
} }

View File

@ -56,12 +56,7 @@ void pk_TypeInfo__ctor(pk_TypeInfo* self,
void pk_TypeInfo__dtor(pk_TypeInfo* self) { c11_vector__dtor(&self->annotated_fields); } void pk_TypeInfo__dtor(pk_TypeInfo* self) { c11_vector__dtor(&self->annotated_fields); }
static bool _py_object__new__(int argc, py_Ref argv) {
assert(argc >= 1);
py_Type cls = argv[0].type;
py_newobject(py_retval(), cls, 0, 0);
return true;
}
void pk_VM__ctor(pk_VM* self) { void pk_VM__ctor(pk_VM* self) {
self->top_frame = NULL; self->top_frame = NULL;
@ -95,6 +90,7 @@ void pk_VM__ctor(pk_VM* self) {
validate(tp_object, pk_VM__new_type(self, "object", 0, NULL, true)); validate(tp_object, pk_VM__new_type(self, "object", 0, NULL, true));
validate(tp_type, pk_VM__new_type(self, "type", 1, NULL, false)); validate(tp_type, pk_VM__new_type(self, "type", 1, NULL, false));
pk_object__register();
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));
@ -166,10 +162,6 @@ void pk_VM__ctor(pk_VM* self) {
py_newnotimplemented(&tmp); py_newnotimplemented(&tmp);
py_setdict(&self->builtins, py_name("NotImplemented"), &tmp); py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
/* Do Buildin Bindings*/
// object.__new__
py_bindmagic(tp_object, __new__, _py_object__new__);
self->main = *py_newmodule("__main__", NULL); self->main = *py_newmodule("__main__", NULL);
} }

View File

@ -7,12 +7,12 @@
static bool _py_int##name(int argc, py_Ref argv) { \ static bool _py_int##name(int argc, py_Ref argv) { \
PY_CHECK_ARGC(2); \ PY_CHECK_ARGC(2); \
if(py_isint(&argv[1])) { \ if(py_isint(&argv[1])) { \
int64_t lhs = py_toint(&argv[0]); \ py_i64 lhs = py_toint(&argv[0]); \
int64_t rhs = py_toint(&argv[1]); \ py_i64 rhs = py_toint(&argv[1]); \
rint(py_retval(), lhs op rhs); \ rint(py_retval(), lhs op rhs); \
} else if(py_isfloat(&argv[1])) { \ } else if(py_isfloat(&argv[1])) { \
int64_t lhs = py_toint(&argv[0]); \ py_i64 lhs = py_toint(&argv[0]); \
double rhs = py_tofloat(&argv[1]); \ py_f64 rhs = py_tofloat(&argv[1]); \
rfloat(py_retval(), lhs op rhs); \ rfloat(py_retval(), lhs op rhs); \
} else { \ } else { \
py_newnotimplemented(py_retval()); \ py_newnotimplemented(py_retval()); \
@ -21,8 +21,8 @@
} \ } \
static bool _py_float##name(int argc, py_Ref argv) { \ static bool _py_float##name(int argc, py_Ref argv) { \
PY_CHECK_ARGC(2); \ PY_CHECK_ARGC(2); \
double lhs = py_tofloat(&argv[0]); \ py_f64 lhs = py_tofloat(&argv[0]); \
double rhs; \ py_f64 rhs; \
if(py_castfloat(&argv[1], &rhs)) { \ if(py_castfloat(&argv[1], &rhs)) { \
rfloat(py_retval(), lhs op rhs); \ rfloat(py_retval(), lhs op rhs); \
} else { \ } else { \
@ -36,7 +36,7 @@ DEF_NUM_BINARY_OP(__sub__, -, py_newint, py_newfloat)
DEF_NUM_BINARY_OP(__mul__, *, py_newint, py_newfloat) DEF_NUM_BINARY_OP(__mul__, *, py_newint, py_newfloat)
DEF_NUM_BINARY_OP(__eq__, ==, py_newbool, py_newbool) DEF_NUM_BINARY_OP(__eq__, ==, py_newbool, py_newbool)
DEF_NUM_BINARY_OP(__ne__, ==, py_newbool, py_newbool) DEF_NUM_BINARY_OP(__ne__, !=, py_newbool, py_newbool)
DEF_NUM_BINARY_OP(__lt__, <, py_newbool, py_newbool) DEF_NUM_BINARY_OP(__lt__, <, py_newbool, py_newbool)
DEF_NUM_BINARY_OP(__le__, <=, py_newbool, py_newbool) DEF_NUM_BINARY_OP(__le__, <=, py_newbool, py_newbool)
DEF_NUM_BINARY_OP(__gt__, >, py_newbool, py_newbool) DEF_NUM_BINARY_OP(__gt__, >, py_newbool, py_newbool)
@ -46,22 +46,22 @@ DEF_NUM_BINARY_OP(__ge__, >=, py_newbool, py_newbool)
static bool _py_int__neg__(int argc, py_Ref argv) { static bool _py_int__neg__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); py_i64 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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); py_f64 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_CHECK_ARGC(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); py_i64 lhs = py_toint(&argv[0]);
double rhs; py_f64 rhs;
if(py_castfloat(&argv[1], &rhs)) { if(py_castfloat(&argv[1], &rhs)) {
py_newfloat(py_retval(), lhs / rhs); py_newfloat(py_retval(), lhs / rhs);
} else { } else {
@ -72,8 +72,8 @@ 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_CHECK_ARGC(2); PY_CHECK_ARGC(2);
double lhs = py_tofloat(&argv[0]); py_f64 lhs = py_tofloat(&argv[0]);
double rhs; py_f64 rhs;
if(py_castfloat(&argv[1], &rhs)) { if(py_castfloat(&argv[1], &rhs)) {
py_newfloat(py_retval(), lhs / rhs); py_newfloat(py_retval(), lhs / rhs);
} else { } else {
@ -87,8 +87,8 @@ static bool _py_float__truediv__(int argc, py_Ref argv) {
static bool _py_number__pow__(int argc, py_Ref argv) { static bool _py_number__pow__(int argc, py_Ref argv) {
PY_CHECK_ARGC(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]); py_i64 lhs = py_toint(&argv[0]);
int64_t rhs = py_toint(&argv[1]); py_i64 rhs = py_toint(&argv[1]);
if(rhs < 0) { if(rhs < 0) {
if(lhs == 0) { if(lhs == 0) {
return ZeroDivisionError("0.0 cannot be raised to a negative power"); return ZeroDivisionError("0.0 cannot be raised to a negative power");
@ -97,7 +97,7 @@ static bool _py_number__pow__(int argc, py_Ref argv) {
} }
} else { } else {
// rhs >= 0 // rhs >= 0
int64_t ret = 1; py_i64 ret = 1;
while(true) { while(true) {
if(rhs & 1) ret *= lhs; if(rhs & 1) ret *= lhs;
rhs >>= 1; rhs >>= 1;
@ -107,7 +107,7 @@ static bool _py_number__pow__(int argc, py_Ref argv) {
py_newint(py_retval(), ret); py_newint(py_retval(), ret);
} }
} else { } else {
double lhs, rhs; py_f64 lhs, rhs;
py_castfloat(&argv[0], &lhs); py_castfloat(&argv[0], &lhs);
if(py_castfloat(&argv[1], &rhs)) { if(py_castfloat(&argv[1], &rhs)) {
py_newfloat(py_retval(), pow(lhs, rhs)); py_newfloat(py_retval(), pow(lhs, rhs));
@ -120,9 +120,9 @@ 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_CHECK_ARGC(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); py_i64 lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) { if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&argv[1]); py_i64 rhs = py_toint(&argv[1]);
if(rhs == 0) return -1; if(rhs == 0) return -1;
py_newint(py_retval(), lhs / rhs); py_newint(py_retval(), lhs / rhs);
} else { } else {
@ -133,9 +133,9 @@ 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_CHECK_ARGC(2); PY_CHECK_ARGC(2);
int64_t lhs = py_toint(&argv[0]); py_i64 lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) { if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&argv[1]); py_i64 rhs = py_toint(&argv[1]);
if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero"); if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
py_newint(py_retval(), lhs % rhs); py_newint(py_retval(), lhs % rhs);
} else { } else {
@ -146,14 +146,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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); py_i64 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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int64_t x = py_toint(py_arg(0)); py_i64 x = py_toint(py_arg(0));
if(x < 0) x = -x; if(x < 0) x = -x;
int bits = 0; int bits = 0;
while(x) { while(x) {
@ -167,9 +167,9 @@ 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_CHECK_ARGC(2); \ PY_CHECK_ARGC(2); \
int64_t lhs = py_toint(&argv[0]); \ py_i64 lhs = py_toint(&argv[0]); \
if(py_isint(&argv[1])) { \ if(py_isint(&argv[1])) { \
int64_t rhs = py_toint(&argv[1]); \ py_i64 rhs = py_toint(&argv[1]); \
py_newint(py_retval(), lhs op rhs); \ py_newint(py_retval(), lhs op rhs); \
} else { \ } else { \
py_newnotimplemented(py_retval()); \ py_newnotimplemented(py_retval()); \
@ -187,7 +187,7 @@ DEF_INT_BITWISE_OP(__rshift__, >>)
static bool _py_int__repr__(int argc, py_Ref argv) { static bool _py_int__repr__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); py_i64 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);
py_newstrn(py_retval(), buf, size); py_newstrn(py_retval(), buf, size);
@ -196,7 +196,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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); py_f64 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);
py_newstrn(py_retval(), buf, size); py_newstrn(py_retval(), buf, size);
@ -223,7 +223,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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int64_t val = py_toint(&argv[0]); py_i64 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));
return true; return true;
@ -231,7 +231,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_CHECK_ARGC(1); PY_CHECK_ARGC(1);
double val = py_tofloat(&argv[0]); py_f64 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));
return true; return true;
@ -248,7 +248,7 @@ static bool _py_int__new__(int argc, py_Ref argv) {
switch(argv[1].type) { switch(argv[1].type) {
case tp_float: { case tp_float: {
// int(1.1) == 1 // int(1.1) == 1
py_newint(py_retval(), (int64_t)py_tofloat(&argv[1])); py_newint(py_retval(), (py_i64)py_tofloat(&argv[1]));
return true; return true;
} }
case tp_int: { case tp_int: {
@ -258,7 +258,7 @@ static bool _py_int__new__(int argc, py_Ref argv) {
} }
case tp_bool: { case tp_bool: {
// int(True) == 1 // int(True) == 1
py_newint(py_retval(), (int64_t)py_tobool(&argv[1])); py_newint(py_retval(), (py_i64)py_tobool(&argv[1]));
return true; return true;
} }
case tp_str: break; // leave to the next block case tp_str: break; // leave to the next block
@ -340,7 +340,7 @@ static bool _py_float__new__(int argc, py_Ref argv) {
} }
// tp_bool // tp_bool
static bool _py_bool__new__(int argc, py_Ref argv){ static bool _py_bool__new__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int res = py_bool(argv); int res = py_bool(argv);
if(res == -1) return false; if(res == -1) return false;
@ -348,24 +348,24 @@ static bool _py_bool__new__(int argc, py_Ref argv){
return true; return true;
} }
static bool _py_bool__hash__(int argc, py_Ref argv){ static bool _py_bool__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
bool res = py_tobool(argv); bool res = py_tobool(argv);
py_newint(py_retval(), res); py_newint(py_retval(), res);
return true; return true;
} }
static bool _py_bool__repr__(int argc, py_Ref argv){ static bool _py_bool__repr__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
bool res = py_tobool(argv); bool res = py_tobool(argv);
py_newstr(py_retval(), res ? "True" : "False"); py_newstr(py_retval(), res ? "True" : "False");
return true; return true;
} }
static bool _py_bool__eq__(int argc, py_Ref argv){ static bool _py_bool__eq__(int argc, py_Ref argv) {
PY_CHECK_ARGC(2); PY_CHECK_ARGC(2);
bool lhs = py_tobool(&argv[0]); bool lhs = py_tobool(&argv[0]);
if(argv[1].type == tp_bool){ if(argv[1].type == tp_bool) {
bool rhs = py_tobool(&argv[1]); bool rhs = py_tobool(&argv[1]);
py_newbool(py_retval(), lhs == rhs); py_newbool(py_retval(), lhs == rhs);
} else { } else {
@ -374,10 +374,10 @@ static bool _py_bool__eq__(int argc, py_Ref argv){
return true; return true;
} }
static bool _py_bool__ne__(int argc, py_Ref argv){ static bool _py_bool__ne__(int argc, py_Ref argv) {
PY_CHECK_ARGC(2); PY_CHECK_ARGC(2);
bool lhs = py_tobool(&argv[0]); bool lhs = py_tobool(&argv[0]);
if(argv[1].type == tp_bool){ if(argv[1].type == tp_bool) {
bool rhs = py_tobool(&argv[1]); bool rhs = py_tobool(&argv[1]);
py_newbool(py_retval(), lhs != rhs); py_newbool(py_retval(), lhs != rhs);
} else { } else {

37
src/public/py_object.c Normal file
View File

@ -0,0 +1,37 @@
#include "pocketpy/interpreter/vm.h"
#include "pocketpy/pocketpy.h"
static bool _py_object__new__(int argc, py_Ref argv) {
assert(argc >= 1);
py_Type cls = argv[0].type;
py_newobject(py_retval(), cls, 0, 0);
return true;
}
static bool _py_object__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
assert(argv->is_ptr);
py_newint(py_retval(), (py_i64)argv->_obj);
return true;
}
static bool _py_object__eq__(int argc, py_Ref argv) {
PY_CHECK_ARGC(2);
bool res = py_isidentical(py_arg(0), py_arg(1));
py_newbool(py_retval(), res);
return true;
}
static bool _py_object__ne__(int argc, py_Ref argv) {
PY_CHECK_ARGC(2);
bool res = py_isidentical(py_arg(0), py_arg(1));
py_newbool(py_retval(), !res);
return true;
}
void pk_object__register() {
py_bindmagic(tp_object, __new__, _py_object__new__);
py_bindmagic(tp_object, __hash__, _py_object__hash__);
py_bindmagic(tp_object, __eq__, _py_object__eq__);
py_bindmagic(tp_object, __ne__, _py_object__ne__);
}

View File

@ -43,7 +43,22 @@ int py_bool(const py_Ref val) {
} }
} }
bool py_hash(const py_Ref val, int64_t* out) { return 0; } bool py_hash(const py_Ref val, int64_t* out) {
py_Type t = val->type;
pk_TypeInfo* types = (pk_TypeInfo*)pk_current_vm->types.data;
do {
py_Ref _hash = &types[t].magic[__hash__];
py_Ref _eq = &types[t].magic[__eq__];
if(!py_isnil(_hash) && !py_isnil(_eq)) {
bool ok = py_call(_hash, 1, val);
if(!ok) return false;
*out = py_toint(py_retval());
return true;
}
t = types[t].base;
} while(t);
return TypeError("unhashable type: '%t'", val->type);
}
int py_getattr(const py_Ref self, py_Name name, py_Ref out) { return -1; } int py_getattr(const py_Ref self, py_Name name, py_Ref out) { return -1; }