mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-31 08:50:17 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "26a12bb640e6cfd8aa503d46f67e88b158f1bb17" and "145b36b6778c4d378581edb8333f22c86299bb2d" have entirely different histories.
		
	
	
		
			26a12bb640
			...
			145b36b677
		
	
		
							
								
								
									
										21
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								build.sh
									
									
									
									
									
								
							| @ -7,7 +7,10 @@ if ! type -P clang >/dev/null 2>&1; then | |||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
|  | echo "It takes a moment to finish building." | ||||||
|  | echo "" | ||||||
| echo "> Running prebuild.py... " | echo "> Running prebuild.py... " | ||||||
|  | 
 | ||||||
| python prebuild.py | python prebuild.py | ||||||
| 
 | 
 | ||||||
| if [ $? -ne 0 ]; then | if [ $? -ne 0 ]; then | ||||||
| @ -19,7 +22,23 @@ SRC=$(find src/ -name "*.c") | |||||||
| 
 | 
 | ||||||
| echo "> Compiling and linking source files... " | echo "> Compiling and linking source files... " | ||||||
| 
 | 
 | ||||||
| clang -std=c11 -O2 -Wfatal-errors -Iinclude -DNDEBUG -o main src2/main.c $SRC -lm | FLAGS="-std=c11 -O1 -Wfatal-errors -Iinclude -DNDEBUG" | ||||||
|  | 
 | ||||||
|  | if [[ "$OSTYPE" == "darwin"* ]]; then | ||||||
|  |     LIB_EXTENSION=".dylib" | ||||||
|  |     FLAGS="$FLAGS -undefined dynamic_lookup" | ||||||
|  |     LINK_FLAGS="" | ||||||
|  | else | ||||||
|  |     LIB_EXTENSION=".so" | ||||||
|  |     LINK_FLAGS="-Wl,-rpath=." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | clang $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared -lm | ||||||
|  | 
 | ||||||
|  | # compile main.cpp and link to libpocketpy.so | ||||||
|  | echo "> Compiling main.c and linking to libpocketpy$LIB_EXTENSION..." | ||||||
|  | 
 | ||||||
|  | clang $FLAGS -o main -O1 src2/main.c -L. -lpocketpy $LINK_FLAGS | ||||||
| 
 | 
 | ||||||
| if [ $? -eq 0 ]; then | if [ $? -eq 0 ]; then | ||||||
|     echo "Build completed. Type \"./main\" to enter REPL." |     echo "Build completed. Type \"./main\" to enter REPL." | ||||||
|  | |||||||
| @ -8,5 +8,3 @@ void pk__add_module_dis(); | |||||||
| void pk__add_module_random(); | void pk__add_module_random(); | ||||||
| void pk__add_module_json(); | void pk__add_module_json(); | ||||||
| void pk__add_module_gc(); | void pk__add_module_gc(); | ||||||
| void pk__add_module_time(); |  | ||||||
| void pk__add_module_easing(); |  | ||||||
|  | |||||||
| @ -31,4 +31,3 @@ typedef struct py_TValue { | |||||||
| // 16 bytes to make py_arg() macro work
 | // 16 bytes to make py_arg() macro work
 | ||||||
| static_assert(sizeof(py_CFunction) <= 8, "sizeof(py_CFunction) > 8"); | static_assert(sizeof(py_CFunction) <= 8, "sizeof(py_CFunction) > 8"); | ||||||
| static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16"); | static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16"); | ||||||
| static_assert(offsetof(py_TValue, extra) == 4, "offsetof(py_TValue, extra) != 4"); |  | ||||||
| @ -23,7 +23,6 @@ typedef double py_f64; | |||||||
| typedef void (*py_Dtor)(void*); | typedef void (*py_Dtor)(void*); | ||||||
| 
 | 
 | ||||||
| #define PY_RAISE  // mark a function that can raise an exception
 | #define PY_RAISE  // mark a function that can raise an exception
 | ||||||
| #define PY_RETURN  // mark a function that can modify `py_retval()` on success
 |  | ||||||
| 
 | 
 | ||||||
| typedef struct c11_sv { | typedef struct c11_sv { | ||||||
|     const char* data; |     const char* data; | ||||||
| @ -45,7 +44,7 @@ typedef py_TValue* py_ItemRef; | |||||||
| /// @param argc number of arguments.
 | /// @param argc number of arguments.
 | ||||||
| /// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
 | /// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
 | ||||||
| /// @return true if the function is successful.
 | /// @return true if the function is successful.
 | ||||||
| typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE PY_RETURN; | typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE }; | enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE }; | ||||||
| 
 | 
 | ||||||
| @ -75,16 +74,14 @@ void py_switchvm(int index); | |||||||
| bool py_exec(const char* source, | bool py_exec(const char* source, | ||||||
|              const char* filename, |              const char* filename, | ||||||
|              enum py_CompileMode mode, |              enum py_CompileMode mode, | ||||||
|              py_Ref module) PY_RAISE PY_RETURN; |              py_Ref module) PY_RAISE; | ||||||
| 
 |  | ||||||
| #define py_eval(source, module) py_exec((source), "<string>", EVAL_MODE, (module)) |  | ||||||
| 
 | 
 | ||||||
| /// Compile a source string into a code object.
 | /// Compile a source string into a code object.
 | ||||||
| /// Use python's `exec()` or `eval()` to execute it.
 | /// Use python's `exec()` or `eval()` to execute it.
 | ||||||
| bool py_compile(const char* source, | bool py_compile(const char* source, | ||||||
|                 const char* filename, |                 const char* filename, | ||||||
|                 enum py_CompileMode mode, |                 enum py_CompileMode mode, | ||||||
|                 bool is_dynamic) PY_RAISE PY_RETURN; |                 bool is_dynamic) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| /// Python equivalent to `globals()`.
 | /// Python equivalent to `globals()`.
 | ||||||
| void py_newglobals(py_Ref); | void py_newglobals(py_Ref); | ||||||
| @ -173,7 +170,7 @@ py_i64 py_toint(py_Ref); | |||||||
| /// Convert a `float` object in python to `double`.
 | /// Convert a `float` object in python to `double`.
 | ||||||
| py_f64 py_tofloat(py_Ref); | py_f64 py_tofloat(py_Ref); | ||||||
| /// Cast a `int` or `float` object in python to `double`.
 | /// Cast a `int` or `float` object in python to `double`.
 | ||||||
| /// If successful, return true and set the value to `out`.
 | /// If successful, returns true and set the value to `out`.
 | ||||||
| /// Otherwise, return false and raise `TypeError`.
 | /// Otherwise, return false and raise `TypeError`.
 | ||||||
| bool py_castfloat(py_Ref, py_f64* out) PY_RAISE; | bool py_castfloat(py_Ref, py_f64* out) PY_RAISE; | ||||||
| /// Convert a `bool` object in python to `bool`.
 | /// Convert a `bool` object in python to `bool`.
 | ||||||
| @ -204,9 +201,6 @@ void* py_touserdata(py_Ref); | |||||||
| 
 | 
 | ||||||
| /// Get the type of the object.
 | /// Get the type of the object.
 | ||||||
| py_Type py_typeof(py_Ref self); | 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); |  | ||||||
| /// Check if the object is exactly the given type.
 | /// Check if the object is exactly the given type.
 | ||||||
| bool py_istype(py_Ref, py_Type); | bool py_istype(py_Ref, py_Type); | ||||||
| /// Check if the object is an instance of the given type.
 | /// Check if the object is an instance of the given type.
 | ||||||
| @ -229,7 +223,7 @@ py_ItemRef py_tpobject(py_Type type); | |||||||
| /// Get the type name.
 | /// Get the type name.
 | ||||||
| const char* py_tpname(py_Type type); | const char* py_tpname(py_Type type); | ||||||
| /// Call a type to create a new instance.
 | /// Call a type to create a new instance.
 | ||||||
| bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN; | bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| /// Check if the object is an instance of the given type.
 | /// Check if the object is an instance of the given type.
 | ||||||
| /// Raise `TypeError` if the check fails.
 | /// Raise `TypeError` if the check fails.
 | ||||||
| @ -282,9 +276,6 @@ void py_setslot(py_Ref self, int i, py_Ref val); | |||||||
| /// Get the current `function` object from the stack.
 | /// Get the current `function` object from the stack.
 | ||||||
| /// Return `NULL` if not available.
 | /// Return `NULL` if not available.
 | ||||||
| py_StackRef py_inspect_currentfunction(); | 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(); |  | ||||||
| 
 | 
 | ||||||
| /************* Bindings *************/ | /************* Bindings *************/ | ||||||
| 
 | 
 | ||||||
| @ -324,13 +315,13 @@ void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFu | |||||||
| /************* Python Equivalents *************/ | /************* Python Equivalents *************/ | ||||||
| 
 | 
 | ||||||
| /// Python equivalent to `getattr(self, name)`.
 | /// Python equivalent to `getattr(self, name)`.
 | ||||||
| bool py_getattr(py_Ref self, py_Name name) PY_RAISE PY_RETURN; | bool py_getattr(py_Ref self, py_Name name) PY_RAISE; | ||||||
| /// Python equivalent to `setattr(self, name, val)`.
 | /// Python equivalent to `setattr(self, name, val)`.
 | ||||||
| bool py_setattr(py_Ref self, py_Name name, py_Ref val) PY_RAISE; | bool py_setattr(py_Ref self, py_Name name, py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `delattr(self, name)`.
 | /// Python equivalent to `delattr(self, name)`.
 | ||||||
| bool py_delattr(py_Ref self, py_Name name) PY_RAISE; | bool py_delattr(py_Ref self, py_Name name) PY_RAISE; | ||||||
| /// Python equivalent to `self[key]`.
 | /// Python equivalent to `self[key]`.
 | ||||||
| bool py_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; | bool py_getitem(py_Ref self, py_Ref key) PY_RAISE; | ||||||
| /// Python equivalent to `self[key] = val`.
 | /// Python equivalent to `self[key] = val`.
 | ||||||
| bool py_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; | bool py_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `del self[key]`.
 | /// Python equivalent to `del self[key]`.
 | ||||||
| @ -339,7 +330,7 @@ bool py_delitem(py_Ref self, py_Ref key) PY_RAISE; | |||||||
| /// Perform a binary operation.
 | /// Perform a binary operation.
 | ||||||
| /// The result will be set to `py_retval()`.
 | /// The result will be set to `py_retval()`.
 | ||||||
| /// The stack remains unchanged after the operation.
 | /// 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; | bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| #define py_binaryadd(lhs, rhs) py_binaryop(lhs, rhs, __add__, __radd__) | #define py_binaryadd(lhs, rhs) py_binaryop(lhs, rhs, __add__, __radd__) | ||||||
| #define py_binarysub(lhs, rhs) py_binaryop(lhs, rhs, __sub__, __rsub__) | #define py_binarysub(lhs, rhs) py_binaryop(lhs, rhs, __sub__, __rsub__) | ||||||
| @ -367,8 +358,6 @@ void py_push(py_Ref src); | |||||||
| void py_pushnil(); | void py_pushnil(); | ||||||
| /// Push a `None` object to the stack.
 | /// Push a `None` object to the stack.
 | ||||||
| void py_pushnone(); | void py_pushnone(); | ||||||
| /// Push a `py_Name` to the stack. This is used for keyword arguments.
 |  | ||||||
| void py_pushname(py_Name name); |  | ||||||
| /// Pop an object from the stack.
 | /// Pop an object from the stack.
 | ||||||
| void py_pop(); | void py_pop(); | ||||||
| /// Shrink the stack by n.
 | /// Shrink the stack by n.
 | ||||||
| @ -384,10 +373,7 @@ bool py_pushmethod(py_Name name); | |||||||
| /// Assume `argc + kwargc` arguments are already pushed to the stack.
 | /// Assume `argc + kwargc` arguments are already pushed to the stack.
 | ||||||
| /// The result will be set to `py_retval()`.
 | /// The result will be set to `py_retval()`.
 | ||||||
| /// The stack size will be reduced by `argc + kwargc`.
 | /// The stack size will be reduced by `argc + kwargc`.
 | ||||||
| bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE PY_RETURN; | bool py_vectorcall(uint16_t argc, uint16_t kwargc) PY_RAISE; | ||||||
| /// 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; |  | ||||||
| 
 | 
 | ||||||
| /************* Modules *************/ | /************* Modules *************/ | ||||||
| 
 | 
 | ||||||
| @ -442,7 +428,7 @@ bool KeyError(py_Ref key) PY_RAISE; | |||||||
| 
 | 
 | ||||||
| /// Python equivalent to `bool(val)`.
 | /// Python equivalent to `bool(val)`.
 | ||||||
| /// 1: true, 0: false, -1: error
 | /// 1: true, 0: false, -1: error
 | ||||||
| int py_bool(py_Ref val) PY_RAISE PY_RETURN; | int py_bool(py_Ref val) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| /// Compare two objects.
 | /// Compare two objects.
 | ||||||
| /// 1: lhs == rhs, 0: lhs != rhs, -1: error
 | /// 1: lhs == rhs, 0: lhs != rhs, -1: error
 | ||||||
| @ -461,36 +447,34 @@ int py_less(py_Ref lhs, py_Ref rhs) PY_RAISE; | |||||||
| /// Get the hash value of the object.
 | /// Get the hash value of the object.
 | ||||||
| bool py_hash(py_Ref, py_i64* out) PY_RAISE; | bool py_hash(py_Ref, py_i64* out) PY_RAISE; | ||||||
| /// Get the iterator of the object.
 | /// Get the iterator of the object.
 | ||||||
| bool py_iter(py_Ref) PY_RAISE PY_RETURN; | bool py_iter(py_Ref) PY_RAISE; | ||||||
| /// Get the next element from the iterator.
 | /// Get the next element from the iterator.
 | ||||||
| /// 1: success, 0: StopIteration, -1: error
 | /// 1: success, 0: StopIteration, -1: error
 | ||||||
| int py_next(py_Ref) PY_RAISE PY_RETURN; | int py_next(py_Ref) PY_RAISE; | ||||||
| /// Python equivalent to `lhs is rhs`.
 | /// Python equivalent to `lhs is rhs`.
 | ||||||
| bool py_isidentical(py_Ref, py_Ref); | bool py_isidentical(py_Ref, py_Ref); | ||||||
| /// Call a function.
 | /// Call a function.
 | ||||||
| /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`.
 | /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`.
 | ||||||
| /// The result will be set to `py_retval()`.
 | /// The result will be set to `py_retval()`.
 | ||||||
| /// The stack remains unchanged after the operation.
 | /// The stack remains unchanged after the operation.
 | ||||||
| bool py_call(py_Ref f, int argc, py_Ref argv) PY_RAISE PY_RETURN; | bool py_call(py_Ref f, int argc, py_Ref argv) PY_RAISE; | ||||||
| 
 | 
 | ||||||
| #if PK_DEBUG | #if PK_DEBUG | ||||||
| /// Call a py_CFunction in a safe way.
 | /// Call a py_CFunction in a safe way.
 | ||||||
| /// This function does extra checks to help you debug `py_CFunction`.
 | /// 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; | bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) PY_RAISE; | ||||||
| #else | #else | ||||||
| #define py_callcfunc(f, argc, argv) (f((argc), (argv))) | #define py_callcfunc(f, argc, argv) (f((argc), (argv))) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /// Python equivalent to `str(val)`.
 | /// Python equivalent to `str(val)`.
 | ||||||
| bool py_str(py_Ref val) PY_RAISE PY_RETURN; | bool py_str(py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `repr(val)`.
 | /// Python equivalent to `repr(val)`.
 | ||||||
| bool py_repr(py_Ref val) PY_RAISE PY_RETURN; | bool py_repr(py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `len(val)`.
 | /// Python equivalent to `len(val)`.
 | ||||||
| bool py_len(py_Ref val) PY_RAISE PY_RETURN; | bool py_len(py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `json.dumps(val)`.
 | /// Python equivalent to `json.dumps(val)`.
 | ||||||
| bool py_json_dumps(py_Ref val) PY_RAISE PY_RETURN; | bool py_json(py_Ref val) PY_RAISE; | ||||||
| /// Python equivalent to `json.loads(val)`.
 |  | ||||||
| bool py_json_loads(const char* source) PY_RAISE PY_RETURN; |  | ||||||
| 
 | 
 | ||||||
| /************* Unchecked Functions *************/ | /************* Unchecked Functions *************/ | ||||||
| 
 | 
 | ||||||
| @ -510,7 +494,7 @@ void py_list_clear(py_Ref self); | |||||||
| void py_list_insert(py_Ref self, int i, py_Ref val); | void py_list_insert(py_Ref self, int i, py_Ref val); | ||||||
| 
 | 
 | ||||||
| /// -1: error, 0: not found, 1: found
 | /// -1: error, 0: not found, 1: found
 | ||||||
| int py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE PY_RETURN; | int py_dict_getitem(py_Ref self, py_Ref key) PY_RAISE; | ||||||
| /// true: success, false: error
 | /// true: success, false: error
 | ||||||
| bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; | bool py_dict_setitem(py_Ref self, py_Ref key, py_Ref val) PY_RAISE; | ||||||
| /// -1: error, 0: not found, 1: found (and deleted)
 | /// -1: error, 0: not found, 1: found (and deleted)
 | ||||||
| @ -527,7 +511,7 @@ int py_dict_len(py_Ref self); | |||||||
| /// An utility function to read a line from stdin for REPL.
 | /// An utility function to read a line from stdin for REPL.
 | ||||||
| int py_replinput(char* buf, int max_size); | int py_replinput(char* buf, int max_size); | ||||||
| 
 | 
 | ||||||
| /// Python favored string formatting.
 | /// Python favored string formatting. (just put here, not for users)
 | ||||||
| /// %d: int
 | /// %d: int
 | ||||||
| /// %i: py_i64 (int64_t)
 | /// %i: py_i64 (int64_t)
 | ||||||
| /// %f: py_f64 (double)
 | /// %f: py_f64 (double)
 | ||||||
| @ -605,3 +589,14 @@ enum py_PredefinedTypes { | |||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | Some notes: | ||||||
|  | 
 | ||||||
|  | ## Macros | ||||||
|  | 1. Function macros are partial functions. They can be used as normal expressions. Use the same | ||||||
|  | naming convention as functions. | ||||||
|  | 2. Snippet macros are `do {...} while(0)` blocks. They cannot be used as expressions. Use | ||||||
|  | `UPPER_CASE` naming convention. | ||||||
|  | 3. Constant macros are used for global constants. Use `UPPER_CASE` or k-prefix naming convention. | ||||||
|  | */ | ||||||
							
								
								
									
										117
									
								
								include/typings/c.pyi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								include/typings/c.pyi
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | |||||||
|  | from typing import Generic, TypeVar | ||||||
|  | 
 | ||||||
|  | def malloc(size: int) -> 'void_p': ... | ||||||
|  | def free(ptr: 'void_p') -> None: ... | ||||||
|  | def memset(ptr: 'void_p', value: int, size: int) -> None: ... | ||||||
|  | def memcpy(dst: 'void_p', src: 'void_p', size: int) -> None: ... | ||||||
|  | 
 | ||||||
|  | T = TypeVar('T') | ||||||
|  | Tp = TypeVar('Tp', bound='void_p') | ||||||
|  | 
 | ||||||
|  | def p_cast(ptr: 'void_p', cls: type[T]) -> T: | ||||||
|  |     """Cast a pointer to a specific type.""" | ||||||
|  | def p_value(ptr: 'void_p') -> int: | ||||||
|  |     """Get the value of a pointer.""" | ||||||
|  | def pp_deref(ptr: Tp) -> Tp: | ||||||
|  |     """Dereference a double pointer.""" | ||||||
|  | 
 | ||||||
|  | class void_p: | ||||||
|  |     def __init__(self, addr: int): ... | ||||||
|  |     def __eq__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __ne__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __lt__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __le__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __gt__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __ge__(self, other: 'void_p') -> bool: ... | ||||||
|  |     def __hash__(self) -> int: ... | ||||||
|  |     def __repr__(self) -> str: ... | ||||||
|  | 
 | ||||||
|  | class Pointer(Generic[T], void_p): | ||||||
|  |     def read(self) -> T: ... | ||||||
|  |     def write(self, value: T) -> None: ... | ||||||
|  |     def __getitem__(self, index: int) -> T: ... | ||||||
|  |     def __setitem__(self, index: int, value: T) -> None: ... | ||||||
|  | 
 | ||||||
|  | class char_p(Pointer[int]): | ||||||
|  |     def read_string(self) -> str: ... | ||||||
|  |     def write_string(self, value: str) -> None: ... | ||||||
|  | 
 | ||||||
|  | class uchar_p(Pointer[int]): pass | ||||||
|  | class short_p(Pointer[int]): pass | ||||||
|  | class ushort_p(Pointer[int]): pass | ||||||
|  | class int_p(Pointer[int]): pass | ||||||
|  | class uint_p(Pointer[int]): pass | ||||||
|  | class long_p(Pointer[int]): pass | ||||||
|  | class ulong_p(Pointer[int]): pass | ||||||
|  | class longlong_p(Pointer[int]): pass | ||||||
|  | class ulonglong_p(Pointer[int]): pass | ||||||
|  | class float_p(Pointer[float]): pass | ||||||
|  | class double_p(Pointer[float]): pass | ||||||
|  | class bool_p(Pointer[bool]): pass | ||||||
|  | 
 | ||||||
|  | class struct: | ||||||
|  |     def __init__(self, size: int): ... | ||||||
|  |     def addr(self) -> 'void_p': ... | ||||||
|  |     def copy(self) -> 'struct': ... | ||||||
|  |     def sizeof(self) -> int: ... | ||||||
|  |     def __eq__(self, other: 'struct') -> bool: ... | ||||||
|  |     def __ne__(self, other: 'struct') -> bool: ... | ||||||
|  | 
 | ||||||
|  |     def hex(self) -> str: ... | ||||||
|  |     @staticmethod | ||||||
|  |     def fromhex(s: str) -> 'struct': ... | ||||||
|  | 
 | ||||||
|  |     def read_char(self, offset=0) -> int: ... | ||||||
|  |     def read_uchar(self, offset=0) -> int: ... | ||||||
|  |     def read_short(self, offset=0) -> int: ... | ||||||
|  |     def read_ushort(self, offset=0) -> int: ... | ||||||
|  |     def read_int(self, offset=0) -> int: ... | ||||||
|  |     def read_uint(self, offset=0) -> int: ... | ||||||
|  |     def read_long(self, offset=0) -> int: ... | ||||||
|  |     def read_ulong(self, offset=0) -> int: ... | ||||||
|  |     def read_longlong(self, offset=0) -> int: ... | ||||||
|  |     def read_ulonglong(self, offset=0) -> int: ... | ||||||
|  |     def read_float(self, offset=0) -> float: ... | ||||||
|  |     def read_double(self, offset=0) -> float: ... | ||||||
|  |     def read_bool(self, offset=0) -> bool: ... | ||||||
|  |     def read_void_p(self, offset=0) -> 'void_p': ... | ||||||
|  |     def write_char(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_uchar(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_short(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_ushort(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_int(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_uint(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_long(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_ulong(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_longlong(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_ulonglong(self, value: int, offset=0) -> None: ... | ||||||
|  |     def write_float(self, value: float, offset=0) -> None: ... | ||||||
|  |     def write_double(self, value: float, offset=0) -> None: ... | ||||||
|  |     def write_bool(self, value: bool, offset=0) -> None: ... | ||||||
|  |     def write_void_p(self, value: 'void_p', offset=0) -> None: ... | ||||||
|  | 
 | ||||||
|  | def char_(val: int) -> struct: ... | ||||||
|  | def uchar_(val: int) -> struct: ... | ||||||
|  | def short_(val: int) -> struct: ... | ||||||
|  | def ushort_(val: int) -> struct: ... | ||||||
|  | def int_(val: int) -> struct: ... | ||||||
|  | def uint_(val: int) -> struct: ... | ||||||
|  | def long_(val: int) -> struct: ... | ||||||
|  | def ulong_(val: int) -> struct: ... | ||||||
|  | def longlong_(val: int) -> struct: ... | ||||||
|  | def ulonglong_(val: int) -> struct: ... | ||||||
|  | def float_(val: float) -> struct: ... | ||||||
|  | def double_(val: float) -> struct: ... | ||||||
|  | def bool_(val: bool) -> struct: ... | ||||||
|  | 
 | ||||||
|  | class _StructLike(Generic[T]): | ||||||
|  |     def tostruct(self) -> struct: ... | ||||||
|  |     @classmethod | ||||||
|  |     def fromstruct(cls, s: struct) -> T: ... | ||||||
|  | 
 | ||||||
|  |     def addr(self) -> 'Pointer[T]': ... | ||||||
|  |     def copy(self) -> T: ... | ||||||
|  |     def sizeof(self) -> int: ... | ||||||
|  |     def __eq__(self, other: T) -> bool: ... | ||||||
|  |     def __ne__(self, other: T) -> bool: ... | ||||||
|  | 
 | ||||||
| @ -1,5 +1,4 @@ | |||||||
| from time import localtime | from time import localtime | ||||||
| import operator |  | ||||||
| 
 | 
 | ||||||
| class timedelta: | class timedelta: | ||||||
|     def __init__(self, days=0, seconds=0): |     def __init__(self, days=0, seconds=0): | ||||||
| @ -14,10 +13,25 @@ class timedelta: | |||||||
|             return NotImplemented |             return NotImplemented | ||||||
|         return (self.days, self.seconds) == (other.days, other.seconds) |         return (self.days, self.seconds) == (other.days, other.seconds) | ||||||
| 
 | 
 | ||||||
|     def __ne__(self, other: 'timedelta') -> bool: |     def __lt__(self, other: 'timedelta') -> bool: | ||||||
|         if type(other) is not timedelta: |         if type(other) is not timedelta: | ||||||
|             return NotImplemented |             return NotImplemented | ||||||
|         return (self.days, self.seconds) != (other.days, other.seconds) |         return (self.days, self.seconds) < (other.days, other.seconds) | ||||||
|  | 
 | ||||||
|  |     def __le__(self, other: 'timedelta') -> bool: | ||||||
|  |         if type(other) is not timedelta: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.days, self.seconds) <= (other.days, other.seconds) | ||||||
|  | 
 | ||||||
|  |     def __gt__(self, other: 'timedelta') -> bool: | ||||||
|  |         if type(other) is not timedelta: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.days, self.seconds) > (other.days, other.seconds) | ||||||
|  | 
 | ||||||
|  |     def __ge__(self, other: 'timedelta') -> bool: | ||||||
|  |         if type(other) is not timedelta: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.days, self.seconds) >= (other.days, other.seconds) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class date: | class date: | ||||||
| @ -31,32 +45,30 @@ class date: | |||||||
|         t = localtime() |         t = localtime() | ||||||
|         return date(t.tm_year, t.tm_mon, t.tm_mday) |         return date(t.tm_year, t.tm_mon, t.tm_mday) | ||||||
| 
 | 
 | ||||||
|     def __cmp(self, other, op): |  | ||||||
|         if not isinstance(other, date): |  | ||||||
|             return NotImplemented |  | ||||||
|         if self.year != other.year: |  | ||||||
|             return op(self.year, other.year) |  | ||||||
|         if self.month != other.month: |  | ||||||
|             return op(self.month, other.month) |  | ||||||
|         return op(self.day, other.day) |  | ||||||
| 
 |  | ||||||
|     def __eq__(self, other: 'date') -> bool: |     def __eq__(self, other: 'date') -> bool: | ||||||
|         return self.__cmp(other, operator.eq) |         if type(other) is not date: | ||||||
|      |             return NotImplemented | ||||||
|     def __ne__(self, other: 'date') -> bool: |         return (self.year, self.month, self.day) == (other.year, other.month, other.day) | ||||||
|         return self.__cmp(other, operator.ne) |  | ||||||
| 
 | 
 | ||||||
|     def __lt__(self, other: 'date') -> bool: |     def __lt__(self, other: 'date') -> bool: | ||||||
|         return self.__cmp(other, operator.lt) |         if type(other) is not date: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day) < (other.year, other.month, other.day) | ||||||
| 
 | 
 | ||||||
|     def __le__(self, other: 'date') -> bool: |     def __le__(self, other: 'date') -> bool: | ||||||
|         return self.__cmp(other, operator.le) |         if type(other) is not date: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day) <= (other.year, other.month, other.day) | ||||||
| 
 | 
 | ||||||
|     def __gt__(self, other: 'date') -> bool: |     def __gt__(self, other: 'date') -> bool: | ||||||
|         return self.__cmp(other, operator.gt) |         if type(other) is not date: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day) > (other.year, other.month, other.day) | ||||||
| 
 | 
 | ||||||
|     def __ge__(self, other: 'date') -> bool: |     def __ge__(self, other: 'date') -> bool: | ||||||
|         return self.__cmp(other, operator.ge) |         if type(other) is not date: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day) >= (other.year, other.month, other.day) | ||||||
| 
 | 
 | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return f"{self.year}-{self.month:02}-{self.day:02}" |         return f"{self.year}-{self.month:02}-{self.day:02}" | ||||||
| @ -96,37 +108,41 @@ class datetime(date): | |||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return f"datetime.datetime({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})" |         return f"datetime.datetime({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})" | ||||||
| 
 | 
 | ||||||
|     def __cmp(self, other, op): |  | ||||||
|         if not isinstance(other, datetime): |  | ||||||
|             return NotImplemented |  | ||||||
|         if self.year != other.year: |  | ||||||
|             return op(self.year, other.year) |  | ||||||
|         if self.month != other.month: |  | ||||||
|             return op(self.month, other.month) |  | ||||||
|         if self.day != other.day: |  | ||||||
|             return op(self.day, other.day) |  | ||||||
|         if self.hour != other.hour: |  | ||||||
|             return op(self.hour, other.hour) |  | ||||||
|         if self.minute != other.minute: |  | ||||||
|             return op(self.minute, other.minute) |  | ||||||
|         return op(self.second, other.second) |  | ||||||
| 
 |  | ||||||
|     def __eq__(self, other) -> bool: |     def __eq__(self, other) -> bool: | ||||||
|         return self.__cmp(other, operator.eq) |         if type(other) is not datetime: | ||||||
|      |             return NotImplemented | ||||||
|     def __ne__(self, other) -> bool: |         return (self.year, self.month, self.day, self.hour, self.minute, self.second) ==\ | ||||||
|         return self.__cmp(other, operator.ne) |             (other.year, other.month, other.day, | ||||||
|  |              other.hour, other.minute, other.second) | ||||||
| 
 | 
 | ||||||
|     def __lt__(self, other) -> bool: |     def __lt__(self, other) -> bool: | ||||||
|         return self.__cmp(other, operator.lt) |         if type(other) is not datetime: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day, self.hour, self.minute, self.second) <\ | ||||||
|  |             (other.year, other.month, other.day, | ||||||
|  |              other.hour, other.minute, other.second) | ||||||
| 
 | 
 | ||||||
|     def __le__(self, other) -> bool: |     def __le__(self, other) -> bool: | ||||||
|         return self.__cmp(other, operator.le) |         if type(other) is not datetime: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day, self.hour, self.minute, self.second) <=\ | ||||||
|  |             (other.year, other.month, other.day, | ||||||
|  |              other.hour, other.minute, other.second) | ||||||
| 
 | 
 | ||||||
|     def __gt__(self, other) -> bool: |     def __gt__(self, other) -> bool: | ||||||
|         return self.__cmp(other, operator.gt) |         if type(other) is not datetime: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day, self.hour, self.minute, self.second) >\ | ||||||
|  |             (other.year, other.month, other.day, | ||||||
|  |              other.hour, other.minute, other.second) | ||||||
| 
 | 
 | ||||||
|     def __ge__(self, other) -> bool: |     def __ge__(self, other) -> bool: | ||||||
|         return self.__cmp(other, operator.ge) |         if type(other) is not datetime: | ||||||
|  |             return NotImplemented | ||||||
|  |         return (self.year, self.month, self.day, self.hour, self.minute, self.second) >=\ | ||||||
|  |             (other.year, other.month, other.day, | ||||||
|  |              other.hour, other.minute, other.second) | ||||||
| 
 | 
 | ||||||
|  |     def timestamp(self) -> float: | ||||||
|  |         raise NotImplementedError | ||||||
| 
 | 
 | ||||||
|  | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -202,8 +202,6 @@ void VM__ctor(VM* self) { | |||||||
|     pk__add_module_random(); |     pk__add_module_random(); | ||||||
|     pk__add_module_json(); |     pk__add_module_json(); | ||||||
|     pk__add_module_gc(); |     pk__add_module_gc(); | ||||||
|     pk__add_module_time(); |  | ||||||
|     pk__add_module_easing(); |  | ||||||
| 
 | 
 | ||||||
|     // add python builtins
 |     // add python builtins
 | ||||||
|     do { |     do { | ||||||
| @ -331,9 +329,7 @@ py_Type pk_newtype(const char* name, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) { | py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) { | ||||||
|     py_Type type = pk_newtype(name, base, module, dtor, false, false); |     return pk_newtype(name, base, module, dtor, false, false); | ||||||
|     if(module) py_setdict(module, py_name(name), py_tpobject(type)); |  | ||||||
|     return type; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool | static bool | ||||||
|  | |||||||
| @ -1,251 +0,0 @@ | |||||||
| #include "pocketpy/pocketpy.h" |  | ||||||
| #include "pocketpy/interpreter/vm.h" |  | ||||||
| 
 |  | ||||||
| #include "math.h" |  | ||||||
| 
 |  | ||||||
| // https://easings.net/
 |  | ||||||
| 
 |  | ||||||
| const double kPi = 3.1415926545; |  | ||||||
| 
 |  | ||||||
| static double easeLinear(double x) { return x; } |  | ||||||
| 
 |  | ||||||
| static double easeInSine(double x) { return 1.0 - cos(x * kPi / 2); } |  | ||||||
| 
 |  | ||||||
| static double easeOutSine(double x) { return sin(x * kPi / 2); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutSine(double x) { return -(cos(kPi * x) - 1) / 2; } |  | ||||||
| 
 |  | ||||||
| static double easeInQuad(double x) { return x * x; } |  | ||||||
| 
 |  | ||||||
| static double easeOutQuad(double x) { return 1 - pow(1 - x, 2); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutQuad(double x) { |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return 2 * x * x; |  | ||||||
|     } else { |  | ||||||
|         return 1 - pow(-2 * x + 2, 2) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInCubic(double x) { return x * x * x; } |  | ||||||
| 
 |  | ||||||
| static double easeOutCubic(double x) { return 1 - pow(1 - x, 3); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutCubic(double x) { |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return 4 * x * x * x; |  | ||||||
|     } else { |  | ||||||
|         return 1 - pow(-2 * x + 2, 3) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInQuart(double x) { return pow(x, 4); } |  | ||||||
| 
 |  | ||||||
| static double easeOutQuart(double x) { return 1 - pow(1 - x, 4); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutQuart(double x) { |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return 8 * pow(x, 4); |  | ||||||
|     } else { |  | ||||||
|         return 1 - pow(-2 * x + 2, 4) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInQuint(double x) { return pow(x, 5); } |  | ||||||
| 
 |  | ||||||
| static double easeOutQuint(double x) { return 1 - pow(1 - x, 5); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutQuint(double x) { |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return 16 * pow(x, 5); |  | ||||||
|     } else { |  | ||||||
|         return 1 - pow(-2 * x + 2, 5) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInExpo(double x) { return x == 0 ? 0 : pow(2, 10 * x - 10); } |  | ||||||
| 
 |  | ||||||
| static double easeOutExpo(double x) { return x == 1 ? 1 : 1 - pow(2, -10 * x); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutExpo(double x) { |  | ||||||
|     if(x == 0) { |  | ||||||
|         return 0; |  | ||||||
|     } else if(x == 1) { |  | ||||||
|         return 1; |  | ||||||
|     } else if(x < 0.5) { |  | ||||||
|         return pow(2, 20 * x - 10) / 2; |  | ||||||
|     } else { |  | ||||||
|         return (2 - pow(2, -20 * x + 10)) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInCirc(double x) { return 1 - sqrt(1 - pow(x, 2)); } |  | ||||||
| 
 |  | ||||||
| static double easeOutCirc(double x) { return sqrt(1 - pow(x - 1, 2)); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutCirc(double x) { |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return (1 - sqrt(1 - pow(2 * x, 2))) / 2; |  | ||||||
|     } else { |  | ||||||
|         return (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInBack(double x) { |  | ||||||
|     const double c1 = 1.70158; |  | ||||||
|     const double c3 = c1 + 1; |  | ||||||
|     return c3 * x * x * x - c1 * x * x; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeOutBack(double x) { |  | ||||||
|     const double c1 = 1.70158; |  | ||||||
|     const double c3 = c1 + 1; |  | ||||||
|     return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInOutBack(double x) { |  | ||||||
|     const double c1 = 1.70158; |  | ||||||
|     const double c2 = c1 * 1.525; |  | ||||||
|     if(x < 0.5) { |  | ||||||
|         return (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2; |  | ||||||
|     } else { |  | ||||||
|         return (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInElastic(double x) { |  | ||||||
|     const double c4 = (2 * kPi) / 3; |  | ||||||
|     if(x == 0) { |  | ||||||
|         return 0; |  | ||||||
|     } else if(x == 1) { |  | ||||||
|         return 1; |  | ||||||
|     } else { |  | ||||||
|         return -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeOutElastic(double x) { |  | ||||||
|     const double c4 = (2 * kPi) / 3; |  | ||||||
|     if(x == 0) { |  | ||||||
|         return 0; |  | ||||||
|     } else if(x == 1) { |  | ||||||
|         return 1; |  | ||||||
|     } else { |  | ||||||
|         return pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInOutElastic(double x) { |  | ||||||
|     const double c5 = (2 * kPi) / 4.5; |  | ||||||
|     if(x == 0) { |  | ||||||
|         return 0; |  | ||||||
|     } else if(x == 1) { |  | ||||||
|         return 1; |  | ||||||
|     } else if(x < 0.5) { |  | ||||||
|         return -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2; |  | ||||||
|     } else { |  | ||||||
|         return (pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeOutBounce(double x) { |  | ||||||
|     const double n1 = 7.5625; |  | ||||||
|     const double d1 = 2.75; |  | ||||||
|     if(x < 1 / d1) { |  | ||||||
|         return n1 * x * x; |  | ||||||
|     } else if(x < 2 / d1) { |  | ||||||
|         x -= 1.5 / d1; |  | ||||||
|         return n1 * x * x + 0.75; |  | ||||||
|     } else if(x < 2.5 / d1) { |  | ||||||
|         x -= 2.25 / d1; |  | ||||||
|         return n1 * x * x + 0.9375; |  | ||||||
|     } else { |  | ||||||
|         x -= 2.625 / d1; |  | ||||||
|         return n1 * x * x + 0.984375; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static double easeInBounce(double x) { return 1 - easeOutBounce(1 - x); } |  | ||||||
| 
 |  | ||||||
| static double easeInOutBounce(double x) { |  | ||||||
|     return x < 0.5 ? (1 - easeOutBounce(1 - 2 * x)) / 2 : (1 + easeOutBounce(2 * x - 1)) / 2; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define DEF_EASE(name)                                                                             \ |  | ||||||
|     static bool easing_##name(int argc, py_Ref argv) {                                             \ |  | ||||||
|         PY_CHECK_ARGC(1);                                                                          \ |  | ||||||
|         py_f64 t;                                                                                  \ |  | ||||||
|         if(!py_castfloat(argv, &t)) return false;                                                  \ |  | ||||||
|         py_newfloat(py_retval(), ease##name(t));                                                   \ |  | ||||||
|         return true;                                                                               \ |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| DEF_EASE(Linear) |  | ||||||
| DEF_EASE(InSine) |  | ||||||
| DEF_EASE(OutSine) |  | ||||||
| DEF_EASE(InOutSine) |  | ||||||
| DEF_EASE(InQuad) |  | ||||||
| DEF_EASE(OutQuad) |  | ||||||
| DEF_EASE(InOutQuad) |  | ||||||
| DEF_EASE(InCubic) |  | ||||||
| DEF_EASE(OutCubic) |  | ||||||
| DEF_EASE(InOutCubic) |  | ||||||
| DEF_EASE(InQuart) |  | ||||||
| DEF_EASE(OutQuart) |  | ||||||
| DEF_EASE(InOutQuart) |  | ||||||
| DEF_EASE(InQuint) |  | ||||||
| DEF_EASE(OutQuint) |  | ||||||
| DEF_EASE(InOutQuint) |  | ||||||
| DEF_EASE(InExpo) |  | ||||||
| DEF_EASE(OutExpo) |  | ||||||
| DEF_EASE(InOutExpo) |  | ||||||
| DEF_EASE(InCirc) |  | ||||||
| DEF_EASE(OutCirc) |  | ||||||
| DEF_EASE(InOutCirc) |  | ||||||
| DEF_EASE(InBack) |  | ||||||
| DEF_EASE(OutBack) |  | ||||||
| DEF_EASE(InOutBack) |  | ||||||
| DEF_EASE(InElastic) |  | ||||||
| DEF_EASE(OutElastic) |  | ||||||
| DEF_EASE(InOutElastic) |  | ||||||
| DEF_EASE(InBounce) |  | ||||||
| DEF_EASE(OutBounce) |  | ||||||
| DEF_EASE(InOutBounce) |  | ||||||
| 
 |  | ||||||
| #undef DEF_EASE |  | ||||||
| 
 |  | ||||||
| void pk__add_module_easing() { |  | ||||||
|     py_GlobalRef mod = py_newmodule("easing"); |  | ||||||
| 
 |  | ||||||
|     py_bindfunc(mod, "Linear", easing_Linear); |  | ||||||
|     py_bindfunc(mod, "InSine", easing_InSine); |  | ||||||
|     py_bindfunc(mod, "OutSine", easing_OutSine); |  | ||||||
|     py_bindfunc(mod, "InOutSine", easing_InOutSine); |  | ||||||
|     py_bindfunc(mod, "InQuad", easing_InQuad); |  | ||||||
|     py_bindfunc(mod, "OutQuad", easing_OutQuad); |  | ||||||
|     py_bindfunc(mod, "InOutQuad", easing_InOutQuad); |  | ||||||
|     py_bindfunc(mod, "InCubic", easing_InCubic); |  | ||||||
|     py_bindfunc(mod, "OutCubic", easing_OutCubic); |  | ||||||
|     py_bindfunc(mod, "InOutCubic", easing_InOutCubic); |  | ||||||
|     py_bindfunc(mod, "InQuart", easing_InQuart); |  | ||||||
|     py_bindfunc(mod, "OutQuart", easing_OutQuart); |  | ||||||
|     py_bindfunc(mod, "InOutQuart", easing_InOutQuart); |  | ||||||
|     py_bindfunc(mod, "InQuint", easing_InQuint); |  | ||||||
|     py_bindfunc(mod, "OutQuint", easing_OutQuint); |  | ||||||
|     py_bindfunc(mod, "InOutQuint", easing_InOutQuint); |  | ||||||
|     py_bindfunc(mod, "InExpo", easing_InExpo); |  | ||||||
|     py_bindfunc(mod, "OutExpo", easing_OutExpo); |  | ||||||
|     py_bindfunc(mod, "InOutExpo", easing_InOutExpo); |  | ||||||
|     py_bindfunc(mod, "InCirc", easing_InCirc); |  | ||||||
|     py_bindfunc(mod, "OutCirc", easing_OutCirc); |  | ||||||
|     py_bindfunc(mod, "InOutCirc", easing_InOutCirc); |  | ||||||
|     py_bindfunc(mod, "InBack", easing_InBack); |  | ||||||
|     py_bindfunc(mod, "OutBack", easing_OutBack); |  | ||||||
|     py_bindfunc(mod, "InOutBack", easing_InOutBack); |  | ||||||
|     py_bindfunc(mod, "InElastic", easing_InElastic); |  | ||||||
|     py_bindfunc(mod, "OutElastic", easing_OutElastic); |  | ||||||
|     py_bindfunc(mod, "InOutElastic", easing_InOutElastic); |  | ||||||
|     py_bindfunc(mod, "InBounce", easing_InBounce); |  | ||||||
|     py_bindfunc(mod, "OutBounce", easing_OutBounce); |  | ||||||
|     py_bindfunc(mod, "InOutBounce", easing_InOutBounce); |  | ||||||
| } |  | ||||||
| @ -10,12 +10,13 @@ static bool json_loads(int argc, py_Ref argv) { | |||||||
|     PY_CHECK_ARGC(1); |     PY_CHECK_ARGC(1); | ||||||
|     PY_CHECK_ARG_TYPE(0, tp_str); |     PY_CHECK_ARG_TYPE(0, tp_str); | ||||||
|     const char* source = py_tostr(argv); |     const char* source = py_tostr(argv); | ||||||
|     return py_json_loads(source); |     py_GlobalRef mod = py_getmodule("json"); | ||||||
|  |     return py_exec(source, "<json>", EVAL_MODE, mod); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool json_dumps(int argc, py_Ref argv) { | static bool json_dumps(int argc, py_Ref argv) { | ||||||
|     PY_CHECK_ARGC(1); |     PY_CHECK_ARGC(1); | ||||||
|     return py_json_dumps(argv); |     return py_json(argv); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk__add_module_json() { | void pk__add_module_json() { | ||||||
| @ -97,7 +98,7 @@ static bool json__write_object(c11_sbuf* buf, py_TValue* obj) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool py_json_dumps(py_Ref val) { | bool py_json(py_Ref val) { | ||||||
|     c11_sbuf buf; |     c11_sbuf buf; | ||||||
|     c11_sbuf__ctor(&buf); |     c11_sbuf__ctor(&buf); | ||||||
|     bool ok = json__write_object(&buf, val); |     bool ok = json__write_object(&buf, val); | ||||||
| @ -108,15 +109,3 @@ bool py_json_dumps(py_Ref val) { | |||||||
|     c11_sbuf__py_submit(&buf, py_retval()); |     c11_sbuf__py_submit(&buf, py_retval()); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| bool py_json_loads(const char* source) { |  | ||||||
|     py_GlobalRef mod = py_getmodule("json"); |  | ||||||
|     return py_exec(source, "<json>", EVAL_MODE, mod); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool py_pusheval(const char* expr, py_GlobalRef module) { |  | ||||||
|     bool ok = py_exec(expr, "<string>", EVAL_MODE, module); |  | ||||||
|     if(!ok) return false; |  | ||||||
|     py_push(py_retval()); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,103 +0,0 @@ | |||||||
| #include "pocketpy/pocketpy.h" |  | ||||||
| #include "pocketpy/interpreter/vm.h" |  | ||||||
| #include "time.h" |  | ||||||
| 
 |  | ||||||
| #define NANOS_PER_SEC 1000000000 |  | ||||||
| 
 |  | ||||||
| static bool get_ns(int64_t* out) { |  | ||||||
|     struct timespec tms; |  | ||||||
|     /* The C11 way */ |  | ||||||
|     if(!timespec_get(&tms, TIME_UTC)) { |  | ||||||
|         return py_exception(tp_OSError, "%s", "timespec_get() failed"); |  | ||||||
|     } |  | ||||||
|     /* seconds, multiplied with 1 billion */ |  | ||||||
|     int64_t nanos = tms.tv_sec * NANOS_PER_SEC; |  | ||||||
|     /* Add full nanoseconds */ |  | ||||||
|     nanos += tms.tv_nsec; |  | ||||||
|     *out = nanos; |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool time_time(int argc, py_Ref argv) { |  | ||||||
|     PY_CHECK_ARGC(0); |  | ||||||
|     int64_t nanos; |  | ||||||
|     if(!get_ns(&nanos)) return false; |  | ||||||
|     py_newfloat(py_retval(), (double)nanos / NANOS_PER_SEC); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool time_time_ns(int argc, py_Ref argv) { |  | ||||||
|     PY_CHECK_ARGC(0); |  | ||||||
|     int64_t nanos; |  | ||||||
|     if(!get_ns(&nanos)) return false; |  | ||||||
|     py_newint(py_retval(), nanos); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool time_sleep(int argc, py_Ref argv) { |  | ||||||
|     PY_CHECK_ARGC(1); |  | ||||||
|     py_f64 secs; |  | ||||||
|     if(!py_castfloat(argv, &secs)) return false; |  | ||||||
| 
 |  | ||||||
|     int64_t start; |  | ||||||
|     if(!get_ns(&start)) return false; |  | ||||||
|     const int64_t end = start + secs * 1000000000; |  | ||||||
|     while(true) { |  | ||||||
|         int64_t now; |  | ||||||
|         if(!get_ns(&now)) return false; |  | ||||||
|         if(now >= end) break; |  | ||||||
|     } |  | ||||||
|     py_newnone(py_retval()); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool time_localtime(int argc, py_Ref argv) { |  | ||||||
|     PY_CHECK_ARGC(0); |  | ||||||
|     py_Type tp_struct_time = py_gettype("time", py_name("struct_time")); |  | ||||||
|     assert(tp_struct_time); |  | ||||||
|     struct tm* ud = py_newobject(py_retval(), tp_struct_time, 0, sizeof(struct tm)); |  | ||||||
|     time_t t = time(NULL); |  | ||||||
|     *ud = *localtime(&t); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define DEF_STRUCT_TIME__PROPERTY(name, expr)                                                      \ |  | ||||||
|     static bool struct_time__##name(int argc, py_Ref argv) {                                       \ |  | ||||||
|         PY_CHECK_ARGC(1);                                                                          \ |  | ||||||
|         struct tm* tm = py_touserdata(argv);                                                       \ |  | ||||||
|         py_newint(py_retval(), expr);                                                              \ |  | ||||||
|         return true;                                                                               \ |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_year, tm->tm_year + 1900) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_mon, tm->tm_mon + 1) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_mday, tm->tm_mday) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_hour, tm->tm_hour) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_min, tm->tm_min) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_sec, tm->tm_sec) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_wday, (tm->tm_wday + 6) % 7) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_yday, tm->tm_yday + 1) |  | ||||||
| DEF_STRUCT_TIME__PROPERTY(tm_isdst, tm->tm_isdst) |  | ||||||
| 
 |  | ||||||
| #undef DEF_STRUCT_TIME__PROPERTY |  | ||||||
| 
 |  | ||||||
| void pk__add_module_time() { |  | ||||||
|     py_Ref mod = py_newmodule("time"); |  | ||||||
| 
 |  | ||||||
|     py_Type tp_struct_time = py_newtype("struct_time", tp_object, mod, NULL); |  | ||||||
| 
 |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_year", struct_time__tm_year, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_mon", struct_time__tm_mon, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_mday", struct_time__tm_mday, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_hour", struct_time__tm_hour, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_min", struct_time__tm_min, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_sec", struct_time__tm_sec, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_wday", struct_time__tm_wday, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_yday", struct_time__tm_yday, NULL); |  | ||||||
|     py_bindproperty(tp_struct_time, "tm_isdst", struct_time__tm_isdst, NULL); |  | ||||||
| 
 |  | ||||||
|     py_bindfunc(mod, "time", time_time); |  | ||||||
|     py_bindfunc(mod, "time_ns", time_time_ns); |  | ||||||
|     py_bindfunc(mod, "sleep", time_sleep); |  | ||||||
|     py_bindfunc(mod, "localtime", time_localtime); |  | ||||||
| } |  | ||||||
| @ -58,11 +58,3 @@ bool py_issubclass(py_Type derived, py_Type base) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| py_Type py_typeof(py_Ref self) { return self->type; } | py_Type py_typeof(py_Ref self) { return self->type; } | ||||||
| 
 |  | ||||||
| py_Type py_gettype(const char* module, py_Name name) { |  | ||||||
|     py_Ref mod = py_getmodule(module); |  | ||||||
|     if(!mod) return 0; |  | ||||||
|     py_Ref object = py_getdict(mod, name); |  | ||||||
|     if(object && py_istype(object, tp_type)) return py_totype(object); |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
| @ -21,6 +21,9 @@ py_Ref py_getdict(py_Ref self, py_Name name) { | |||||||
| 
 | 
 | ||||||
| void py_setdict(py_Ref self, py_Name name, py_Ref val) { | void py_setdict(py_Ref self, py_Name name, py_Ref val) { | ||||||
|     assert(self && self->is_ptr); |     assert(self && self->is_ptr); | ||||||
|  |     // if(py_isidentical(self, &pk_current_vm->main)){
 | ||||||
|  |     //     printf("Setting main: %s\n", py_name2str(name));
 | ||||||
|  |     // }
 | ||||||
|     if(!py_ismagicname(name) || self->type != tp_type) { |     if(!py_ismagicname(name) || self->type != tp_type) { | ||||||
|         NameDict__set(PyObject__dict(self->_obj), name, *val); |         NameDict__set(PyObject__dict(self->_obj), name, *val); | ||||||
|     } else { |     } else { | ||||||
| @ -64,12 +67,6 @@ py_StackRef py_inspect_currentfunction(){ | |||||||
|     return frame->p0; |     return frame->p0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| py_GlobalRef py_inspect_currentmodule(){ |  | ||||||
|     Frame* frame = pk_current_vm->top_frame; |  | ||||||
|     if(!frame) return NULL; |  | ||||||
|     return frame->module; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void py_assign(py_Ref dst, py_Ref src) { *dst = *src; } | void py_assign(py_Ref dst, py_Ref src) { *dst = *src; } | ||||||
| 
 | 
 | ||||||
| /* Stack References */ | /* Stack References */ | ||||||
| @ -103,12 +100,8 @@ void py_pushnone() { | |||||||
|     py_newnone(vm->stack.sp++); |     py_newnone(vm->stack.sp++); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void py_pushname(py_Name name){ |  | ||||||
|     VM* vm = pk_current_vm; |  | ||||||
|     py_newint(vm->stack.sp++, name); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| py_Ref py_pushtmp() { | py_Ref py_pushtmp() { | ||||||
|     VM* vm = pk_current_vm; |     VM* vm = pk_current_vm; | ||||||
|     return vm->stack.sp++; |     py_newnil(vm->stack.sp++); | ||||||
|  |     return py_peek(-1); | ||||||
| } | } | ||||||
| @ -4,6 +4,11 @@ import datetime | |||||||
| def test_timedelta(): | def test_timedelta(): | ||||||
|     assert datetime.timedelta(days=1) == datetime.timedelta(days=1) |     assert datetime.timedelta(days=1) == datetime.timedelta(days=1) | ||||||
|     assert datetime.timedelta(days=1) != datetime.timedelta(days=2) |     assert datetime.timedelta(days=1) != datetime.timedelta(days=2) | ||||||
|  |     assert datetime.timedelta(days=1, seconds=1) >= datetime.timedelta(days=1) | ||||||
|  |     assert datetime.timedelta(days=0, seconds=1) <= datetime.timedelta(days=1) | ||||||
|  |     assert datetime.timedelta(days=1, seconds=1) < datetime.timedelta(days=2) | ||||||
|  |     assert datetime.timedelta(days=1, seconds=1) > datetime.timedelta(days=0) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def test_date(): | def test_date(): | ||||||
|     assert datetime.date(2023, 8, 5) == datetime.date(2023, 8, 5) |     assert datetime.date(2023, 8, 5) == datetime.date(2023, 8, 5) | ||||||
| @ -13,6 +18,7 @@ def test_date(): | |||||||
|     assert datetime.date(2024, 8, 5) > datetime.date(2023, 8, 6) |     assert datetime.date(2024, 8, 5) > datetime.date(2023, 8, 6) | ||||||
|     assert datetime.date(2023, 8, 5) < datetime.date(2024, 8, 6) |     assert datetime.date(2023, 8, 5) < datetime.date(2024, 8, 6) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| def test_datetime(): | def test_datetime(): | ||||||
|     assert datetime.datetime( |     assert datetime.datetime( | ||||||
|         2023, 8, 5, 12, 0, 0) == datetime.datetime(2023, 8, 5, 12, 0, 0) |         2023, 8, 5, 12, 0, 0) == datetime.datetime(2023, 8, 5, 12, 0, 0) | ||||||
| @ -27,6 +33,7 @@ def test_datetime(): | |||||||
|     assert datetime.datetime( |     assert datetime.datetime( | ||||||
|         2023, 8, 5, 12, 0, 0) <= datetime.datetime(2023, 8, 5, 12, 1, 0) |         2023, 8, 5, 12, 0, 0) <= datetime.datetime(2023, 8, 5, 12, 1, 0) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| test_timedelta() | test_timedelta() | ||||||
| test_date() | test_date() | ||||||
| test_datetime() | test_datetime() | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| from linalg import mat3x3, vec2, vec3 | from linalg import mat3x3, vec2, vec3, vec4 | ||||||
| import random | import random | ||||||
| import sys | import sys | ||||||
| import math | import math | ||||||
| @ -69,6 +69,25 @@ element_value_list = [getattr(test_vec3, attr) for attr in element_name_list] | |||||||
| copy_element_value_list = [getattr(test_vec3, attr) for attr in element_name_list] | copy_element_value_list = [getattr(test_vec3, attr) for attr in element_name_list] | ||||||
| assert element_value_list == copy_element_value_list | assert element_value_list == copy_element_value_list | ||||||
| 
 | 
 | ||||||
|  | # test vec4-------------------------------------------------------------------- | ||||||
|  | # 生成随机测试目标 | ||||||
|  | min_num = -10.0 | ||||||
|  | max_num = 10.0 | ||||||
|  | test_vec4 = vec4(*tuple([random.uniform(min_num, max_num) for _ in range(4)])) | ||||||
|  | static_test_vec4_float = vec4(3.1886954323, -1098399.59932453432, 9.00000000000002765, 4565400000000.0000000045) | ||||||
|  | static_test_vec4_int = vec4(278, -13919730938747, 1364223456756456, -37) | ||||||
|  | 
 | ||||||
|  | # test __repr__ | ||||||
|  | assert str(static_test_vec4_float).startswith('vec4(') | ||||||
|  | assert str(static_test_vec4_int).startswith('vec4(') | ||||||
|  | 
 | ||||||
|  | # test copy | ||||||
|  | element_name_list = ['x', 'y', 'z', 'w'] | ||||||
|  | element_value_list = [getattr(test_vec4, attr) for attr in element_name_list] | ||||||
|  | copy_element_value_list = [getattr(test_vec4.copy(), attr) for attr in element_name_list] | ||||||
|  | assert element_value_list == copy_element_value_list | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # test mat3x3-------------------------------------------------------------------- | # test mat3x3-------------------------------------------------------------------- | ||||||
| def mat_to_str_list(mat): | def mat_to_str_list(mat): | ||||||
|     ret = [[0,0,0], [0,0,0], [0,0,0]] |     ret = [[0,0,0], [0,0,0], [0,0,0]] | ||||||
| @ -427,6 +446,13 @@ assert test_mat_copy.inverse_transform_point(test_vec2_copy) == test_mat_copy.in | |||||||
| # test inverse_transform_vector | # test inverse_transform_vector | ||||||
| assert test_mat_copy.inverse_transform_vector(test_vec2_copy) == test_mat_copy.inverse().transform_vector(test_vec2_copy) | assert test_mat_copy.inverse_transform_vector(test_vec2_copy) == test_mat_copy.inverse().transform_vector(test_vec2_copy) | ||||||
| 
 | 
 | ||||||
|  | import c | ||||||
|  | a = vec4(1, 2, 3, 4) | ||||||
|  | b = a.tostruct() | ||||||
|  | assert a.sizeof() == 16 | ||||||
|  | assert b.sizeof() == 16 | ||||||
|  | assert vec4.fromstruct(b) == a | ||||||
|  | 
 | ||||||
| val = vec2.angle(vec2(-1, 0), vec2(0, -1)) | val = vec2.angle(vec2(-1, 0), vec2(0, -1)) | ||||||
| assert 1.57 < val < 1.58 | assert 1.57 < val < 1.58 | ||||||
| 
 | 
 | ||||||
| @ -440,6 +466,12 @@ class mymat3x3(mat3x3): | |||||||
|      |      | ||||||
| assert mymat3x3().f() | assert mymat3x3().f() | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | # test assign | ||||||
|  | c = vec4(1, 2, 3, 4) | ||||||
|  | assert c.copy_(vec4(5, 6, 7, 8)) is None | ||||||
|  | assert c == vec4(5, 6, 7, 8) | ||||||
|  | 
 | ||||||
| d = mat3x3.identity() | d = mat3x3.identity() | ||||||
| assert d.copy_(mat3x3.zeros()) is None | assert d.copy_(mat3x3.zeros()) is None | ||||||
| assert d == mat3x3.zeros() | assert d == mat3x3.zeros() | ||||||
| @ -459,7 +491,9 @@ except IndexError: | |||||||
| # test vec * vec | # test vec * vec | ||||||
| assert vec2(1, 2) * vec2(3, 4) == vec2(3, 8) | assert vec2(1, 2) * vec2(3, 4) == vec2(3, 8) | ||||||
| assert vec3(1, 2, 3) * vec3(4, 5, 6) == vec3(4, 10, 18) | assert vec3(1, 2, 3) * vec3(4, 5, 6) == vec3(4, 10, 18) | ||||||
|  | assert vec4(1, 2, 3, 4) * vec4(5, 6, 7, 8) == vec4(5, 12, 21, 32) | ||||||
| 
 | 
 | ||||||
| # test vec.__getitem__ | # test vec.__getitem__ | ||||||
| assert vec2(1, 2)[0] == 1 and vec2(1, 2)[1] == 2 | assert vec2(1, 2)[0] == 1 and vec2(1, 2)[1] == 2 | ||||||
| assert vec3(1, 2, 3)[0] == 1 and vec3(1, 2, 3)[1] == 2 and vec3(1, 2, 3)[2] == 3 | assert vec3(1, 2, 3)[0] == 1 and vec3(1, 2, 3)[1] == 2 and vec3(1, 2, 3)[2] == 3 | ||||||
|  | assert vec4(1, 2, 3, 4)[0] == 1 and vec4(1, 2, 3, 4)[1] == 2 and vec4(1, 2, 3, 4)[2] == 3 and vec4(1, 2, 3, 4)[3] == 4 | ||||||
|  | |||||||
| @ -259,15 +259,14 @@ DEALINGS IN THE SOFTWARE. | |||||||
|     var Module = { |     var Module = { | ||||||
|       onRuntimeInitialized: function () { |       onRuntimeInitialized: function () { | ||||||
|         Module.ccall('py_initialize', null, [], []); |         Module.ccall('py_initialize', null, [], []); | ||||||
|         console.log("py_initialize() called"); |  | ||||||
|       }, |       }, | ||||||
|       print: function (text) { |       print: function (text) { | ||||||
|  |         console.log(text); | ||||||
|         code_output.innerText += text + '\n'; |         code_output.innerText += text + '\n'; | ||||||
|       }, |       }, | ||||||
|       onabort: function (what) { |       onabort: function (what) { | ||||||
|         code_output.innerText += 'Aborted: ' + what + '\n'; |         code_output.innerText += 'Aborted: ' + what + '\n'; | ||||||
|         Module.ccall('py_finalize', null, [], []); |         Module.ccall('py_finalize', null, [], []); | ||||||
|         console.log("py_finalize() called"); |  | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|   </script> |   </script> | ||||||
| @ -295,7 +294,6 @@ DEALINGS IN THE SOFTWARE. | |||||||
|           'py_exec', 'boolean', ['string', 'string', 'number', 'number'], |           'py_exec', 'boolean', ['string', 'string', 'number', 'number'], | ||||||
|           [source, 'main.py', 0, 0] |           [source, 'main.py', 0, 0] | ||||||
|         ); |         ); | ||||||
|         console.log("py_exec() called"); |  | ||||||
|         if (!ok) { |         if (!ok) { | ||||||
|           Module.ccall('py_printexc', null, [], []); |           Module.ccall('py_printexc', null, [], []); | ||||||
|           Module.ccall('py_clearexc', null, ['number'], [0]); |           Module.ccall('py_clearexc', null, ['number'], [0]); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user