From 1fb4ebdf5bc360aa1be0d681c29121ab5847a47f Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 15 Aug 2024 00:35:30 +0800 Subject: [PATCH] ... --- CMakeLists.txt | 5 +- include/pocketpy/pocketpy.h | 305 ++++++++++++++++++------------------ 2 files changed, 159 insertions(+), 151 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1f6a485..17f3d34b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,10 +52,13 @@ else() endif() if(PK_BUILD_SHARED_LIB) + message(">> Building shared library") add_library(${PROJECT_NAME} SHARED ${POCKETPY_SRC}) elseif(PK_BUILD_STATIC_LIB) + message(">> Building static library") add_library(${PROJECT_NAME} STATIC ${POCKETPY_SRC}) else() + message(">> Building shared library + executable") add_library(${PROJECT_NAME} SHARED ${POCKETPY_SRC}) add_executable(main src2/main.c) target_link_libraries(main ${PROJECT_NAME}) @@ -63,5 +66,5 @@ endif() # link math library if(UNIX) - target_link_libraries(${PROJECT_NAME} PRIVATE m) + target_link_libraries(${PROJECT_NAME} m) endif() \ No newline at end of file diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index bb16f4e1..baf4aa56 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -65,27 +65,27 @@ typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE PY_RETURN; enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE }; /// A shorthand for `True`. -extern py_GlobalRef py_True; +PK_EXPORT extern py_GlobalRef py_True; /// A shorthand for `False`. -extern py_GlobalRef py_False; +PK_EXPORT extern py_GlobalRef py_False; /// A shorthand for `None`. -extern py_GlobalRef py_None; +PK_EXPORT extern py_GlobalRef py_None; /// A shorthand for `nil`. `nil` is not a valid python object. -extern py_GlobalRef py_NIL; +PK_EXPORT extern py_GlobalRef py_NIL; /************* Global Setup *************/ /// Initialize pocketpy and the default VM. -void py_initialize(); +PK_EXPORT void py_initialize(); /// Finalize pocketpy and free all VMs. -void py_finalize(); +PK_EXPORT void py_finalize(); /// Get the current VM index. -int py_currentvm(); +PK_EXPORT int py_currentvm(); /// Switch to a VM. /// @param index index of the VM ranging from 0 to 16 (exclusive). `0` is the default VM. -void py_switchvm(int index); +PK_EXPORT void py_switchvm(int index); /// Set `sys.argv`. Used for storing command-line arguments. -void py_sys_setargv(int argc, char** argv); +PK_EXPORT void py_sys_setargv(int argc, char** argv); /// Run a source string. /// @param source source string. @@ -93,81 +93,81 @@ void py_sys_setargv(int argc, char** argv); /// @param mode compile mode. Use `EXEC_MODE` for statements `EVAL_MODE` for expressions. /// @param module target module. Use NULL for the main module. /// @return `true` if the execution is successful or `false` if an exception is raised. -bool py_exec(const char* source, - const char* filename, - enum py_CompileMode mode, - py_Ref module) PY_RAISE PY_RETURN; +PK_EXPORT bool py_exec(const char* source, + const char* filename, + enum py_CompileMode mode, + py_Ref module) PY_RAISE PY_RETURN; /// Evaluate a source string. Equivalent to `py_exec(source, "", EVAL_MODE, module)`. -bool py_eval(const char* source, py_Ref module) PY_RAISE PY_RETURN; +PK_EXPORT bool py_eval(const char* source, py_Ref module) PY_RAISE PY_RETURN; /// Compile a source string into a code object. /// Use python's `exec()` or `eval()` to execute it. -bool py_compile(const char* source, - const char* filename, - enum py_CompileMode mode, - bool is_dynamic) PY_RAISE PY_RETURN; +PK_EXPORT bool py_compile(const char* source, + const char* filename, + enum py_CompileMode mode, + bool is_dynamic) PY_RAISE PY_RETURN; /// Python equivalent to `globals()`. -void py_newglobals(py_Ref); +PK_EXPORT void py_newglobals(py_Ref); /// Python equivalent to `locals()`. /// @return a temporary object, which expires on the associated function return. -void py_newlocals(py_Ref); +PK_EXPORT void py_newlocals(py_Ref); /************* Values Creation *************/ /// Create an `int` object. -void py_newint(py_Ref, py_i64); +PK_EXPORT void py_newint(py_Ref, py_i64); /// Create a `float` object. -void py_newfloat(py_Ref, py_f64); +PK_EXPORT void py_newfloat(py_Ref, py_f64); /// Create a `bool` object. -void py_newbool(py_Ref, bool); +PK_EXPORT void py_newbool(py_Ref, bool); /// Create a `str` object from a null-terminated string (utf-8). -void py_newstr(py_Ref, const char*); +PK_EXPORT void py_newstr(py_Ref, const char*); /// Create a `str` object from a char array (utf-8). -void py_newstrn(py_Ref, const char*, int); +PK_EXPORT void py_newstrn(py_Ref, const char*, int); /// Create a `bytes` object with `n` UNINITIALIZED bytes. -unsigned char* py_newbytes(py_Ref, int n); +PK_EXPORT unsigned char* py_newbytes(py_Ref, int n); /// Create a `None` object. -void py_newnone(py_Ref); +PK_EXPORT void py_newnone(py_Ref); /// Create a `NotImplemented` object. -void py_newnotimplemented(py_Ref out); +PK_EXPORT void py_newnotimplemented(py_Ref out); /// Create a `...` object. -void py_newellipsis(py_Ref out); +PK_EXPORT void py_newellipsis(py_Ref out); /// Create a `nil` object. `nil` is an invalid representation of an object. /// Don't use it unless you know what you are doing. -void py_newnil(py_Ref); +PK_EXPORT void py_newnil(py_Ref); /// Create a `tuple` with `n` UNINITIALIZED elements. /// You should initialize all elements before using it. -void py_newtuple(py_Ref, int n); +PK_EXPORT void py_newtuple(py_Ref, int n); /// Create an empty `list`. -void py_newlist(py_Ref); +PK_EXPORT void py_newlist(py_Ref); /// Create a `list` with `n` UNINITIALIZED elements. /// You should initialize all elements before using it. -void py_newlistn(py_Ref, int n); +PK_EXPORT void py_newlistn(py_Ref, int n); /// Create an empty `dict`. -void py_newdict(py_Ref); +PK_EXPORT void py_newdict(py_Ref); /// Create an UNINITIALIZED `slice` object. /// You should use `py_setslot()` to set `start`, `stop`, and `step`. -void py_newslice(py_Ref); +PK_EXPORT void py_newslice(py_Ref); /// Create a `nativefunc` object. -void py_newnativefunc(py_Ref out, py_CFunction); +PK_EXPORT void py_newnativefunc(py_Ref out, py_CFunction); /// Create a `function` object. -py_Name +PK_EXPORT py_Name py_newfunction(py_Ref out, const char* sig, py_CFunction f, const char* docstring, int slots); /// Create a `boundmethod` object. -void py_newboundmethod(py_Ref out, py_Ref self, py_Ref func); +PK_EXPORT void py_newboundmethod(py_Ref out, py_Ref self, py_Ref func); /************* Name Convertions *************/ /// Convert a null-terminated string to a name. -py_Name py_name(const char*); +PK_EXPORT py_Name py_name(const char*); /// Convert a name to a null-terminated string. -const char* py_name2str(py_Name); +PK_EXPORT const char* py_name2str(py_Name); /// Convert a name to a `c11_sv`. -py_Name py_namev(c11_sv name); +PK_EXPORT py_Name py_namev(c11_sv name); /// Convert a `c11_sv` to a name. -c11_sv py_name2sv(py_Name); +PK_EXPORT c11_sv py_name2sv(py_Name); #define py_ismagicname(name) (name <= __missing__) @@ -178,7 +178,10 @@ c11_sv py_name2sv(py_Name); /// @param base base type. /// @param module module where the type is defined. Use `NULL` for built-in types. /// @param dtor destructor function. Use `NULL` if not needed. -py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, py_Dtor dtor); +PK_EXPORT py_Type py_newtype(const char* name, + py_Type base, + const py_GlobalRef module, + py_Dtor dtor); /// Create a new object. /// @param out output reference. @@ -186,32 +189,32 @@ py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, py /// @param slots number of slots. Use `-1` to create a `__dict__`. /// @param udsize size of your userdata. /// @return pointer to the userdata. -void* py_newobject(py_Ref out, py_Type type, int slots, int udsize); +PK_EXPORT void* py_newobject(py_Ref out, py_Type type, int slots, int udsize); /************* Type Cast *************/ /// Convert an `int` object in python to `int64_t`. -py_i64 py_toint(py_Ref); +PK_EXPORT py_i64 py_toint(py_Ref); /// Convert a `float` object in python to `double`. -py_f64 py_tofloat(py_Ref); +PK_EXPORT py_f64 py_tofloat(py_Ref); /// Cast a `int` or `float` object in python to `double`. /// If successful, return true and set the value to `out`. /// Otherwise, return false and raise `TypeError`. -bool py_castfloat(py_Ref, py_f64* out) PY_RAISE; +PK_EXPORT bool py_castfloat(py_Ref, py_f64* out) PY_RAISE; /// Convert a `bool` object in python to `bool`. -bool py_tobool(py_Ref); +PK_EXPORT bool py_tobool(py_Ref); /// Convert a `type` object in python to `py_Type`. -py_Type py_totype(py_Ref); +PK_EXPORT py_Type py_totype(py_Ref); /// Convert a `str` object in python to null-terminated string. -const char* py_tostr(py_Ref); +PK_EXPORT const char* py_tostr(py_Ref); /// Convert a `str` object in python to char array. -const char* py_tostrn(py_Ref, int* size); +PK_EXPORT const char* py_tostrn(py_Ref, int* size); /// Convert a `str` object in python to `c11_sv`. -c11_sv py_tosv(py_Ref); +PK_EXPORT c11_sv py_tosv(py_Ref); /// Convert a `bytes` object in python to char array. -unsigned char* py_tobytes(py_Ref, int* size); +PK_EXPORT unsigned char* py_tobytes(py_Ref, int* size); /// Convert a user-defined object to its userdata. -void* py_touserdata(py_Ref); +PK_EXPORT void* py_touserdata(py_Ref); #define py_isint(self) py_istype(self, tp_int) #define py_isfloat(self) py_istype(self, tp_float) @@ -225,37 +228,37 @@ void* py_touserdata(py_Ref); #define py_isnone(self) py_istype(self, tp_NoneType) /// Get the type of the object. -py_Type py_typeof(py_Ref self); +PK_EXPORT py_Type py_typeof(py_Ref self); /// Get type by module and name. e.g. `py_gettype("time", py_name("struct_time"))`. /// Return `0` if not found. -py_Type py_gettype(const char* module, py_Name name); +PK_EXPORT py_Type py_gettype(const char* module, py_Name name); /// Check if the object is exactly the given type. -bool py_istype(py_Ref, py_Type); +PK_EXPORT bool py_istype(py_Ref, py_Type); /// Check if the object is an instance of the given type. -bool py_isinstance(py_Ref obj, py_Type type); +PK_EXPORT bool py_isinstance(py_Ref obj, py_Type type); /// Check if the derived type is a subclass of the base type. -bool py_issubclass(py_Type derived, py_Type base); +PK_EXPORT bool py_issubclass(py_Type derived, py_Type base); /// Search the magic method from the given type to the base type. /// Return `NULL` if not found. -py_ItemRef py_tpfindmagic(py_Type, py_Name name); +PK_EXPORT py_ItemRef py_tpfindmagic(py_Type, py_Name name); /// Search the name from the given type to the base type. /// Return `NULL` if not found. -py_ItemRef py_tpfindname(py_Type, py_Name name); +PK_EXPORT py_ItemRef py_tpfindname(py_Type, py_Name name); /// Get the magic method from the given type only. /// The returned reference is always valid. However, its value may be `nil`. -py_ItemRef py_tpgetmagic(py_Type type, py_Name name); +PK_EXPORT py_ItemRef py_tpgetmagic(py_Type type, py_Name name); /// Get the type object of the given type. -py_ItemRef py_tpobject(py_Type type); +PK_EXPORT py_ItemRef py_tpobject(py_Type type); /// Get the type name. -const char* py_tpname(py_Type type); +PK_EXPORT const char* py_tpname(py_Type type); /// Call a type to create a new instance. -bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN; +PK_EXPORT bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN; /// Check if the object is an instance of the given type. /// Raise `TypeError` if the check fails. -bool py_checktype(py_Ref self, py_Type type) PY_RAISE; +PK_EXPORT bool py_checktype(py_Ref self, py_Type type) PY_RAISE; #define py_checkint(self) py_checktype(self, tp_int) #define py_checkfloat(self) py_checktype(self, tp_float) @@ -266,47 +269,47 @@ bool py_checktype(py_Ref self, py_Type type) PY_RAISE; /// Get the i-th register. /// All registers are located in a contiguous memory. -py_GlobalRef py_getreg(int i); +PK_EXPORT py_GlobalRef py_getreg(int i); /// Set the i-th register. -void py_setreg(int i, py_Ref val); +PK_EXPORT void py_setreg(int i, py_Ref val); /// Get variable in the `__main__` module. -py_ItemRef py_getglobal(py_Name name); +PK_EXPORT py_ItemRef py_getglobal(py_Name name); /// Set variable in the `__main__` module. -void py_setglobal(py_Name name, py_Ref val); +PK_EXPORT void py_setglobal(py_Name name, py_Ref val); /// Get variable in the `builtins` module. -py_ItemRef py_getbuiltin(py_Name name); +PK_EXPORT py_ItemRef py_getbuiltin(py_Name name); /// Equivalent to `*dst = *src`. -void py_assign(py_Ref dst, py_Ref src); +PK_EXPORT void py_assign(py_Ref dst, py_Ref src); /// Get the last return value. -py_GlobalRef py_retval(); +PK_EXPORT py_GlobalRef py_retval(); /// Get an item from the object's `__dict__`. /// Return `NULL` if not found. -py_ItemRef py_getdict(py_Ref self, py_Name name); +PK_EXPORT py_ItemRef py_getdict(py_Ref self, py_Name name); /// Set an item to the object's `__dict__`. -void py_setdict(py_Ref self, py_Name name, py_Ref val); +PK_EXPORT void py_setdict(py_Ref self, py_Name name, py_Ref val); /// Delete an item from the object's `__dict__`. /// Return `true` if the deletion is successful. -bool py_deldict(py_Ref self, py_Name name); +PK_EXPORT bool py_deldict(py_Ref self, py_Name name); /// Prepare an insertion to the object's `__dict__`. -py_ItemRef py_emplacedict(py_Ref self, py_Name name); +PK_EXPORT py_ItemRef py_emplacedict(py_Ref self, py_Name name); /// Get the i-th slot of the object. /// The object must have slots and `i` must be in valid range. -py_ObjectRef py_getslot(py_Ref self, int i); +PK_EXPORT py_ObjectRef py_getslot(py_Ref self, int i); /// Set the i-th slot of the object. -void py_setslot(py_Ref self, int i, py_Ref val); +PK_EXPORT void py_setslot(py_Ref self, int i, py_Ref val); /************* Inspection *************/ /// Get the current `function` object from the stack. /// Return `NULL` if not available. -py_StackRef py_inspect_currentfunction(); +PK_EXPORT py_StackRef py_inspect_currentfunction(); /// Get the current `module` object where the code is executed. /// Return `NULL` if not available. -py_GlobalRef py_inspect_currentmodule(); +PK_EXPORT py_GlobalRef py_inspect_currentmodule(); /************* Bindings *************/ @@ -314,23 +317,24 @@ py_GlobalRef py_inspect_currentmodule(); /// @param obj the target object. /// @param sig signature of the function. e.g. `add(x, y)`. /// @param f function to bind. -void py_bind(py_Ref obj, const char* sig, py_CFunction f); +PK_EXPORT void py_bind(py_Ref obj, const char* sig, py_CFunction f); /// Bind a method to type via "argc-based" style. /// @param type the target type. /// @param name name of the method. /// @param f function to bind. -void py_bindmethod(py_Type type, const char* name, py_CFunction f); +PK_EXPORT void py_bindmethod(py_Type type, const char* name, py_CFunction f); /// Bind a function to the object via "argc-based" style. /// @param obj the target object. /// @param name name of the function. /// @param f function to bind. -void py_bindfunc(py_Ref obj, const char* name, py_CFunction f); +PK_EXPORT void py_bindfunc(py_Ref obj, const char* name, py_CFunction f); /// Bind a property to type. /// @param type the target type. /// @param name name of the property. /// @param getter getter function. /// @param setter setter function. Use `NULL` if not needed. -void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFunction setter); +PK_EXPORT void + py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFunction setter); #define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpgetmagic((type), __magic__), (f)) @@ -346,22 +350,22 @@ void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFu /************* Python Equivalents *************/ /// Python equivalent to `getattr(self, name)`. -bool py_getattr(py_Ref self, py_Name name) PY_RAISE PY_RETURN; +PK_EXPORT bool py_getattr(py_Ref self, py_Name name) PY_RAISE PY_RETURN; /// Python equivalent to `setattr(self, name, val)`. -bool py_setattr(py_Ref self, py_Name name, py_Ref val) PY_RAISE; +PK_EXPORT bool py_setattr(py_Ref self, py_Name name, py_Ref val) PY_RAISE; /// Python equivalent to `delattr(self, name)`. -bool py_delattr(py_Ref self, py_Name name) PY_RAISE; +PK_EXPORT bool py_delattr(py_Ref self, py_Name name) PY_RAISE; /// Python equivalent to `self[key]`. -bool py_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; +PK_EXPORT bool py_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; /// Python equivalent to `self[key] = val`. -bool py_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; +PK_EXPORT bool py_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; /// Python equivalent to `del self[key]`. -bool py_delitem(py_Ref self, py_Ref key) PY_RAISE; +PK_EXPORT bool py_delitem(py_Ref self, py_Ref key) PY_RAISE; /// Perform a binary operation. /// The result will be set to `py_retval()`. /// The stack remains unchanged after the operation. -bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) PY_RAISE PY_RETURN; +PK_EXPORT bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) PY_RAISE PY_RETURN; #define py_binaryadd(lhs, rhs) py_binaryop(lhs, rhs, __add__, __radd__) #define py_binarysub(lhs, rhs) py_binaryop(lhs, rhs, __sub__, __rsub__) @@ -382,68 +386,68 @@ bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) PY_RAISE PY_RE /// Get the i-th object from the top of the stack. /// `i` should be negative, e.g. (-1) means TOS. -py_StackRef py_peek(int i); +PK_EXPORT py_StackRef py_peek(int i); /// Push the object to the stack. -void py_push(py_Ref src); +PK_EXPORT void py_push(py_Ref src); /// Push a `nil` object to the stack. -void py_pushnil(); +PK_EXPORT void py_pushnil(); /// Push a `None` object to the stack. -void py_pushnone(); +PK_EXPORT void py_pushnone(); /// Push a `py_Name` to the stack. This is used for keyword arguments. -void py_pushname(py_Name name); +PK_EXPORT void py_pushname(py_Name name); /// Pop an object from the stack. -void py_pop(); +PK_EXPORT void py_pop(); /// Shrink the stack by n. -void py_shrink(int n); +PK_EXPORT void py_shrink(int n); /// Get a temporary variable from the stack. -py_StackRef py_pushtmp(); +PK_EXPORT py_StackRef py_pushtmp(); /// Get the unbound method of the object. /// Assume the object is located at the top of the stack. /// If return true: `[self] -> [unbound, self]`. /// If return false: `[self] -> [self]` (no change). -bool py_pushmethod(py_Name name); +PK_EXPORT bool py_pushmethod(py_Name name); /// Call a callable object. /// Assume `argc + kwargc` arguments are already pushed to the stack. /// The result will be set to `py_retval()`. /// The stack size will be reduced by `argc + kwargc`. -bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE PY_RETURN; +PK_EXPORT bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE PY_RETURN; /// Evaluate an expression and push the result to the stack. /// This function is used for testing. -bool py_pusheval(const char* expr, py_GlobalRef module) PY_RAISE; +PK_EXPORT bool py_pusheval(const char* expr, py_GlobalRef module) PY_RAISE; /************* Modules *************/ /// Create a new module. -py_GlobalRef py_newmodule(const char* path); +PK_EXPORT py_GlobalRef py_newmodule(const char* path); /// Get a module by path. -py_GlobalRef py_getmodule(const char* path); +PK_EXPORT py_GlobalRef py_getmodule(const char* path); /// Import a module. /// The result will be set to `py_retval()`. /// -1: error, 0: not found, 1: success -int py_import(const char* path) PY_RAISE; +PK_EXPORT int py_import(const char* path) PY_RAISE; /************* Errors *************/ /// Raise an exception by type and message. Always return false. -bool py_exception(py_Type type, const char* fmt, ...) PY_RAISE; +PK_EXPORT bool py_exception(py_Type type, const char* fmt, ...) PY_RAISE; /// Raise an expection object. Always return false. -bool py_raise(py_Ref) PY_RAISE; +PK_EXPORT bool py_raise(py_Ref) PY_RAISE; /// Print the current exception. /// The exception will be set as handled. -void py_printexc(); +PK_EXPORT void py_printexc(); /// Format the current exception and return a null-terminated string. /// The result should be freed by the caller. /// The exception will be set as handled. -char* py_formatexc(); +PK_EXPORT char* py_formatexc(); /// Check if an exception is raised. -bool py_checkexc(bool ignore_handled); +PK_EXPORT bool py_checkexc(bool ignore_handled); /// Check if the exception is an instance of the given type. /// If match, the exception will be set as handled. -bool py_matchexc(py_Type type); +PK_EXPORT bool py_matchexc(py_Type type); /// Clear the current exception. /// @param p0 the unwinding point. Use `NULL` if not needed. -void py_clearexc(py_StackRef p0); +PK_EXPORT void py_clearexc(py_StackRef p0); #define NameError(n) py_exception(tp_NameError, "name '%n' is not defined", (n)) #define TypeError(...) py_exception(tp_TypeError, __VA_ARGS__) @@ -457,21 +461,21 @@ void py_clearexc(py_StackRef p0); #define UnboundLocalError(n) \ py_exception(tp_UnboundLocalError, "local variable '%n' referenced before assignment", (n)) -bool StopIteration(); -bool KeyError(py_Ref key) PY_RAISE; +PK_EXPORT bool StopIteration(); +PK_EXPORT bool KeyError(py_Ref key) PY_RAISE; /************* Operators *************/ /// Python equivalent to `bool(val)`. /// 1: true, 0: false, -1: error -int py_bool(py_Ref val) PY_RAISE PY_RETURN; +PK_EXPORT int py_bool(py_Ref val) PY_RAISE PY_RETURN; /// Compare two objects. /// 1: lhs == rhs, 0: lhs != rhs, -1: error -int py_equal(py_Ref lhs, py_Ref rhs) PY_RAISE; +PK_EXPORT int py_equal(py_Ref lhs, py_Ref rhs) PY_RAISE; /// Compare two objects. /// 1: lhs < rhs, 0: lhs >= rhs, -1: error -int py_less(py_Ref lhs, py_Ref rhs) PY_RAISE; +PK_EXPORT int py_less(py_Ref lhs, py_Ref rhs) PY_RAISE; #define py_eq(lhs, rhs) py_binaryop(lhs, rhs, __eq__, __eq__) #define py_ne(lhs, rhs) py_binaryop(lhs, rhs, __ne__, __ne__) @@ -481,74 +485,75 @@ int py_less(py_Ref lhs, py_Ref rhs) PY_RAISE; #define py_ge(lhs, rhs) py_binaryop(lhs, rhs, __ge__, __le__) /// Get the hash value of the object. -bool py_hash(py_Ref, py_i64* out) PY_RAISE; +PK_EXPORT bool py_hash(py_Ref, py_i64* out) PY_RAISE; /// Get the iterator of the object. -bool py_iter(py_Ref) PY_RAISE PY_RETURN; +PK_EXPORT bool py_iter(py_Ref) PY_RAISE PY_RETURN; /// Get the next element from the iterator. /// 1: success, 0: StopIteration, -1: error -int py_next(py_Ref) PY_RAISE PY_RETURN; +PK_EXPORT int py_next(py_Ref) PY_RAISE PY_RETURN; /// Python equivalent to `lhs is rhs`. -bool py_isidentical(py_Ref, py_Ref); +PK_EXPORT bool py_isidentical(py_Ref, py_Ref); /// Call a function. /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`. /// The result will be set to `py_retval()`. /// The stack remains unchanged after the operation. -bool py_call(py_Ref f, int argc, py_Ref argv) PY_RAISE PY_RETURN; +PK_EXPORT bool py_call(py_Ref f, int argc, py_Ref argv) PY_RAISE PY_RETURN; #if PK_DEBUG /// Call a `py_CFunction` in a safe way. /// This function does extra checks to help you debug `py_CFunction`. -bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) PY_RAISE PY_RETURN; +PK_EXPORT bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) PY_RAISE PY_RETURN; #else #define py_callcfunc(f, argc, argv) (f((argc), (argv))) #endif /// Python equivalent to `str(val)`. -bool py_str(py_Ref val) PY_RAISE PY_RETURN; +PK_EXPORT bool py_str(py_Ref val) PY_RAISE PY_RETURN; /// Python equivalent to `repr(val)`. -bool py_repr(py_Ref val) PY_RAISE PY_RETURN; +PK_EXPORT bool py_repr(py_Ref val) PY_RAISE PY_RETURN; /// Python equivalent to `len(val)`. -bool py_len(py_Ref val) PY_RAISE PY_RETURN; +PK_EXPORT bool py_len(py_Ref val) PY_RAISE PY_RETURN; /// Python equivalent to `json.dumps(val)`. -bool py_json_dumps(py_Ref val) PY_RAISE PY_RETURN; +PK_EXPORT bool py_json_dumps(py_Ref val) PY_RAISE PY_RETURN; /// Python equivalent to `json.loads(val)`. -bool py_json_loads(const char* source) PY_RAISE PY_RETURN; +PK_EXPORT bool py_json_loads(const char* source) PY_RAISE PY_RETURN; /************* Unchecked Functions *************/ -py_ObjectRef py_tuple_data(py_Ref self); -py_ObjectRef py_tuple_getitem(py_Ref self, int i); -void py_tuple_setitem(py_Ref self, int i, py_Ref val); -int py_tuple_len(py_Ref self); +PK_EXPORT py_ObjectRef py_tuple_data(py_Ref self); +PK_EXPORT py_ObjectRef py_tuple_getitem(py_Ref self, int i); +PK_EXPORT void py_tuple_setitem(py_Ref self, int i, py_Ref val); +PK_EXPORT int py_tuple_len(py_Ref self); -py_ItemRef py_list_data(py_Ref self); -py_ItemRef py_list_getitem(py_Ref self, int i); -void py_list_setitem(py_Ref self, int i, py_Ref val); -void py_list_delitem(py_Ref self, int i); -int py_list_len(py_Ref self); -void py_list_swap(py_Ref self, int i, int j); -void py_list_append(py_Ref self, py_Ref val); -py_ItemRef py_list_emplace(py_Ref self); -void py_list_clear(py_Ref self); -void py_list_insert(py_Ref self, int i, py_Ref val); +PK_EXPORT py_ItemRef py_list_data(py_Ref self); +PK_EXPORT py_ItemRef py_list_getitem(py_Ref self, int i); +PK_EXPORT void py_list_setitem(py_Ref self, int i, py_Ref val); +PK_EXPORT void py_list_delitem(py_Ref self, int i); +PK_EXPORT int py_list_len(py_Ref self); +PK_EXPORT void py_list_swap(py_Ref self, int i, int j); +PK_EXPORT void py_list_append(py_Ref self, py_Ref val); +PK_EXPORT py_ItemRef py_list_emplace(py_Ref self); +PK_EXPORT void py_list_clear(py_Ref self); +PK_EXPORT void py_list_insert(py_Ref self, int i, py_Ref val); /// -1: error, 0: not found, 1: found -int py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; +PK_EXPORT int py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; /// true: success, false: error -bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; +PK_EXPORT bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; /// -1: error, 0: not found, 1: found (and deleted) -int py_dict_delitem(py_Ref self, py_Ref key) PY_RAISE; +PK_EXPORT int py_dict_delitem(py_Ref self, py_Ref key) PY_RAISE; /// -1: error, 0: not found, 1: found -int py_dict_contains(py_Ref self, py_Ref key) PY_RAISE; +PK_EXPORT int py_dict_contains(py_Ref self, py_Ref key) PY_RAISE; /// true: success, false: error -bool py_dict_apply(py_Ref self, bool (*f)(py_Ref key, py_Ref val, void* ctx), void* ctx) PY_RAISE; +PK_EXPORT bool + py_dict_apply(py_Ref self, bool (*f)(py_Ref key, py_Ref val, void* ctx), void* ctx) PY_RAISE; /// noexcept -int py_dict_len(py_Ref self); +PK_EXPORT int py_dict_len(py_Ref self); /************* Others *************/ /// An utility function to read a line from stdin for REPL. -int py_replinput(char* buf, int max_size); +PK_EXPORT int py_replinput(char* buf, int max_size); /// Python favored string formatting. /// %d: int