From 0f47105b271add1dc6d94688dcd8185e13361ffe Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 5 May 2024 10:51:06 +0800 Subject: [PATCH] doc fix --- include/pocketpy/common.h | 2 + include/pocketpy/vm.h | 92 ++++++++++++++++++++++----------------- src/ceval.cpp | 26 +++++------ src/dataclasses.cpp | 2 +- src/pocketpy.cpp | 6 +-- src/vm.cpp | 24 +++++----- 6 files changed, 84 insertions(+), 68 deletions(-) diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 335ef742..569ea78a 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -109,6 +109,8 @@ struct Type { #define PK_VAR_LAMBDA(x) ([](VM* vm, ArgsView args) { return VAR(x); }) #define PK_ACTION(x) ([](VM* vm, ArgsView args) { x; return vm->None; }) +#define PK_REGION(name) 1 + #ifdef POCKETPY_H #define PK_FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!"); #else diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index c2b23252..2395bd0a 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -128,7 +128,7 @@ struct ImportContext{ class VM { PK_ALWAYS_PASS_BY_POINTER(VM) - VM* vm; // self reference for simplify code + VM* vm; // self reference to simplify code public: ManagedHeap heap; ValueStack s_data; @@ -152,9 +152,9 @@ public: // this is for repr() recursion detection (no need to mark) std::set _repr_recursion_set; - ImportContext __import_context; // for import - PyObject* __last_exception; // last exception - PyObject* __curr_class; // current class being defined + ImportContext __import_context; + PyObject* __last_exception; + PyObject* __curr_class; PyObject* __cached_object_new; std::map __cached_codes; @@ -182,45 +182,50 @@ public: const bool enable_os; VM(bool enable_os=true); - /********** py_xxx **********/ - PyObject* py_str(PyObject* obj); - PyObject* py_repr(PyObject* obj); - PyObject* py_json(PyObject* obj); - PyObject* py_iter(PyObject* obj); - PyObject* py_next(PyObject*); - PyObject* _py_next(const PyTypeInfo*, PyObject*); - PyObject* py_import(Str path, bool throw_err=true); - PyObject* py_negate(PyObject* obj); +#if PK_REGION("Python Equivalents") + PyObject* py_str(PyObject* obj); // x -> str(x) + PyObject* py_repr(PyObject* obj); // x -> repr(x) + PyObject* py_json(PyObject* obj); // x -> json.dumps(x) + PyObject* py_iter(PyObject* obj); // x -> iter(x) + PyObject* py_next(PyObject*); // x -> next(x) + PyObject* _py_next(const PyTypeInfo*, PyObject*); // x -> next(x) with type info cache + PyObject* py_import(Str path, bool throw_err=true); // x -> __import__(x) + PyObject* py_negate(PyObject* obj); // x -> -x - List py_list(PyObject*); - bool py_callable(PyObject* obj); - bool py_bool(PyObject* obj); - i64 py_hash(PyObject* obj); + List py_list(PyObject*); // x -> list(x) + bool py_callable(PyObject* obj); // x -> callable(x) + bool py_bool(PyObject* obj); // x -> bool(x) + i64 py_hash(PyObject* obj); // x -> hash(x) - bool py_eq(PyObject* lhs, PyObject* rhs); - // new in v1.2.9 - bool py_lt(PyObject* lhs, PyObject* rhs); - bool py_le(PyObject* lhs, PyObject* rhs); - bool py_gt(PyObject* lhs, PyObject* rhs); - bool py_ge(PyObject* lhs, PyObject* rhs); - bool py_ne(PyObject* lhs, PyObject* rhs) { return !py_eq(lhs, rhs); } + bool py_eq(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs == rhs + bool py_lt(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs < rhs + bool py_le(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs <= rhs + bool py_gt(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs > rhs + bool py_ge(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs >= rhs + bool py_ne(PyObject* lhs, PyObject* rhs) { // (lhs, rhs) -> lhs != rhs + return !py_eq(lhs, rhs); + } +#endif - /********** utils **********/ +#if PK_REGION("Utility Methods") PyObject* new_module(Str name, Str package=""); + PyObject* new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled=true); ArgsView cast_array_view(PyObject* obj); void set_main_argv(int argc, char** argv); i64 normalized_index(i64 index, int size); Str disassemble(CodeObject_ co); void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step); +#endif - /********** name lookup **********/ +#if PK_REGION("Name Lookup Methods") PyObject* find_name_in_mro(Type cls, StrName name); + PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false); PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true); void delattr(PyObject* obj, StrName name); - PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false); void setattr(PyObject* obj, StrName name, PyObject* value); +#endif - /********** execution **********/ +#if PK_REGION("Source Execution Methods") CodeObject_ compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false); Str precompile(std::string_view source, const Str& filename, CompileMode mode); PyObject* exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module=nullptr); @@ -232,8 +237,9 @@ public: callstack.emplace(s_data._sp, std::forward(args)...); return __run_top_frame(); } +#endif - /********** invocation **********/ +#if PK_REGION("Invocation Methods") PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false); template @@ -255,12 +261,14 @@ public: PyObject* callable = get_unbound_method(self, name, &self); return call_method(self, callable, args...); } +#endif - /********** io **********/ +#if PK_REGION("Logging Methods") virtual void stdout_write(const Str& s){ _stdout(s.data, s.size); } virtual void stderr_write(const Str& s){ _stderr(s.data, s.size); } +#endif - /********** bindings **********/ +#if PK_REGION("Magic Bindings") void bind__repr__(Type type, PyObject* (*f)(VM*, PyObject*)); void bind__str__(Type type, PyObject* (*f)(VM*, PyObject*)); void bind__iter__(Type type, PyObject* (*f)(VM*, PyObject*)); @@ -296,7 +304,9 @@ public: void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)); void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)); void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)); - // new style binding api +#endif + +#if PK_REGION("General Bindings") PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, UserData userdata={}, BindType bt=BindType::DEFAULT); PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, UserData userdata={}, BindType bt=BindType::DEFAULT){ return bind_func(_t(type), name, argc, fn, userdata, bt); @@ -304,19 +314,21 @@ public: PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr); template PyObject* bind_field(PyObject*, const char*, F T::*); - // without docstring + PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT); - // with docstring + PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT); template PyObject* bind(PyObject*, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT); - /********** error **********/ +#endif + +#if PK_REGION("Error Reporting Methods") void _error(PyObject*); void StackOverflowError() { __builtin_error("StackOverflowError"); } void IOError(const Str& msg) { __builtin_error("IOError", msg); } @@ -337,10 +349,9 @@ public: void BinaryOptError(const char* op, PyObject* _0, PyObject* _1); void AttributeError(PyObject* obj, StrName name); void AttributeError(const Str& msg){ __builtin_error("AttributeError", msg); } +#endif - /********** type **********/ - PyObject* new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled=true); - const PyTypeInfo* _inst_type_info(PyObject* obj); +#if PK_REGION("Type Checking Methods") bool isinstance(PyObject* obj, Type base); bool issubclass(Type cls, Type base); void check_type(PyObject* obj, Type type){ if(!is_type(obj, type)) TypeError(type, _tp(obj)); } @@ -348,8 +359,10 @@ public: PyObject* _t(PyObject* obj){ return _all_types[_tp(obj)].obj; } PyObject* _t(Type t){ return _all_types[t.index].obj; } Type _tp(PyObject* obj){ return is_small_int(obj) ? tp_int : obj->type; } + const PyTypeInfo* _tp_info(PyObject* obj); +#endif - /********** user type **********/ +#if PK_REGION("User Type Registration") template Type _tp_user(){ return _find_type_in_cxx_typeid_map(); } template @@ -379,6 +392,7 @@ public: } return it->second; } +#endif /********** private **********/ virtual ~VM(); diff --git a/src/ceval.cpp b/src/ceval.cpp index 13ca1701..4d993cba 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -17,7 +17,7 @@ namespace pkpy{ #define BINARY_F_COMPARE(func, op, rfunc) \ PyObject* ret; \ - const PyTypeInfo* _ti = _inst_type_info(_0); \ + const PyTypeInfo* _ti = _tp_info(_0); \ if(_ti->m##func){ \ ret = _ti->m##func(this, _0, _1); \ }else{ \ @@ -48,7 +48,7 @@ void VM::__op_unpack_sequence(uint16_t arg){ }else{ auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!! _0 = py_iter(_0); - const PyTypeInfo* ti = _inst_type_info(_0); + const PyTypeInfo* ti = _tp_info(_0); for(int i=0; im__getitem__){ TOP() = _ti->m__getitem__(this, _0, _1); }else{ @@ -235,7 +235,7 @@ __NEXT_STEP:; PyObject* _1 = frame->_locals[byte.arg]; if(_1 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]); PyObject* _0 = TOP(); // a - auto _ti = _inst_type_info(_0); + auto _ti = _tp_info(_0); if(_ti->m__getitem__){ TOP() = _ti->m__getitem__(this, _0, _1); }else{ @@ -245,7 +245,7 @@ __NEXT_STEP:; case OP_LOAD_SUBSCR_SMALL_INT:{ PyObject* _1 = (PyObject*)(uintptr_t)byte.arg; PyObject* _0 = TOP(); // a - auto _ti = _inst_type_info(_0); + auto _ti = _tp_info(_0); if(_ti->m__getitem__){ TOP() = _ti->m__getitem__(this, _0, _1); }else{ @@ -279,7 +279,7 @@ __NEXT_STEP:; PyObject* _2 = POPX(); // b PyObject* _1 = POPX(); // a PyObject* _0 = POPX(); // val - auto _ti = _inst_type_info(_1); + auto _ti = _tp_info(_1); if(_ti->m__setitem__){ _ti->m__setitem__(this, _1, _2, _0); }else{ @@ -291,7 +291,7 @@ __NEXT_STEP:; if(_2 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]); PyObject* _1 = POPX(); // a PyObject* _0 = POPX(); // val - auto _ti = _inst_type_info(_1); + auto _ti = _tp_info(_1); if(_ti->m__setitem__){ _ti->m__setitem__(this, _1, _2, _0); }else{ @@ -324,7 +324,7 @@ __NEXT_STEP:; case OP_DELETE_SUBSCR:{ PyObject* _1 = POPX(); PyObject* _0 = POPX(); - auto _ti = _inst_type_info(_0); + auto _ti = _tp_info(_0); if(_ti->m__delitem__){ _ti->m__delitem__(this, _0, _1); }else{ @@ -423,7 +423,7 @@ __NEXT_STEP:; } DISPATCH() /*****************************************/ #define BINARY_OP_SPECIAL(func) \ - _ti = _inst_type_info(_0); \ + _ti = _tp_info(_0); \ if(_ti->m##func){ \ TOP() = _ti->m##func(this, _0, _1); \ }else{ \ @@ -589,7 +589,7 @@ __NEXT_STEP:; } DISPATCH() case OP_CONTAINS_OP:{ // a in b -> b __contains__ a - auto _ti = _inst_type_info(TOP()); + auto _ti = _tp_info(TOP()); PyObject* _0; if(_ti->m__contains__){ _0 = _ti->m__contains__(this, TOP(), SECOND()); @@ -749,7 +749,7 @@ __NEXT_STEP:; DISPATCH() case OP_UNARY_INVERT:{ PyObject* _0; - auto _ti = _inst_type_info(TOP()); + auto _ti = _tp_info(TOP()); if(_ti->m__invert__) _0 = _ti->m__invert__(this, TOP()); else _0 = call_method(TOP(), __invert__); TOP() = _0; @@ -790,7 +790,7 @@ __NEXT_STEP:; } DISPATCH() case OP_FOR_ITER_UNPACK:{ PyObject* _0 = TOP(); - const PyTypeInfo* _ti = _inst_type_info(_0); + const PyTypeInfo* _ti = _tp_info(_0); if(_ti->m__next__){ unsigned n = _ti->m__next__(this, _0); if(n == 0){ @@ -850,7 +850,7 @@ __NEXT_STEP:; case OP_UNPACK_EX: { auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!! PyObject* _0 = py_iter(POPX()); - const PyTypeInfo* _ti = _inst_type_info(_0); + const PyTypeInfo* _ti = _tp_info(_0); PyObject* _1; for(int i=0; ibind_func(mod, "asdict", 1, [](VM* vm, ArgsView args){ - const auto& fields = vm->_inst_type_info(args[0])->annotated_fields; + const auto& fields = vm->_tp_info(args[0])->annotated_fields; const NameDict& obj_d = args[0]->attr(); Dict d(vm); for(StrName field: fields){ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 82eb28db..658fcf67 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -249,7 +249,7 @@ void __init_builtins(VM* _vm) { }); _vm->bind_func(_vm->builtins, "len", 1, [](VM* vm, ArgsView args){ - const PyTypeInfo* ti = vm->_inst_type_info(args[0]); + const PyTypeInfo* ti = vm->_tp_info(args[0]); if(ti->m__len__) return VAR(ti->m__len__(vm, args[0])); return vm->call_method(args[0], __len__); }); @@ -691,7 +691,7 @@ void __init_builtins(VM* _vm) { const Str& self = _CAST(Str&, args[0]); SStream ss; PyObject* it = vm->py_iter(args[1]); // strong ref - const PyTypeInfo* info = vm->_inst_type_info(args[1]); + const PyTypeInfo* info = vm->_tp_info(args[1]); PyObject* obj = vm->_py_next(info, it); while(obj != vm->StopIteration){ if(!ss.empty()) ss << self; @@ -913,7 +913,7 @@ void __init_builtins(VM* _vm) { auto _lock = vm->heap.gc_scope_lock(); List& self = _CAST(List&, args[0]); PyObject* it = vm->py_iter(args[1]); // strong ref - const PyTypeInfo* info = vm->_inst_type_info(args[1]); + const PyTypeInfo* info = vm->_tp_info(args[1]); PyObject* obj = vm->_py_next(info, it); while(obj != vm->StopIteration){ self.push_back(obj); diff --git a/src/vm.cpp b/src/vm.cpp index 77239a1d..87420749 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -84,7 +84,7 @@ namespace pkpy{ } PyObject* VM::py_str(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); if(ti->m__str__) return ti->m__str__(this, obj); PyObject* self; PyObject* f = get_unbound_method(obj, __str__, &self, false); @@ -93,7 +93,7 @@ namespace pkpy{ } PyObject* VM::py_repr(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); if(ti->m__repr__) return ti->m__repr__(this, obj); return call_method(obj, __repr__); } @@ -104,7 +104,7 @@ namespace pkpy{ } PyObject* VM::py_iter(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); if(ti->m__iter__) return ti->m__iter__(this, obj); PyObject* self; PyObject* iter_f = get_unbound_method(obj, __iter__, &self, false); @@ -212,14 +212,14 @@ namespace pkpy{ return obj; } - const PyTypeInfo* VM::_inst_type_info(PyObject* obj){ + const PyTypeInfo* VM::_tp_info(PyObject* obj){ if(is_small_int(obj)) return &_all_types[tp_int]; return &_all_types[obj->type]; } bool VM::py_eq(PyObject* lhs, PyObject* rhs){ if(lhs == rhs) return true; - const PyTypeInfo* ti = _inst_type_info(lhs); + const PyTypeInfo* ti = _tp_info(lhs); PyObject* res; if(ti->m__eq__){ res = ti->m__eq__(this, lhs, rhs); @@ -228,7 +228,7 @@ namespace pkpy{ res = call_method(lhs, __eq__, rhs); if(res != vm->NotImplemented) return res == vm->True; - ti = _inst_type_info(rhs); + ti = _tp_info(rhs); if(ti->m__eq__){ res = ti->m__eq__(this, rhs, lhs); if(res != vm->NotImplemented) return res == vm->True; @@ -255,7 +255,7 @@ namespace pkpy{ } PyObject* VM::py_next(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); return _py_next(ti, obj); } @@ -394,7 +394,7 @@ namespace pkpy{ } PyObject* VM::py_negate(PyObject* obj){ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); if(ti->m__neg__) return ti->m__neg__(this, obj); return call_method(obj, __neg__); } @@ -418,7 +418,7 @@ List VM::py_list(PyObject* it){ auto _lock = heap.gc_scope_lock(); it = py_iter(it); List list; - const PyTypeInfo* info = _inst_type_info(it); + const PyTypeInfo* info = _tp_info(it); PyObject* obj = _py_next(info, it); while(obj != StopIteration){ list.push_back(obj); @@ -473,7 +473,7 @@ void VM::parse_int_slice(const Slice& s, int length, int& start, int& stop, int& i64 VM::py_hash(PyObject* obj){ // https://docs.python.org/3.10/reference/datamodel.html#object.__hash__ - const PyTypeInfo* ti = _inst_type_info(obj); + const PyTypeInfo* ti = _tp_info(obj); if(ti->m__hash__) return ti->m__hash__(this, obj); PyObject* self; @@ -814,7 +814,7 @@ void VM::__unpack_as_list(ArgsView args, List& list){ // maybe this check should be done in the compile time if(w.level != 1) TypeError("expected level 1 star wrapper"); PyObject* _0 = py_iter(w.obj); - const PyTypeInfo* info = _inst_type_info(_0); + const PyTypeInfo* info = _tp_info(_0); PyObject* _1 = _py_next(info, _0); while(_1 != StopIteration){ list.push_back(_1); @@ -1048,7 +1048,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ } void VM::delattr(PyObject *_0, StrName _name){ - const PyTypeInfo* ti = _inst_type_info(_0); + const PyTypeInfo* ti = _tp_info(_0); if(ti->m__delattr__ && ti->m__delattr__(this, _0, _name)) return; if(is_tagged(_0) || !_0->is_attr_valid()) TypeError("cannot delete attribute"); if(!_0->attr().del(_name)) AttributeError(_0, _name);