mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
refactor
This commit is contained in:
parent
1ad12abbe1
commit
1e15cb2af2
82
src/cffi.h
82
src/cffi.h
@ -5,7 +5,7 @@
|
|||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
struct CType{
|
struct CType{
|
||||||
PY_CLASS(c, type_)
|
PY_CLASS(CType, c, type_)
|
||||||
|
|
||||||
const char* name; // must be a literal
|
const char* name; // must be a literal
|
||||||
const int size;
|
const int size;
|
||||||
@ -16,7 +16,7 @@ struct CType{
|
|||||||
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
||||||
CType& self = vm->_cast<CType>(args[0]);
|
CType& self = CAST(CType, args[0]);
|
||||||
StrStream ss;
|
StrStream ss;
|
||||||
ss << "<c._type '" << self.name << "' (" << self.size*8 << " bits)>";
|
ss << "<c._type '" << self.name << "' (" << self.size*8 << " bits)>";
|
||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
@ -51,7 +51,7 @@ constexpr int C_TYPE(const char name[]){
|
|||||||
#define C_TYPE_T(x) (kCTypes[C_TYPE(x)])
|
#define C_TYPE_T(x) (kCTypes[C_TYPE(x)])
|
||||||
|
|
||||||
struct Pointer{
|
struct Pointer{
|
||||||
PY_CLASS(c, ptr_)
|
PY_CLASS(Pointer, c, ptr_)
|
||||||
|
|
||||||
void* ptr;
|
void* ptr;
|
||||||
CType ctype; // base type
|
CType ctype; // base type
|
||||||
@ -70,61 +70,61 @@ struct Pointer{
|
|||||||
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
StrStream ss;
|
StrStream ss;
|
||||||
ss << "<" << self.ctype.name << "* at " << (i64)self.ptr << ">";
|
ss << "<" << self.ctype.name << "* at " << (i64)self.ptr << ">";
|
||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "__add__", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "__add__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
return vm->new_object<Pointer>(self + CAST(i64, args[1]));
|
return VAR_T(Pointer, self + CAST(i64, args[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "__sub__", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "__sub__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
return vm->new_object<Pointer>(self - CAST_V(i64, args[1]));
|
return VAR_T(Pointer, self - CAST_V(i64, args[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "__eq__", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "__eq__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
Pointer& other = vm->_cast<Pointer>(args[1]);
|
Pointer& other = CAST(Pointer, args[1]);
|
||||||
return VAR(self.ptr == other.ptr);
|
return VAR(self.ptr == other.ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "__ne__", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "__ne__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
Pointer& other = vm->_cast<Pointer>(args[1]);
|
Pointer& other = CAST(Pointer, args[1]);
|
||||||
return VAR(self.ptr != other.ptr);
|
return VAR(self.ptr != other.ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://docs.python.org/zh-cn/3/library/ctypes.html
|
// https://docs.python.org/zh-cn/3/library/ctypes.html
|
||||||
vm->bind_method<1>(type, "__getitem__", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "__getitem__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
i64 index = CAST_V(i64, args[1]);
|
i64 index = CAST_V(i64, args[1]);
|
||||||
return (self+index).get(vm);
|
return (self+index).get(vm);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<2>(type, "__setitem__", [](VM* vm, Args& args) {
|
vm->bind_method<2>(type, "__setitem__", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
i64 index = CAST_V(i64, args[1]);
|
i64 index = CAST_V(i64, args[1]);
|
||||||
(self+index).set(vm, args[2]);
|
(self+index).set(vm, args[2]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "cast", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "cast", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
CType& ctype = vm->_cast<CType>(args[1]);
|
CType& ctype = CAST(CType, args[1]);
|
||||||
return vm->new_object<Pointer>(self.ptr, ctype);
|
return VAR_T(Pointer, self.ptr, ctype);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "get", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "get", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
return self.get(vm);
|
return self.get(vm);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "set", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "set", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
self.set(vm, args[1]);
|
self.set(vm, args[1]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
@ -155,7 +155,7 @@ struct Pointer{
|
|||||||
case C_TYPE("uint16_"): return VAR(ref<uint16_t>());
|
case C_TYPE("uint16_"): return VAR(ref<uint16_t>());
|
||||||
case C_TYPE("uint32_"): return VAR(ref<uint32_t>());
|
case C_TYPE("uint32_"): return VAR(ref<uint32_t>());
|
||||||
case C_TYPE("uint64_"): return VAR(ref<uint64_t>());
|
case C_TYPE("uint64_"): return VAR(ref<uint64_t>());
|
||||||
case C_TYPE("void_p_"): return vm->new_object<Pointer>(ref<void*>(), C_TYPE_T("void_"));
|
case C_TYPE("void_p_"): return VAR_T(Pointer, ref<void*>(), C_TYPE_T("void_"));
|
||||||
// use macro here to do extension
|
// use macro here to do extension
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ struct Pointer{
|
|||||||
case C_TYPE("uint16_"): ref<uint16_t>() = CAST_V(i64, val); break;
|
case C_TYPE("uint16_"): ref<uint16_t>() = CAST_V(i64, val); break;
|
||||||
case C_TYPE("uint32_"): ref<uint32_t>() = CAST_V(i64, val); break;
|
case C_TYPE("uint32_"): ref<uint32_t>() = CAST_V(i64, val); break;
|
||||||
case C_TYPE("uint64_"): ref<uint64_t>() = CAST_V(i64, val); break;
|
case C_TYPE("uint64_"): ref<uint64_t>() = CAST_V(i64, val); break;
|
||||||
case C_TYPE("void_p_"): ref<void*>() = vm->_cast<Pointer>(val).ptr; break;
|
case C_TYPE("void_p_"): ref<void*>() = CAST(Pointer, val).ptr; break;
|
||||||
// use macro here to do extension
|
// use macro here to do extension
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ static const StructMetaInfo _Point2_info = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Struct {
|
struct Struct {
|
||||||
PY_CLASS(c, struct_)
|
PY_CLASS(Struct, c, struct_)
|
||||||
|
|
||||||
const StructMetaInfo* info;
|
const StructMetaInfo* info;
|
||||||
int8_t* _data; // store any `struct`
|
int8_t* _data; // store any `struct`
|
||||||
@ -238,11 +238,11 @@ struct Struct {
|
|||||||
|
|
||||||
static void _register(VM* vm, PyVar mod, PyVar type){
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||||
vm->bind_static_method<-1>(type, "__new__", [](VM* vm, Args& args) {
|
vm->bind_static_method<-1>(type, "__new__", [](VM* vm, Args& args) {
|
||||||
return vm->new_object<Struct>();
|
return VAR_T(Struct);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
|
||||||
Struct& self = vm->_cast<Struct>(args[0]);
|
Struct& self = CAST(Struct, args[0]);
|
||||||
StrStream ss;
|
StrStream ss;
|
||||||
ss << self.info->name << "(" << ")";
|
ss << self.info->name << "(" << ")";
|
||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
@ -252,41 +252,41 @@ struct Struct {
|
|||||||
|
|
||||||
void add_module_c(VM* vm){
|
void add_module_c(VM* vm){
|
||||||
PyVar mod = vm->new_module("c");
|
PyVar mod = vm->new_module("c");
|
||||||
PyVar ptr_t = vm->register_class<Pointer>(mod);
|
PyVar ptr_t = Pointer::register_class(vm, mod);
|
||||||
vm->register_class<CType>(mod);
|
CType::register_class(vm, mod);
|
||||||
vm->register_class<Struct>(mod);
|
Struct::register_class(vm, mod);
|
||||||
|
|
||||||
for(int i=0; i<kCTypeCount; i++){
|
for(int i=0; i<kCTypeCount; i++){
|
||||||
vm->setattr(mod, kCTypes[i].name, vm->new_object<CType>(kCTypes[i]));
|
vm->setattr(mod, kCTypes[i].name, VAR_T(CType, kCTypes[i]));
|
||||||
}
|
}
|
||||||
vm->setattr(mod, "nullptr", vm->new_object<Pointer>(nullptr, C_TYPE_T("void_")));
|
vm->setattr(mod, "nullptr", VAR_T(Pointer, nullptr, C_TYPE_T("void_")));
|
||||||
|
|
||||||
vm->bind_func<1>(mod, "malloc", [](VM* vm, Args& args) {
|
vm->bind_func<1>(mod, "malloc", [](VM* vm, Args& args) {
|
||||||
i64 size = CAST_V(i64, args[0]);
|
i64 size = CAST_V(i64, args[0]);
|
||||||
return vm->new_object<Pointer>(malloc(size), C_TYPE_T("void_"));
|
return VAR_T(Pointer, malloc(size), C_TYPE_T("void_"));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<1>(mod, "free", [](VM* vm, Args& args) {
|
vm->bind_func<1>(mod, "free", [](VM* vm, Args& args) {
|
||||||
Pointer& self = vm->_cast<Pointer>(args[0]);
|
Pointer& self = CAST(Pointer, args[0]);
|
||||||
free(self.ptr);
|
free(self.ptr);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<1>(mod, "sizeof", [](VM* vm, Args& args) {
|
vm->bind_func<1>(mod, "sizeof", [](VM* vm, Args& args) {
|
||||||
CType& ctype = vm->_cast<CType>(args[0]);
|
CType& ctype = CAST(CType, args[0]);
|
||||||
return VAR(ctype.size);
|
return VAR(ctype.size);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<3>(mod, "memcpy", [](VM* vm, Args& args) {
|
vm->bind_func<3>(mod, "memcpy", [](VM* vm, Args& args) {
|
||||||
Pointer& dst = vm->_cast<Pointer>(args[0]);
|
Pointer& dst = CAST(Pointer, args[0]);
|
||||||
Pointer& src = vm->_cast<Pointer>(args[1]);
|
Pointer& src = CAST(Pointer, args[1]);
|
||||||
i64 size = CAST_V(i64, args[2]);
|
i64 size = CAST_V(i64, args[2]);
|
||||||
memcpy(dst.ptr, src.ptr, size);
|
memcpy(dst.ptr, src.ptr, size);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<3>(mod, "memset", [](VM* vm, Args& args) {
|
vm->bind_func<3>(mod, "memset", [](VM* vm, Args& args) {
|
||||||
Pointer& dst = vm->_cast<Pointer>(args[0]);
|
Pointer& dst = CAST(Pointer, args[0]);
|
||||||
i64 val = CAST_V(i64, args[1]);
|
i64 val = CAST_V(i64, args[1]);
|
||||||
i64 size = CAST_V(i64, args[2]);
|
i64 size = CAST_V(i64, args[2]);
|
||||||
memset(dst.ptr, (int)val, size);
|
memset(dst.ptr, (int)val, size);
|
||||||
@ -296,10 +296,10 @@ void add_module_c(VM* vm){
|
|||||||
vm->bind_func<1>(mod, "strdup", [ptr_t](VM* vm, Args& args) {
|
vm->bind_func<1>(mod, "strdup", [ptr_t](VM* vm, Args& args) {
|
||||||
if(is_type(args[0], vm->tp_str)){
|
if(is_type(args[0], vm->tp_str)){
|
||||||
const Str& s = CAST(Str, args[0]);
|
const Str& s = CAST(Str, args[0]);
|
||||||
return vm->new_object<Pointer>(strdup(s.c_str()), C_TYPE_T("char_"));
|
return VAR_T(Pointer, strdup(s.c_str()), C_TYPE_T("char_"));
|
||||||
}else if(is_type(args[0], OBJ_GET(Type, ptr_t))){
|
}else if(is_type(args[0], OBJ_GET(Type, ptr_t))){
|
||||||
Pointer& p = vm->_cast<Pointer>(args[0]);
|
Pointer& p = CAST(Pointer, args[0]);
|
||||||
return vm->new_object<Pointer>(strdup(p.cast<char*>()), C_TYPE_T("char_"));
|
return VAR_T(Pointer, strdup(p.cast<char*>()), C_TYPE_T("char_"));
|
||||||
}else{
|
}else{
|
||||||
vm->TypeError("strdup() argument must be 'str' or 'char*'");
|
vm->TypeError("strdup() argument must be 'str' or 'char*'");
|
||||||
return vm->None;
|
return vm->None;
|
||||||
@ -307,13 +307,13 @@ void add_module_c(VM* vm){
|
|||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<2>(mod, "strcmp", [](VM* vm, Args& args) {
|
vm->bind_func<2>(mod, "strcmp", [](VM* vm, Args& args) {
|
||||||
Pointer& p1 = vm->_cast<Pointer>(args[0]);
|
Pointer& p1 = CAST(Pointer, args[0]);
|
||||||
Pointer& p2 = vm->_cast<Pointer>(args[1]);
|
Pointer& p2 = CAST(Pointer, args[1]);
|
||||||
return VAR(strcmp(p1.cast<char*>(), p2.cast<char*>()));
|
return VAR(strcmp(p1.cast<char*>(), p2.cast<char*>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_func<1>(mod, "strlen", [](VM* vm, Args& args) {
|
vm->bind_func<1>(mod, "strlen", [](VM* vm, Args& args) {
|
||||||
Pointer& p = vm->_cast<Pointer>(args[0]);
|
Pointer& p = CAST(Pointer, args[0]);
|
||||||
return VAR(strlen(p.cast<char*>()));
|
return VAR(strlen(p.cast<char*>()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
42
src/obj.h
42
src/obj.h
@ -149,14 +149,19 @@ inline bool is_float(const PyVar& obj) noexcept {
|
|||||||
return obj.is_tag_10();
|
return obj.is_tag_10();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PY_CLASS(mod, name) \
|
#define PY_CLASS(T, mod, name) \
|
||||||
inline static Type _type(VM* vm) { \
|
static Type _type(VM* vm) { \
|
||||||
static StrName __x0(#mod); \
|
static StrName __x0(#mod); \
|
||||||
static StrName __x1(#name); \
|
static StrName __x1(#name); \
|
||||||
return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \
|
return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \
|
||||||
} \
|
} \
|
||||||
inline static const char* _mod() { return #mod; } \
|
static PyVar register_class(VM* vm, PyVar mod) { \
|
||||||
inline static const char* _name() { return #name; }
|
PyVar type = vm->new_type_object(mod, #name, vm->_t(vm->tp_object));\
|
||||||
|
if(OBJ_NAME(mod) != #mod) UNREACHABLE(); \
|
||||||
|
T::_register(vm, mod, type); \
|
||||||
|
type->attr()._try_perfect_rehash(); \
|
||||||
|
return type; \
|
||||||
|
}
|
||||||
|
|
||||||
union __8B {
|
union __8B {
|
||||||
i64 _int;
|
i64 _int;
|
||||||
@ -165,16 +170,37 @@ union __8B {
|
|||||||
__8B(f64 val) : _float(val) {}
|
__8B(f64 val) : _float(val) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename, typename = void> struct is_py_class : std::false_type {};
|
||||||
|
template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T py_cast_v(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
T py_cast_v(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T _py_cast_v(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
T _py_cast_v(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& py_cast(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
void _check_py_class(VM* vm, const PyVar& var);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& _py_cast(VM* vm, const PyVar& var) { UNREACHABLE(); }
|
T& py_cast(VM* vm, const PyVar& obj) {
|
||||||
|
if constexpr(is_py_class<T>::value){
|
||||||
|
_check_py_class<T>(vm, obj);
|
||||||
|
return OBJ_GET(T, obj);
|
||||||
|
}else{
|
||||||
|
throw std::runtime_error("bad py_cast() call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
T& _py_cast(VM* vm, const PyVar& obj) {
|
||||||
|
if constexpr(is_py_class<T>::value){
|
||||||
|
return OBJ_GET(T, obj);
|
||||||
|
}else{
|
||||||
|
throw std::runtime_error("bad py_cast() call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define VAR(x) py_var(vm, x)
|
#define VAR(x) py_var(vm, x)
|
||||||
|
#define VAR_T(T, ...) vm->new_object(T::_type(vm), T(__VA_ARGS__))
|
||||||
#define CAST(T, x) py_cast<T>(vm, x)
|
#define CAST(T, x) py_cast<T>(vm, x)
|
||||||
#define CAST_V(T, x) py_cast_v<T>(vm, x)
|
#define CAST_V(T, x) py_cast_v<T>(vm, x)
|
||||||
#define _CAST(T, x) _py_cast<T>(vm, x)
|
#define _CAST(T, x) _py_cast<T>(vm, x)
|
||||||
|
@ -611,7 +611,7 @@ void add_module_dis(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FileIO {
|
struct FileIO {
|
||||||
PY_CLASS(io, FileIO)
|
PY_CLASS(FileIO, io, FileIO)
|
||||||
|
|
||||||
Str file;
|
Str file;
|
||||||
Str mode;
|
Str mode;
|
||||||
@ -630,32 +630,32 @@ struct FileIO {
|
|||||||
|
|
||||||
static void _register(VM* vm, PyVar mod, PyVar type){
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||||
vm->bind_static_method<2>(type, "__new__", [](VM* vm, Args& args){
|
vm->bind_static_method<2>(type, "__new__", [](VM* vm, Args& args){
|
||||||
return vm->new_object<FileIO>(
|
return VAR_T(FileIO,
|
||||||
vm, CAST(Str, args[0]), CAST(Str, args[1])
|
vm, CAST(Str, args[0]), CAST(Str, args[1])
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "read", [](VM* vm, Args& args){
|
vm->bind_method<0>(type, "read", [](VM* vm, Args& args){
|
||||||
FileIO& io = vm->_cast<FileIO>(args[0]);
|
FileIO& io = CAST(FileIO, args[0]);
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
io._fs >> buffer;
|
io._fs >> buffer;
|
||||||
return VAR(buffer);
|
return VAR(buffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "write", [](VM* vm, Args& args){
|
vm->bind_method<1>(type, "write", [](VM* vm, Args& args){
|
||||||
FileIO& io = vm->_cast<FileIO>(args[0]);
|
FileIO& io = CAST(FileIO, args[0]);
|
||||||
io._fs << CAST(Str, args[1]);
|
io._fs << CAST(Str, args[1]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "close", [](VM* vm, Args& args){
|
vm->bind_method<0>(type, "close", [](VM* vm, Args& args){
|
||||||
FileIO& io = vm->_cast<FileIO>(args[0]);
|
FileIO& io = CAST(FileIO, args[0]);
|
||||||
io._fs.close();
|
io._fs.close();
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__exit__", [](VM* vm, Args& args){
|
vm->bind_method<0>(type, "__exit__", [](VM* vm, Args& args){
|
||||||
FileIO& io = vm->_cast<FileIO>(args[0]);
|
FileIO& io = CAST(FileIO, args[0]);
|
||||||
io._fs.close();
|
io._fs.close();
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
@ -665,7 +665,7 @@ struct FileIO {
|
|||||||
};
|
};
|
||||||
void add_module_io(VM* vm){
|
void add_module_io(VM* vm){
|
||||||
PyVar mod = vm->new_module("io");
|
PyVar mod = vm->new_module("io");
|
||||||
PyVar type = vm->register_class<FileIO>(mod);
|
PyVar type = FileIO::register_class(vm, mod);
|
||||||
vm->bind_builtin_func<2>("open", [type](VM* vm, const Args& args){
|
vm->bind_builtin_func<2>("open", [type](VM* vm, const Args& args){
|
||||||
return vm->call(type, args);
|
return vm->call(type, args);
|
||||||
});
|
});
|
||||||
@ -674,7 +674,7 @@ void add_module_io(VM* vm){
|
|||||||
void add_module_os(VM* vm){}
|
void add_module_os(VM* vm){}
|
||||||
|
|
||||||
struct ReMatch {
|
struct ReMatch {
|
||||||
PY_CLASS(re, Match)
|
PY_CLASS(ReMatch, re, Match)
|
||||||
|
|
||||||
i64 start;
|
i64 start;
|
||||||
i64 end;
|
i64 end;
|
||||||
@ -683,16 +683,16 @@ struct ReMatch {
|
|||||||
|
|
||||||
static void _register(VM* vm, PyVar mod, PyVar type){
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||||
vm->bind_method<-1>(type, "__init__", CPP_NOT_IMPLEMENTED());
|
vm->bind_method<-1>(type, "__init__", CPP_NOT_IMPLEMENTED());
|
||||||
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(vm->_cast<ReMatch>(args[0]).start)));
|
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(CAST(ReMatch, args[0]).start)));
|
||||||
vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(vm->_cast<ReMatch>(args[0]).end)));
|
vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(CAST(ReMatch, args[0]).end)));
|
||||||
|
|
||||||
vm->bind_method<0>(type, "span", [](VM* vm, Args& args) {
|
vm->bind_method<0>(type, "span", [](VM* vm, Args& args) {
|
||||||
auto& self = vm->_cast<ReMatch>(args[0]);
|
auto& self = CAST(ReMatch, args[0]);
|
||||||
return VAR(two_args(VAR(self.start), VAR(self.end)));
|
return VAR(two_args(VAR(self.start), VAR(self.end)));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<1>(type, "group", [](VM* vm, Args& args) {
|
vm->bind_method<1>(type, "group", [](VM* vm, Args& args) {
|
||||||
auto& self = vm->_cast<ReMatch>(args[0]);
|
auto& self = CAST(ReMatch, args[0]);
|
||||||
int index = (int)CAST_V(i64, args[1]);
|
int index = (int)CAST_V(i64, args[1]);
|
||||||
index = vm->normalized_index(index, self.m.size());
|
index = vm->normalized_index(index, self.m.size());
|
||||||
return VAR(self.m[index].str());
|
return VAR(self.m[index].str());
|
||||||
@ -707,14 +707,14 @@ PyVar _regex_search(const Str& pattern, const Str& string, bool fromStart, VM* v
|
|||||||
if(fromStart && m.position() != 0) return vm->None;
|
if(fromStart && m.position() != 0) return vm->None;
|
||||||
i64 start = string._to_u8_index(m.position());
|
i64 start = string._to_u8_index(m.position());
|
||||||
i64 end = string._to_u8_index(m.position() + m.length());
|
i64 end = string._to_u8_index(m.position() + m.length());
|
||||||
return vm->new_object<ReMatch>(start, end, m);
|
return VAR_T(ReMatch, start, end, m);
|
||||||
}
|
}
|
||||||
return vm->None;
|
return vm->None;
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_module_re(VM* vm){
|
void add_module_re(VM* vm){
|
||||||
PyVar mod = vm->new_module("re");
|
PyVar mod = vm->new_module("re");
|
||||||
vm->register_class<ReMatch>(mod);
|
ReMatch::register_class(vm, mod);
|
||||||
|
|
||||||
vm->bind_func<2>(mod, "match", [](VM* vm, Args& args) {
|
vm->bind_func<2>(mod, "match", [](VM* vm, Args& args) {
|
||||||
const Str& pattern = CAST(Str, args[0]);
|
const Str& pattern = CAST(Str, args[0]);
|
||||||
|
25
src/vm.h
25
src/vm.h
@ -192,11 +192,6 @@ public:
|
|||||||
return make_sp<PyObject, Py_<RAW(T)>>(type, std::move(_value));
|
return make_sp<PyObject, Py_<RAW(T)>>(type, std::move(_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
|
||||||
inline PyVar new_object(Args&&... args) {
|
|
||||||
return new_object(T::_type(this), T(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int ARGC>
|
template<int ARGC>
|
||||||
void bind_func(Str typeName, Str funcName, NativeFuncRaw fn) {
|
void bind_func(Str typeName, Str funcName, NativeFuncRaw fn) {
|
||||||
bind_func<ARGC>(_types[typeName], funcName, fn);
|
bind_func<ARGC>(_types[typeName], funcName, fn);
|
||||||
@ -290,21 +285,6 @@ public:
|
|||||||
return _all_types[OBJ_GET(Type, _t(obj->type)).index];
|
return _all_types[OBJ_GET(Type, _t(obj->type)).index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
PyVar register_class(PyVar mod){
|
|
||||||
PyVar type = new_type_object(mod, T::_name(), _t(tp_object));
|
|
||||||
if(OBJ_NAME(mod) != T::_mod()) UNREACHABLE();
|
|
||||||
T::_register(this, mod, type);
|
|
||||||
type->attr()._try_perfect_rehash();
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T& _cast(const PyVar& obj){
|
|
||||||
check_type(obj, T::_type(this));
|
|
||||||
return OBJ_GET(T, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
~VM() {
|
~VM() {
|
||||||
if(!use_stdio){
|
if(!use_stdio){
|
||||||
delete _stdout;
|
delete _stdout;
|
||||||
@ -446,6 +426,11 @@ PyVar py_var(VM* vm, const char* val){
|
|||||||
return VAR(Str(val));
|
return VAR(Str(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void _check_py_class(VM* vm, const PyVar& obj){
|
||||||
|
vm->check_type(obj, T::_type(vm));
|
||||||
|
}
|
||||||
|
|
||||||
PyVar VM::num_negated(const PyVar& obj){
|
PyVar VM::num_negated(const PyVar& obj){
|
||||||
if (is_int(obj)){
|
if (is_int(obj)){
|
||||||
return VAR(-CAST_V(i64, obj));
|
return VAR(-CAST_V(i64, obj));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user