blueloveTH 5a72730853 backup
2025-02-24 20:56:49 +08:00

90 lines
2.7 KiB
C

#include "pocketpy/pocketpy.h"
#include "pocketpy/interpreter/vm.h"
#include "pocketpy/common/sstream.h"
static bool Enum__wrapper_field(py_Name name, py_Ref value, void* ctx) {
c11_sv name_sv = py_name2sv(name);
if(name_sv.size == 0 || name_sv.data[0] == '_') return true;
py_push(ctx);
py_pushnil();
py_assign(py_pushtmp(), py_name2ref(name));
py_push(value);
bool ok = py_vectorcall(2, 0);
if(!ok) return false;
py_assign(value, py_retval());
return true;
}
static void Enum__on_end_subclass(py_TypeInfo* derived_ti) {
derived_ti->is_sealed = true;
py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self);
}
static bool Enum__new__(int argc, py_Ref argv) {
py_newobject(py_retval(), py_totype(argv), 2, 0);
return true;
}
static bool Enum__init__(int argc, py_Ref argv) {
PY_CHECK_ARGC(3);
PY_CHECK_ARG_TYPE(1, tp_str);
py_setslot(argv, 0, py_arg(1));
py_setslot(argv, 1, py_arg(2));
py_newnone(py_retval());
return true;
}
static bool Enum__str__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
// f'{type(self).__name__}.{self.name}'
c11_sbuf buf;
c11_sbuf__ctor(&buf);
c11_sbuf__write_cstr(&buf, py_tpname(argv->type));
c11_sbuf__write_char(&buf, '.');
c11_sbuf__write_cstr(&buf, py_tostr(py_getslot(argv, 0)));
c11_sbuf__py_submit(&buf, py_retval());
return true;
}
static bool Enum__repr__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
// f'<{str(self)}: {self.value!r}>'
if(!py_str(argv)) return false;
py_push(py_retval()); // str(self)
if(!py_repr(py_getslot(argv, 1))) return false;
py_push(py_retval()); // repr(self.value)
c11_sbuf buf;
c11_sbuf__ctor(&buf);
c11_sbuf__write_cstr(&buf, "<");
c11_sbuf__write_cstr(&buf, py_tostr(py_peek(-2)));
c11_sbuf__write_cstr(&buf, ": ");
c11_sbuf__write_cstr(&buf, py_tostr(py_peek(-1)));
c11_sbuf__write_cstr(&buf, ">");
c11_sbuf__py_submit(&buf, py_retval());
py_shrink(2);
return true;
}
static bool Enum__name(int argc, py_Ref argv) {
py_assign(py_retval(), py_getslot(argv, 0));
return true;
}
static bool Enum__value(int argc, py_Ref argv) {
py_assign(py_retval(), py_getslot(argv, 1));
return true;
}
void pk__add_module_enum() {
py_Ref mod = py_newmodule("enum");
py_Type type = py_newtype("Enum", tp_object, mod, NULL);
py_bindmagic(type, __new__, Enum__new__);
py_bindmagic(type, __init__, Enum__init__);
py_bindmagic(type, __str__, Enum__str__);
py_bindmagic(type, __repr__, Enum__repr__);
py_bindproperty(type, "name", Enum__name, NULL);
py_bindproperty(type, "value", Enum__value, NULL);
pk__type_info(type)->on_end_subclass = Enum__on_end_subclass;
}