mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-31 08:50:17 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			efd98e6a6a
			...
			0871b627ed
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0871b627ed | ||
|  | 2a84911862 | ||
|  | bb67505613 | 
| @ -22,7 +22,7 @@ typedef struct pk_AnyStr { | |||||||
|         float _float; |         float _float; | ||||||
|         double _double; |         double _double; | ||||||
|         char _char; |         char _char; | ||||||
|         const pkpy_Str* _str; |         const py_Str* _str; | ||||||
|         c11_string _sv; |         c11_string _sv; | ||||||
|         const char* _cstr; |         const char* _cstr; | ||||||
|         void* _ptr; |         void* _ptr; | ||||||
| @ -34,7 +34,7 @@ PK_INLINE pk_AnyStr pk_AnyStr__i64(int64_t x) { pk_AnyStr s; s.type = 2; s._i64 | |||||||
| PK_INLINE pk_AnyStr pk_AnyStr__float(float x) { pk_AnyStr s; s.type = 3; s._float = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__float(float x) { pk_AnyStr s; s.type = 3; s._float = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__double(double x) { pk_AnyStr s; s.type = 4; s._double = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__double(double x) { pk_AnyStr s; s.type = 4; s._double = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__char(char x) { pk_AnyStr s; s.type = 5; s._char = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__char(char x) { pk_AnyStr s; s.type = 5; s._char = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__str(const pkpy_Str* x) { pk_AnyStr s; s.type = 6; s._str = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__str(const py_Str* x) { pk_AnyStr s; s.type = 6; s._str = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__sv(c11_string x) { pk_AnyStr s; s.type = 7; s._sv = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__sv(c11_string x) { pk_AnyStr s; s.type = 7; s._sv = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__cstr(const char* x) { pk_AnyStr s; s.type = 8; s._cstr = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__cstr(const char* x) { pk_AnyStr s; s.type = 8; s._cstr = x; return s; } | ||||||
| PK_INLINE pk_AnyStr pk_AnyStr__ptr(void* x) { pk_AnyStr s; s.type = 9; s._ptr = x; return s; } | PK_INLINE pk_AnyStr pk_AnyStr__ptr(void* x) { pk_AnyStr s; s.type = 9; s._ptr = x; return s; } | ||||||
| @ -48,7 +48,7 @@ void pk_SStream__write_i64(pk_SStream* self, int64_t); | |||||||
| void pk_SStream__write_float(pk_SStream* self, float, int precision); | void pk_SStream__write_float(pk_SStream* self, float, int precision); | ||||||
| void pk_SStream__write_double(pk_SStream* self, double, int precision); | void pk_SStream__write_double(pk_SStream* self, double, int precision); | ||||||
| void pk_SStream__write_char(pk_SStream* self, char); | void pk_SStream__write_char(pk_SStream* self, char); | ||||||
| void pk_SStream__write_Str(pk_SStream* self, const pkpy_Str*); | void pk_SStream__write_Str(pk_SStream* self, const py_Str*); | ||||||
| void pk_SStream__write_sv(pk_SStream* self, c11_string); | void pk_SStream__write_sv(pk_SStream* self, c11_string); | ||||||
| void pk_SStream__write_cstr(pk_SStream* self, const char*); | void pk_SStream__write_cstr(pk_SStream* self, const char*); | ||||||
| void pk_SStream__write_cstrn(pk_SStream* self, const char*, int); | void pk_SStream__write_cstrn(pk_SStream* self, const char*, int); | ||||||
| @ -59,7 +59,7 @@ void pk_SStream__write_any(pk_SStream* self, const char* fmt, const pk_AnyStr* a | |||||||
| const char* pk_format_any(const char* fmt, const pk_AnyStr* args, int n); | const char* pk_format_any(const char* fmt, const pk_AnyStr* args, int n); | ||||||
| 
 | 
 | ||||||
| // Submit the stream and return the final string. The stream becomes invalid after this call
 | // Submit the stream and return the final string. The stream becomes invalid after this call
 | ||||||
| pkpy_Str pk_SStream__submit(pk_SStream* self); | py_Str pk_SStream__submit(pk_SStream* self); | ||||||
| 
 | 
 | ||||||
| #define pk__anystr(x) _Generic((x), \ | #define pk__anystr(x) _Generic((x), \ | ||||||
|     int: pk_AnyStr__int, \ |     int: pk_AnyStr__int, \ | ||||||
| @ -67,7 +67,7 @@ pkpy_Str pk_SStream__submit(pk_SStream* self); | |||||||
|     float: pk_AnyStr__float, \ |     float: pk_AnyStr__float, \ | ||||||
|     double: pk_AnyStr__double, \ |     double: pk_AnyStr__double, \ | ||||||
|     char: pk_AnyStr__char, \ |     char: pk_AnyStr__char, \ | ||||||
|     const pkpy_Str*: pk_AnyStr__str, \ |     const py_Str*: pk_AnyStr__str, \ | ||||||
|     c11_string: pk_AnyStr__sv, \ |     c11_string: pk_AnyStr__sv, \ | ||||||
|     const char*: pk_AnyStr__cstr, \ |     const char*: pk_AnyStr__cstr, \ | ||||||
|     void*: pk_AnyStr__ptr \ |     void*: pk_AnyStr__ptr \ | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ int c11_string__cmp(c11_string self, c11_string other); | |||||||
| int c11_string__cmp2(c11_string self, const char* other, int size); | int c11_string__cmp2(c11_string self, const char* other, int size); | ||||||
| int c11_string__cmp3(c11_string self, const char* other); | int c11_string__cmp3(c11_string self, const char* other); | ||||||
| 
 | 
 | ||||||
| typedef struct pkpy_Str{ | typedef struct py_Str{ | ||||||
|     int size; |     int size; | ||||||
|     bool is_ascii; |     bool is_ascii; | ||||||
|     bool is_sso; |     bool is_sso; | ||||||
| @ -27,46 +27,46 @@ typedef struct pkpy_Str{ | |||||||
|         char* _ptr; |         char* _ptr; | ||||||
|         char _inlined[16]; |         char _inlined[16]; | ||||||
|     }; |     }; | ||||||
| } pkpy_Str; | } py_Str; | ||||||
| 
 | 
 | ||||||
| PK_INLINE const char* pkpy_Str__data(const pkpy_Str* self){ | PK_INLINE const char* py_Str__data(const py_Str* self){ | ||||||
|     return self->is_sso ? self->_inlined : self->_ptr; |     return self->is_sso ? self->_inlined : self->_ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PK_INLINE c11_string pkpy_Str__sv(const pkpy_Str* self){ | PK_INLINE c11_string py_Str__sv(const py_Str* self){ | ||||||
|     c11_string retval; |     c11_string retval; | ||||||
|     retval.data = pkpy_Str__data(self); |     retval.data = py_Str__data(self); | ||||||
|     retval.size = self->size; |     retval.size = self->size; | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pkpy_Str__ctor(pkpy_Str* self, const char* data); | void py_Str__ctor(py_Str* self, const char* data); | ||||||
| void pkpy_Str__ctor2(pkpy_Str* self, const char* data, int size); | void py_Str__ctor2(py_Str* self, const char* data, int size); | ||||||
| void pkpy_Str__dtor(pkpy_Str* self); | void py_Str__dtor(py_Str* self); | ||||||
| pkpy_Str pkpy_Str__copy(const pkpy_Str* self); | py_Str py_Str__copy(const py_Str* self); | ||||||
| pkpy_Str pkpy_Str__concat(const pkpy_Str* self, const pkpy_Str* other); | py_Str py_Str__concat(const py_Str* self, const py_Str* other); | ||||||
| pkpy_Str pkpy_Str__concat2(const pkpy_Str* self, const char* other, int size); | py_Str py_Str__concat2(const py_Str* self, const char* other, int size); | ||||||
| pkpy_Str pkpy_Str__slice(const pkpy_Str* self, int start); | py_Str py_Str__slice(const py_Str* self, int start); | ||||||
| pkpy_Str pkpy_Str__slice2(const pkpy_Str* self, int start, int stop); | py_Str py_Str__slice2(const py_Str* self, int start, int stop); | ||||||
| pkpy_Str pkpy_Str__lower(const pkpy_Str* self); | py_Str py_Str__lower(const py_Str* self); | ||||||
| pkpy_Str pkpy_Str__upper(const pkpy_Str* self); | py_Str py_Str__upper(const py_Str* self); | ||||||
| pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote); | py_Str py_Str__escape(const py_Str* self, char quote); | ||||||
| pkpy_Str pkpy_Str__strip(const pkpy_Str* self, bool left, bool right); | py_Str py_Str__strip(const py_Str* self, bool left, bool right); | ||||||
| pkpy_Str pkpy_Str__strip2(const pkpy_Str* self, bool left, bool right, const pkpy_Str* chars); | py_Str py_Str__strip2(const py_Str* self, bool left, bool right, const py_Str* chars); | ||||||
| pkpy_Str pkpy_Str__replace(const pkpy_Str* self, char old, char new_); | py_Str py_Str__replace(const py_Str* self, char old, char new_); | ||||||
| pkpy_Str pkpy_Str__replace2(const pkpy_Str* self, const pkpy_Str* old, const pkpy_Str* new_); | py_Str py_Str__replace2(const py_Str* self, const py_Str* old, const py_Str* new_); | ||||||
| pkpy_Str pkpy_Str__u8_getitem(const pkpy_Str* self, int i); | py_Str py_Str__u8_getitem(const py_Str* self, int i); | ||||||
| pkpy_Str pkpy_Str__u8_slice(const pkpy_Str* self, int start, int stop, int step); | py_Str py_Str__u8_slice(const py_Str* self, int start, int stop, int step); | ||||||
| int pkpy_Str__u8_length(const pkpy_Str* self); | int py_Str__u8_length(const py_Str* self); | ||||||
| int pkpy_Str__cmp(const pkpy_Str* self, const pkpy_Str* other); | int py_Str__cmp(const py_Str* self, const py_Str* other); | ||||||
| int pkpy_Str__cmp2(const pkpy_Str* self, const char* other, int size); | int py_Str__cmp2(const py_Str* self, const char* other, int size); | ||||||
| int pkpy_Str__cmp3(const pkpy_Str* self, const char* other); | int py_Str__cmp3(const py_Str* self, const char* other); | ||||||
| int pkpy_Str__unicode_index_to_byte(const pkpy_Str* self, int i); | int py_Str__unicode_index_to_byte(const py_Str* self, int i); | ||||||
| int pkpy_Str__byte_index_to_unicode(const pkpy_Str* self, int n); | int py_Str__byte_index_to_unicode(const py_Str* self, int n); | ||||||
| int pkpy_Str__index(const pkpy_Str* self, const pkpy_Str* sub, int start); | int py_Str__index(const py_Str* self, const py_Str* sub, int start); | ||||||
| int pkpy_Str__count(const pkpy_Str* self, const pkpy_Str* sub); | int py_Str__count(const py_Str* self, const py_Str* sub); | ||||||
| c11_vector/* T=c11_string */ pkpy_Str__split(const pkpy_Str* self, char sep); | c11_vector/* T=c11_string */ py_Str__split(const py_Str* self, char sep); | ||||||
| c11_vector/* T=c11_string */ pkpy_Str__split2(const pkpy_Str* self, const pkpy_Str* sep); | c11_vector/* T=c11_string */ py_Str__split2(const py_Str* self, const py_Str* sep); | ||||||
| 
 | 
 | ||||||
| bool c11__isascii(const char* p, int size); | bool c11__isascii(const char* p, int size); | ||||||
| bool c11__is_unicode_Lo_char(int c); | bool c11__is_unicode_Lo_char(int c); | ||||||
|  | |||||||
| @ -9,6 +9,8 @@ extern "C" { | |||||||
| 
 | 
 | ||||||
| typedef uint16_t StrName; | typedef uint16_t StrName; | ||||||
| 
 | 
 | ||||||
|  | #define py_name(name) pk_StrName__map(#name) | ||||||
|  | 
 | ||||||
| uint16_t pk_StrName__map(const char*); | uint16_t pk_StrName__map(const char*); | ||||||
| uint16_t pk_StrName__map2(c11_string); | uint16_t pk_StrName__map2(c11_string); | ||||||
| const char* pk_StrName__rmap(uint16_t index); | const char* pk_StrName__rmap(uint16_t index); | ||||||
|  | |||||||
| @ -42,7 +42,7 @@ typedef enum TokenIndex{ | |||||||
| void pk_TokenDeserializer__ctor(pk_TokenDeserializer* self, const char* source); | void pk_TokenDeserializer__ctor(pk_TokenDeserializer* self, const char* source); | ||||||
| bool pk_TokenDeserializer__match_char(pk_TokenDeserializer* self, char c); | bool pk_TokenDeserializer__match_char(pk_TokenDeserializer* self, char c); | ||||||
| c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c); | c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c); | ||||||
| pkpy_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c); | py_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c); | ||||||
| int pk_TokenDeserializer__read_count(pk_TokenDeserializer* self); | int pk_TokenDeserializer__read_count(pk_TokenDeserializer* self); | ||||||
| int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c); | int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c); | ||||||
| double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c); | double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c); | ||||||
|  | |||||||
| @ -98,8 +98,8 @@ struct Lexer { | |||||||
| 
 | 
 | ||||||
|     Lexer(VM* vm, std::string_view source, const Str& filename, CompileMode mode) noexcept{ |     Lexer(VM* vm, std::string_view source, const Str& filename, CompileMode mode) noexcept{ | ||||||
|         src = pkpy_SourceData__rcnew({source.data(), (int)source.size()}, &filename, mode); |         src = pkpy_SourceData__rcnew({source.data(), (int)source.size()}, &filename, mode); | ||||||
|         this->token_start = pkpy_Str__data(&src->source); |         this->token_start = py_Str__data(&src->source); | ||||||
|         this->curr_char = pkpy_Str__data(&src->source); |         this->curr_char = py_Str__data(&src->source); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ~Lexer(){ |     ~Lexer(){ | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| PyVar* FastLocals__try_get_by_name(PyVar* locals, const CodeObject* co, StrName name); | PyVar* FastLocals__try_get_by_name(PyVar* locals, const CodeObject* co, py_Name name); | ||||||
| pk_NameDict* FastLocals__to_namedict(PyVar* locals, const CodeObject* co); | pk_NameDict* FastLocals__to_namedict(PyVar* locals, const CodeObject* co); | ||||||
| 
 | 
 | ||||||
| typedef struct ValueStack { | typedef struct ValueStack { | ||||||
| @ -46,7 +46,7 @@ typedef struct Frame { | |||||||
| } Frame; | } Frame; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Frame* Frame__new(const CodeObject* co, PyObject* module, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co); | Frame* Frame__new(const CodeObject* co, const PyVar* module, const PyVar* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co); | ||||||
| void Frame__delete(Frame* self); | void Frame__delete(Frame* self); | ||||||
| 
 | 
 | ||||||
| PK_INLINE int Frame__ip(const Frame* self){ | PK_INLINE int Frame__ip(const Frame* self){ | ||||||
| @ -64,14 +64,14 @@ PK_INLINE int Frame__iblock(const Frame* self){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PK_INLINE pk_NameDict* Frame__f_globals(Frame* self){ | PK_INLINE pk_NameDict* Frame__f_globals(Frame* self){ | ||||||
|     return self->module->dict; |     return PyObject__dict(self->module); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PK_INLINE PyVar* Frame__f_globals_try_get(Frame* self, StrName name){ | PK_INLINE PyVar* Frame__f_globals_try_get(Frame* self, py_Name name){ | ||||||
|     return pk_NameDict__try_get(self->module->dict, name); |     return pk_NameDict__try_get(Frame__f_globals(self), name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyVar* Frame__f_closure_try_get(Frame* self, StrName name); | PyVar* Frame__f_closure_try_get(Frame* self, py_Name name); | ||||||
| 
 | 
 | ||||||
| int Frame__prepare_jump_exception_handler(Frame* self, ValueStack*); | int Frame__prepare_jump_exception_handler(Frame* self, ValueStack*); | ||||||
| void Frame__prepare_jump_break(Frame* self, ValueStack*, int); | void Frame__prepare_jump_break(Frame* self, ValueStack*, int); | ||||||
|  | |||||||
| @ -28,8 +28,8 @@ void pk_ManagedHeap__collect_if_needed(pk_ManagedHeap* self); | |||||||
| int pk_ManagedHeap__collect(pk_ManagedHeap* self); | int pk_ManagedHeap__collect(pk_ManagedHeap* self); | ||||||
| int pk_ManagedHeap__sweep(pk_ManagedHeap* self); | int pk_ManagedHeap__sweep(pk_ManagedHeap* self); | ||||||
| 
 | 
 | ||||||
| PyObject* pk_ManagedHeap__new(pk_ManagedHeap* self, Type type, int size); | PyObject* pk_ManagedHeap__new(pk_ManagedHeap* self, Type type, int slots, int size); | ||||||
| PyObject* pk_ManagedHeap__gcnew(pk_ManagedHeap* self, Type type, int size); | PyObject* pk_ManagedHeap__gcnew(pk_ManagedHeap* self, Type type, int slots, int size); | ||||||
| 
 | 
 | ||||||
| // external implementation
 | // external implementation
 | ||||||
| void pk_ManagedHeap__mark(pk_ManagedHeap* self); | void pk_ManagedHeap__mark(pk_ManagedHeap* self); | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| typedef struct pk_TypeInfo{ | typedef struct pk_TypeInfo{ | ||||||
|     StrName name; |     py_Name name; | ||||||
|     Type base; |     Type base; | ||||||
| 
 | 
 | ||||||
|     PyVar self;      // the type object itself
 |     PyVar self;      // the type object itself
 | ||||||
| @ -38,7 +38,7 @@ typedef struct pk_TypeInfo{ | |||||||
|     py_CFunction on_end_subclass;   // for enum module
 |     py_CFunction on_end_subclass;   // for enum module
 | ||||||
| } pk_TypeInfo; | } pk_TypeInfo; | ||||||
| 
 | 
 | ||||||
| void pk_TypeInfo__ctor(pk_TypeInfo* self, StrName name, Type base, PyObject* obj, const PyVar* module, bool subclass_enabled); | void pk_TypeInfo__ctor(pk_TypeInfo* self, py_Name name, Type base, PyObject* obj, const PyVar* module, bool subclass_enabled); | ||||||
| void pk_TypeInfo__dtor(pk_TypeInfo* self); | void pk_TypeInfo__dtor(pk_TypeInfo* self); | ||||||
| 
 | 
 | ||||||
| typedef struct pk_VM { | typedef struct pk_VM { | ||||||
| @ -64,6 +64,7 @@ typedef struct pk_VM { | |||||||
|     PyVar last_retval; |     PyVar last_retval; | ||||||
|     // registers
 |     // registers
 | ||||||
|     PyVar reg[8]; |     PyVar reg[8]; | ||||||
|  |     PyVar sysreg[8]; | ||||||
| 
 | 
 | ||||||
|     PyObject* __curr_class; |     PyObject* __curr_class; | ||||||
|     PyObject* __cached_object_new; |     PyObject* __cached_object_new; | ||||||
|  | |||||||
| @ -69,7 +69,7 @@ typedef struct BytecodeEx { | |||||||
| 
 | 
 | ||||||
| typedef struct CodeObject { | typedef struct CodeObject { | ||||||
|     pkpy_SourceData_ src; |     pkpy_SourceData_ src; | ||||||
|     pkpy_Str name; |     py_Str name; | ||||||
| 
 | 
 | ||||||
|     c11_vector/*T=Bytecode*/                codes; |     c11_vector/*T=Bytecode*/                codes; | ||||||
|     c11_vector/*T=CodeObjectByteCodeEx*/    codes_ex; |     c11_vector/*T=CodeObjectByteCodeEx*/    codes_ex; | ||||||
|  | |||||||
| @ -13,12 +13,12 @@ typedef struct pkpy_ExceptionFrame { | |||||||
|     pkpy_SourceData_ src; |     pkpy_SourceData_ src; | ||||||
|     int lineno; |     int lineno; | ||||||
|     const char* cursor; |     const char* cursor; | ||||||
|     pkpy_Str name; |     py_Str name; | ||||||
| } pkpy_ExceptionFrame; | } pkpy_ExceptionFrame; | ||||||
| 
 | 
 | ||||||
| typedef struct pkpy_Exception { | typedef struct pkpy_Exception { | ||||||
|     StrName type; |     StrName type; | ||||||
|     pkpy_Str msg; |     py_Str msg; | ||||||
|     bool is_re; |     bool is_re; | ||||||
| 
 | 
 | ||||||
|     int _ip_on_error; |     int _ip_on_error; | ||||||
| @ -32,7 +32,7 @@ typedef struct pkpy_Exception { | |||||||
| void pkpy_Exception__ctor(pkpy_Exception* self, StrName type); | void pkpy_Exception__ctor(pkpy_Exception* self, StrName type); | ||||||
| void pkpy_Exception__dtor(pkpy_Exception* self); | void pkpy_Exception__dtor(pkpy_Exception* self); | ||||||
| void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int lineno, const char* cursor, const char* name); | void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int lineno, const char* cursor, const char* name); | ||||||
| pkpy_Str pkpy_Exception__summary(pkpy_Exception* self); | py_Str pkpy_Exception__summary(pkpy_Exception* self); | ||||||
| 
 | 
 | ||||||
| struct Error{ | struct Error{ | ||||||
|     const char* type; |     const char* type; | ||||||
|  | |||||||
| @ -11,17 +11,24 @@ typedef struct PyObject{ | |||||||
|     Type type;          // we have a duplicated type here for convenience
 |     Type type;          // we have a duplicated type here for convenience
 | ||||||
|     bool gc_is_large; |     bool gc_is_large; | ||||||
|     bool gc_marked; |     bool gc_marked; | ||||||
|     pk_NameDict* dict;  // gc will delete this on destruction
 |     int slots;          // number of slots in the object
 | ||||||
| } PyObject; | } PyObject; | ||||||
| 
 | 
 | ||||||
| static_assert(sizeof(PyObject) <= 16, "!(sizeof(PyObject) <= 16)"); | // slots >= 0, allocate N slots
 | ||||||
|  | // slots == -1, allocate a dict
 | ||||||
| 
 | 
 | ||||||
| #define PyObject__value_ptr(self)   ((char*)self + 16) | // | 8 bytes HEADER | <N slots> | <value>
 | ||||||
| #define PyObject__as(T, self)       (T*)(PyObject__value_ptr(self)) | // | 8 bytes HEADER | <dict>    | <value>
 | ||||||
| #define PK_OBJ_GET(T, val)          (*(T*)(PyObject__value_ptr((val)._obj))) |  | ||||||
| #define PK_OBJ_SIZEOF(T)            (sizeof(T) + 16) |  | ||||||
| 
 | 
 | ||||||
| PyObject* PyObject__new(Type type, int size); | static_assert(sizeof(PyObject) <= 8, "!(sizeof(PyObject) <= 8)"); | ||||||
|  | 
 | ||||||
|  | PyVar* PyObject__slots(PyObject* self); | ||||||
|  | pk_NameDict* PyObject__dict(PyObject* self); | ||||||
|  | void* PyObject__value(PyObject* self); | ||||||
|  | 
 | ||||||
|  | #define PK_OBJ_HEADER_SIZE(slots) ((slots)>=0 ? 8+sizeof(PyVar)*(slots) : 8+sizeof(pk_NameDict)) | ||||||
|  | 
 | ||||||
|  | PyObject* PyObject__new(Type type, int slots, int size); | ||||||
| void PyObject__delete(PyObject* self); | void PyObject__delete(PyObject* self); | ||||||
| 
 | 
 | ||||||
| PK_INLINE PyVar PyVar__fromobj(PyObject* obj){ | PK_INLINE PyVar PyVar__fromobj(PyObject* obj){ | ||||||
|  | |||||||
| @ -16,21 +16,21 @@ struct pkpy_SourceData { | |||||||
|     enum CompileMode mode; |     enum CompileMode mode; | ||||||
|     bool is_precompiled; |     bool is_precompiled; | ||||||
| 
 | 
 | ||||||
|     pkpy_Str filename; |     py_Str filename; | ||||||
|     pkpy_Str source; |     py_Str source; | ||||||
| 
 | 
 | ||||||
|     c11_vector/*T=const char* */ line_starts; |     c11_vector/*T=const char* */ line_starts; | ||||||
|     c11_vector/*T=pkpy_Str*/ _precompiled_tokens; |     c11_vector/*T=py_Str*/ _precompiled_tokens; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct pkpy_SourceData* pkpy_SourceData_; | typedef struct pkpy_SourceData* pkpy_SourceData_; | ||||||
| 
 | 
 | ||||||
| pkpy_SourceData_ pkpy_SourceData__rcnew(c11_string source, const pkpy_Str *filename, enum CompileMode mode); | pkpy_SourceData_ pkpy_SourceData__rcnew(c11_string source, const py_Str *filename, enum CompileMode mode); | ||||||
| void pkpy_SourceData__ctor(struct pkpy_SourceData *self, c11_string source, const pkpy_Str *filename, enum CompileMode mode); | void pkpy_SourceData__ctor(struct pkpy_SourceData *self, c11_string source, const py_Str *filename, enum CompileMode mode); | ||||||
| void pkpy_SourceData__dtor(struct pkpy_SourceData* self); | void pkpy_SourceData__dtor(struct pkpy_SourceData* self); | ||||||
| 
 | 
 | ||||||
| bool pkpy_SourceData__get_line(const struct pkpy_SourceData* self, int lineno, const char** st, const char** ed); | bool pkpy_SourceData__get_line(const struct pkpy_SourceData* self, int lineno, const char** st, const char** ed); | ||||||
| pkpy_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData *self, int lineno, const char *cursor, const char *name); | py_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData *self, int lineno, const char *cursor, const char *name); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,7 +10,16 @@ extern "C" { | |||||||
| typedef struct PyObject PyObject; | typedef struct PyObject PyObject; | ||||||
| typedef struct PyVar PyVar; | typedef struct PyVar PyVar; | ||||||
| typedef struct pk_VM pk_VM; | typedef struct pk_VM pk_VM; | ||||||
| typedef struct py_Error py_Error; | typedef uint16_t py_Name; | ||||||
|  | typedef int16_t Type; | ||||||
|  | typedef PyVar* py_Ref; | ||||||
|  | typedef int (*py_CFunction)(const py_Ref, int); | ||||||
|  | 
 | ||||||
|  | typedef struct py_Str py_Str; | ||||||
|  | 
 | ||||||
|  | typedef struct py_Error{ | ||||||
|  |     Type type; | ||||||
|  | } py_Error; | ||||||
| 
 | 
 | ||||||
| typedef enum BindType { | typedef enum BindType { | ||||||
|     BindType_FUNCTION, |     BindType_FUNCTION, | ||||||
| @ -18,55 +27,128 @@ typedef enum BindType { | |||||||
|     BindType_CLASSMETHOD, |     BindType_CLASSMETHOD, | ||||||
| } BindType; | } BindType; | ||||||
| 
 | 
 | ||||||
| typedef int (*py_CFunction)(const PyVar*, int); |  | ||||||
| 
 | 
 | ||||||
| typedef uint16_t StrName; |  | ||||||
| typedef int16_t Type; |  | ||||||
| 
 | 
 | ||||||
| extern pk_VM* pk_current_vm; | extern pk_VM* pk_current_vm; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| void py_initialize(); | void py_initialize(); | ||||||
| // void py_switch_vm(const char* name);
 | // void py_switch_vm(const char* name);
 | ||||||
| void py_finalize(); | void py_finalize(); | ||||||
| 
 | 
 | ||||||
| py_Error* py_exec_simple(const char*); | int py_exec_simple(const char*); | ||||||
| py_Error* py_eval_simple(const char*, PyVar*); | int py_eval_simple(const char*, py_Ref); | ||||||
| 
 | 
 | ||||||
| /* py_error */ | /* py_error */ | ||||||
| void py_Error__print(const py_Error*); | py_Error* py_getlasterror(); | ||||||
| void py_Error__delete(py_Error*); | void py_Error__print(py_Error*); | ||||||
| 
 | 
 | ||||||
| int py_eq(const PyVar*, const PyVar*); | int py_eq(const py_Ref, const py_Ref); | ||||||
| int py_le(const PyVar*, const PyVar*); | int py_le(const py_Ref, const py_Ref); | ||||||
| int py_hash(const PyVar*, int64_t* out); | int py_hash(const py_Ref, int64_t* out); | ||||||
| 
 | 
 | ||||||
| /* py_var */ | /* py_var */ | ||||||
| void py_new_int(PyVar*, int64_t); | void py_newint(py_Ref, int64_t); | ||||||
| void py_new_float(PyVar*, double); | void py_newfloat(py_Ref, double); | ||||||
| void py_new_bool(PyVar*, bool); | void py_newbool(py_Ref, bool); | ||||||
| void py_new_str(PyVar*, const char*); | void py_newstr(py_Ref, const char*); | ||||||
| void py_new_strn(PyVar*, const char*, int); | void py_newstrn(py_Ref, const char*, int); | ||||||
| void py_new_fstr(PyVar*, const char*, ...); | // void py_newfstr(py_Ref, const char*, ...);
 | ||||||
| void py_new_bytes(PyVar*, const uint8_t*, int); | void py_newbytes(py_Ref, const uint8_t*, int); | ||||||
| void py_new_none(PyVar*); | void py_newnone(py_Ref); | ||||||
| void py_new_null(PyVar*); | void py_newnull(py_Ref); | ||||||
|  | 
 | ||||||
|  | void py_newtuple(py_Ref, int); | ||||||
| 
 | 
 | ||||||
| // new style decl-based function
 | // new style decl-based function
 | ||||||
| void py_new_function(PyVar*, py_CFunction, const char* sig, BindType bt); | void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt); | ||||||
| void py_new_function2(PyVar*, py_CFunction, const char* sig, BindType bt, const char* docstring, const PyVar* userdata); | void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata); | ||||||
| // old style argc-based function
 | // old style argc-based function
 | ||||||
| void py_new_nativefunc(PyVar*, py_CFunction, int argc, BindType bt); | void py_newnativefunc(py_Ref, py_CFunction, int argc, BindType bt); | ||||||
| void py_new_nativefunc2(PyVar*, py_CFunction, int argc, BindType bt, const char* docstring, const PyVar* userdata); | void py_newnativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata); | ||||||
| 
 | 
 | ||||||
| int py_setattr(PyVar* self, StrName name, const PyVar* val); |  | ||||||
| 
 | 
 | ||||||
| PyVar py_new_module(const char* name); | py_Ref py_newmodule(const char* name, const char* package); | ||||||
| PyVar pk_new_module(const char* name, const char* package); | py_Ref py_getmodule(const char* name); | ||||||
| 
 | const py_Ref py_import(const char* name); | ||||||
| // Type pk_new_type
 |  | ||||||
| 
 | 
 | ||||||
| #define py_isnull(self) ((self)->type == 0) | #define py_isnull(self) ((self)->type == 0) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /// Sets the name of the object to the given value.
 | ||||||
|  | void py_setdict(py_Ref self, py_Name name, const py_Ref val); | ||||||
|  | /// Returns a reference to the name of the object.
 | ||||||
|  | py_Ref py_getdict(const py_Ref self, py_Name name); | ||||||
|  | 
 | ||||||
|  | /// Sets the i-th slot of the object to the given value.
 | ||||||
|  | void py_setslot(py_Ref self, int i, const py_Ref val); | ||||||
|  | /// Returns a reference to the i-th slot of the object.
 | ||||||
|  | py_Ref py_getslot(const py_Ref self, int i); | ||||||
|  | 
 | ||||||
|  | /// Equivalent to `self.name = val`.
 | ||||||
|  | /// Returns 0 | err
 | ||||||
|  | int py_setattr(py_Ref self, py_Name name, const py_Ref val); | ||||||
|  | 
 | ||||||
|  | /// Equivalent to `self.name`.
 | ||||||
|  | /// Returns 0 | err
 | ||||||
|  | int py_getattr(const py_Ref self, py_Name name, py_Ref out); | ||||||
|  | 
 | ||||||
|  | /// Returns a reference to the i-th object from the top of the stack.
 | ||||||
|  | /// i should be negative, e.g. (-1) means TOS.
 | ||||||
|  | py_Ref py_stack(int i); | ||||||
|  | /// Returns a reference to the i-th register.
 | ||||||
|  | py_Ref py_reg(int i); | ||||||
|  | /// Returns a reference to the i-th system register.
 | ||||||
|  | py_Ref py_sysreg(int i); | ||||||
|  | /// Prepares a push and returns an uninitialized reference.
 | ||||||
|  | py_Ref py_push(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /// Pushes the object to the stack.
 | ||||||
|  | void py_pushref(const py_Ref src); | ||||||
|  | /// Pops the object from the stack.
 | ||||||
|  | void py_copyref(const py_Ref src, py_Ref dst); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* tuple */ | ||||||
|  | 
 | ||||||
|  | // unchecked functions, if self is not a tuple, the behavior is undefined
 | ||||||
|  | py_Ref py_tuple__getitem(const py_Ref self, int i); | ||||||
|  | void py_tuple__setitem(py_Ref self, int i, const py_Ref val); | ||||||
|  | int py_tuple__len(const py_Ref self); | ||||||
|  | bool py_tuple__contains(const py_Ref self, const py_Ref val); | ||||||
|  | 
 | ||||||
|  | // unchecked functions, if self is not a list, the behavior is undefined
 | ||||||
|  | py_Ref py_list__getitem(const py_Ref self, int i); | ||||||
|  | void py_list__setitem(py_Ref self, int i, const py_Ref val); | ||||||
|  | void py_list__delitem(py_Ref self, int i); | ||||||
|  | int py_list__len(const py_Ref self); | ||||||
|  | bool py_list__contains(const py_Ref self, const py_Ref val); | ||||||
|  | void py_list__append(py_Ref self, const py_Ref val); | ||||||
|  | void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end); | ||||||
|  | void py_list__clear(py_Ref self); | ||||||
|  | void py_list__insert(py_Ref self, int i, const py_Ref val); | ||||||
|  | 
 | ||||||
|  | // unchecked functions, if self is not a dict, the behavior is undefined
 | ||||||
|  | int py_dict__len(const py_Ref self); | ||||||
|  | bool py_dict__contains(const py_Ref self, const py_Ref key); | ||||||
|  | py_Ref py_dict__getitem(const py_Ref self, const py_Ref key); | ||||||
|  | void py_dict__setitem(py_Ref self, const py_Ref key, const py_Ref val); | ||||||
|  | void py_dict__delitem(py_Ref self, const py_Ref key); | ||||||
|  | void py_dict__clear(py_Ref self); | ||||||
|  | 
 | ||||||
|  | int py_str(const py_Ref, py_Str* out); | ||||||
|  | int py_repr(const py_Ref, py_Str* out); | ||||||
|  | 
 | ||||||
|  | int py_toint(py_Ref, int64_t* out); | ||||||
|  | int py_tofloat(py_Ref, double* out); | ||||||
|  | int py_tostr(py_Ref, py_Str** out); | ||||||
|  | int py_tobool(py_Ref, bool* out); | ||||||
|  | 
 | ||||||
|  | bool py_istype(const py_Ref, Type); | ||||||
|  | bool py_isinstance(const py_Ref obj, Type type); | ||||||
|  | bool py_issubclass(Type derived, Type base); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
| pkpy_SourceData_ pkpy_SourceData__rcnew(c11_string source, const pkpy_Str* filename, enum CompileMode mode) { | pkpy_SourceData_ pkpy_SourceData__rcnew(c11_string source, const py_Str* filename, enum CompileMode mode) { | ||||||
|     pkpy_SourceData_ self = malloc(sizeof(struct pkpy_SourceData)); |     pkpy_SourceData_ self = malloc(sizeof(struct pkpy_SourceData)); | ||||||
|     pkpy_SourceData__ctor(self, source, filename, mode); |     pkpy_SourceData__ctor(self, source, filename, mode); | ||||||
|     self->rc.count = 1; |     self->rc.count = 1; | ||||||
| @ -14,12 +14,12 @@ pkpy_SourceData_ pkpy_SourceData__rcnew(c11_string source, const pkpy_Str* filen | |||||||
| 
 | 
 | ||||||
| void pkpy_SourceData__ctor(struct pkpy_SourceData* self, | void pkpy_SourceData__ctor(struct pkpy_SourceData* self, | ||||||
|                            c11_string source,       // may not be null-terminated
 |                            c11_string source,       // may not be null-terminated
 | ||||||
|                            const pkpy_Str* filename, |                            const py_Str* filename, | ||||||
|                            enum CompileMode mode) { |                            enum CompileMode mode) { | ||||||
|     self->filename = pkpy_Str__copy(filename);  // OPTIMIZEME?
 |     self->filename = py_Str__copy(filename);  // OPTIMIZEME?
 | ||||||
|     self->mode = mode; |     self->mode = mode; | ||||||
|     c11_vector__ctor(&self->line_starts, sizeof(const char*)); |     c11_vector__ctor(&self->line_starts, sizeof(const char*)); | ||||||
|     c11_vector__ctor(&self->_precompiled_tokens, sizeof(pkpy_Str)); |     c11_vector__ctor(&self->_precompiled_tokens, sizeof(py_Str)); | ||||||
| 
 | 
 | ||||||
|     int index = 0; |     int index = 0; | ||||||
|     // Skip utf8 BOM if there is any.
 |     // Skip utf8 BOM if there is any.
 | ||||||
| @ -33,17 +33,17 @@ void pkpy_SourceData__ctor(struct pkpy_SourceData* self, | |||||||
|         index++; |         index++; | ||||||
|     } |     } | ||||||
|     self->source = pk_SStream__submit(&ss); |     self->source = pk_SStream__submit(&ss); | ||||||
|     self->is_precompiled = (strncmp(pkpy_Str__data(&self->source), "pkpy:", 5) == 0); |     self->is_precompiled = (strncmp(py_Str__data(&self->source), "pkpy:", 5) == 0); | ||||||
|     c11_vector__push(const char*, &self->line_starts, pkpy_Str__data(&self->source)); |     c11_vector__push(const char*, &self->line_starts, py_Str__data(&self->source)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pkpy_SourceData__dtor(struct pkpy_SourceData* self) { | void pkpy_SourceData__dtor(struct pkpy_SourceData* self) { | ||||||
|     pkpy_Str__dtor(&self->filename); |     py_Str__dtor(&self->filename); | ||||||
|     pkpy_Str__dtor(&self->source); |     py_Str__dtor(&self->source); | ||||||
|     c11_vector__dtor(&self->line_starts); |     c11_vector__dtor(&self->line_starts); | ||||||
| 
 | 
 | ||||||
|     for(int i=0; i<self->_precompiled_tokens.count; i++){ |     for(int i=0; i<self->_precompiled_tokens.count; i++){ | ||||||
|         pkpy_Str__dtor(c11__at(pkpy_Str, &self->_precompiled_tokens, i)); |         py_Str__dtor(c11__at(py_Str, &self->_precompiled_tokens, i)); | ||||||
|     } |     } | ||||||
|     c11_vector__dtor(&self->_precompiled_tokens); |     c11_vector__dtor(&self->_precompiled_tokens); | ||||||
| } | } | ||||||
| @ -62,7 +62,7 @@ bool pkpy_SourceData__get_line(const struct pkpy_SourceData* self, int lineno, c | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData* self, int lineno, const char* cursor, const char* name) { | py_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData* self, int lineno, const char* cursor, const char* name) { | ||||||
|     pk_SStream ss; |     pk_SStream ss; | ||||||
|     pk_SStream__ctor(&ss); |     pk_SStream__ctor(&ss); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -81,8 +81,8 @@ void pk_SStream__write_double(pk_SStream* self, double val, int precision){ | |||||||
|     if(all_is_digit) pk_SStream__write_cstr(self, ".0"); |     if(all_is_digit) pk_SStream__write_cstr(self, ".0"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_SStream__write_Str(pk_SStream* self, const pkpy_Str* str) { | void pk_SStream__write_Str(pk_SStream* self, const py_Str* str) { | ||||||
|     pk_SStream__write_cstrn(self, pkpy_Str__data(str), str->size); |     pk_SStream__write_cstrn(self, py_Str__data(str), str->size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_SStream__write_sv(pk_SStream* self, c11_string sv) { | void pk_SStream__write_sv(pk_SStream* self, c11_string sv) { | ||||||
| @ -150,9 +150,9 @@ void pk_SStream__write_any(pk_SStream* self, const char* fmt, const pk_AnyStr* a | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pk_SStream__submit(pk_SStream* self) { | py_Str pk_SStream__submit(pk_SStream* self) { | ||||||
|     c11_vector__push(char, &self->data, '\0'); |     c11_vector__push(char, &self->data, '\0'); | ||||||
|     pkpy_Str retval = { |     py_Str retval = { | ||||||
|         .size = self->data.count - 1, |         .size = self->data.count - 1, | ||||||
|         .is_ascii = c11__isascii((char*)self->data.data, self->data.count), |         .is_ascii = c11__isascii((char*)self->data.data, self->data.count), | ||||||
|         .is_sso = false, |         .is_sso = false, | ||||||
|  | |||||||
							
								
								
									
										180
									
								
								src/common/str.c
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								src/common/str.c
									
									
									
									
									
								
							| @ -7,11 +7,11 @@ | |||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| void pkpy_Str__ctor(pkpy_Str *self, const char *data){ | void py_Str__ctor(py_Str *self, const char *data){ | ||||||
|     pkpy_Str__ctor2(self, data, strlen(data)); |     py_Str__ctor2(self, data, strlen(data)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pkpy_Str__ctor2(pkpy_Str *self, const char *data, int size){ | void py_Str__ctor2(py_Str *self, const char *data, int size){ | ||||||
|     self->size = size; |     self->size = size; | ||||||
|     self->is_ascii = c11__isascii(data, size); |     self->is_ascii = c11__isascii(data, size); | ||||||
|     self->is_sso = size < sizeof(self->_inlined); |     self->is_sso = size < sizeof(self->_inlined); | ||||||
| @ -26,7 +26,7 @@ void pkpy_Str__ctor2(pkpy_Str *self, const char *data, int size){ | |||||||
|     p[size] = '\0'; |     p[size] = '\0'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pkpy_Str__dtor(pkpy_Str *self){ | void py_Str__dtor(py_Str *self){ | ||||||
|     if(!self->is_sso){ |     if(!self->is_sso){ | ||||||
|         free(self->_ptr); |         free(self->_ptr); | ||||||
|         self->is_sso = true; |         self->is_sso = true; | ||||||
| @ -34,8 +34,8 @@ void pkpy_Str__dtor(pkpy_Str *self){ | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__copy(const pkpy_Str *self){ | py_Str py_Str__copy(const py_Str *self){ | ||||||
|     pkpy_Str retval = *self; |     py_Str retval = *self; | ||||||
|     if(!self->is_sso){ |     if(!self->is_sso){ | ||||||
|         retval._ptr = (char*)malloc(self->size + 1); |         retval._ptr = (char*)malloc(self->size + 1); | ||||||
|         // '\0' is copied
 |         // '\0' is copied
 | ||||||
| @ -44,8 +44,8 @@ pkpy_Str pkpy_Str__copy(const pkpy_Str *self){ | |||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__concat(const pkpy_Str *self, const pkpy_Str *other){ | py_Str py_Str__concat(const py_Str *self, const py_Str *other){ | ||||||
|     pkpy_Str retval = { |     py_Str retval = { | ||||||
|         .size = self->size + other->size, |         .size = self->size + other->size, | ||||||
|         .is_ascii = self->is_ascii && other->is_ascii, |         .is_ascii = self->is_ascii && other->is_ascii, | ||||||
|         .is_sso = self->size + other->size < sizeof(retval._inlined), |         .is_sso = self->size + other->size < sizeof(retval._inlined), | ||||||
| @ -57,56 +57,56 @@ pkpy_Str pkpy_Str__concat(const pkpy_Str *self, const pkpy_Str *other){ | |||||||
|         retval._ptr = (char*)malloc(retval.size + 1); |         retval._ptr = (char*)malloc(retval.size + 1); | ||||||
|         p = retval._ptr; |         p = retval._ptr; | ||||||
|     } |     } | ||||||
|     memcpy(p, pkpy_Str__data(self), self->size); |     memcpy(p, py_Str__data(self), self->size); | ||||||
|     memcpy(p + self->size, pkpy_Str__data(other), other->size); |     memcpy(p + self->size, py_Str__data(other), other->size); | ||||||
|     p[retval.size] = '\0'; |     p[retval.size] = '\0'; | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__concat2(const pkpy_Str *self, const char *other, int size){ | py_Str py_Str__concat2(const py_Str *self, const char *other, int size){ | ||||||
|     pkpy_Str tmp; |     py_Str tmp; | ||||||
|     pkpy_Str__ctor2(&tmp, other, size); |     py_Str__ctor2(&tmp, other, size); | ||||||
|     pkpy_Str retval = pkpy_Str__concat(self, &tmp); |     py_Str retval = py_Str__concat(self, &tmp); | ||||||
|     pkpy_Str__dtor(&tmp); |     py_Str__dtor(&tmp); | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__slice(const pkpy_Str *self, int start){ | py_Str py_Str__slice(const py_Str *self, int start){ | ||||||
|     return pkpy_Str__slice2(self, start, self->size); |     return py_Str__slice2(self, start, self->size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__slice2(const pkpy_Str *self, int start, int stop){ | py_Str py_Str__slice2(const py_Str *self, int start, int stop){ | ||||||
|     pkpy_Str retval; |     py_Str retval; | ||||||
|     if(stop < start) stop = start; |     if(stop < start) stop = start; | ||||||
|     pkpy_Str__ctor2(&retval, pkpy_Str__data(self) + start, stop - start); |     py_Str__ctor2(&retval, py_Str__data(self) + start, stop - start); | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__lower(const pkpy_Str *self){ | py_Str py_Str__lower(const py_Str *self){ | ||||||
|     pkpy_Str retval = pkpy_Str__copy(self); |     py_Str retval = py_Str__copy(self); | ||||||
|     char* p = (char*)pkpy_Str__data(&retval); |     char* p = (char*)py_Str__data(&retval); | ||||||
|     for(int i = 0; i < retval.size; i++){ |     for(int i = 0; i < retval.size; i++){ | ||||||
|         if('A' <= p[i] && p[i] <= 'Z') p[i] += 32; |         if('A' <= p[i] && p[i] <= 'Z') p[i] += 32; | ||||||
|     } |     } | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__upper(const pkpy_Str *self){ | py_Str py_Str__upper(const py_Str *self){ | ||||||
|     pkpy_Str retval = pkpy_Str__copy(self); |     py_Str retval = py_Str__copy(self); | ||||||
|     char* p = (char*)pkpy_Str__data(&retval); |     char* p = (char*)py_Str__data(&retval); | ||||||
|     for(int i = 0; i < retval.size; i++){ |     for(int i = 0; i < retval.size; i++){ | ||||||
|         if('a' <= p[i] && p[i] <= 'z') p[i] -= 32; |         if('a' <= p[i] && p[i] <= 'z') p[i] -= 32; | ||||||
|     } |     } | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote){ | py_Str py_Str__escape(const py_Str* self, char quote){ | ||||||
|     assert(quote == '"' || quote == '\''); |     assert(quote == '"' || quote == '\''); | ||||||
|     c11_vector buffer; |     c11_vector buffer; | ||||||
|     c11_vector__ctor(&buffer, sizeof(char)); |     c11_vector__ctor(&buffer, sizeof(char)); | ||||||
|     c11_vector__reserve(&buffer, self->size); |     c11_vector__reserve(&buffer, self->size); | ||||||
|     c11_vector__push(char, &buffer, quote); |     c11_vector__push(char, &buffer, quote); | ||||||
|     const char* data = pkpy_Str__data(self); |     const char* data = py_Str__data(self); | ||||||
|     for(int i = 0; i < self->size; i++) { |     for(int i = 0; i < self->size; i++) { | ||||||
|         char c = data[i]; |         char c = data[i]; | ||||||
|         switch(c) { |         switch(c) { | ||||||
| @ -147,7 +147,7 @@ pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote){ | |||||||
|     } |     } | ||||||
|     c11_vector__push(char, &buffer, quote); |     c11_vector__push(char, &buffer, quote); | ||||||
|     c11_vector__push(char, &buffer, '\0'); |     c11_vector__push(char, &buffer, '\0'); | ||||||
|     pkpy_Str retval = { |     py_Str retval = { | ||||||
|         .size = buffer.count - 1, |         .size = buffer.count - 1, | ||||||
|         .is_ascii = self->is_ascii, |         .is_ascii = self->is_ascii, | ||||||
|         .is_sso = false, |         .is_sso = false, | ||||||
| @ -156,8 +156,8 @@ pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote){ | |||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__strip(const pkpy_Str *self, bool left, bool right){ | py_Str py_Str__strip(const py_Str *self, bool left, bool right){ | ||||||
|     const char* data = pkpy_Str__data(self); |     const char* data = py_Str__data(self); | ||||||
|     if(self->is_ascii) { |     if(self->is_ascii) { | ||||||
|         int L = 0; |         int L = 0; | ||||||
|         int R = self->size; |         int R = self->size; | ||||||
| @ -169,67 +169,67 @@ pkpy_Str pkpy_Str__strip(const pkpy_Str *self, bool left, bool right){ | |||||||
|             while(L < R && (data[R - 1] == ' ' || data[R - 1] == '\t' || data[R - 1] == '\n' || data[R - 1] == '\r')) |             while(L < R && (data[R - 1] == ' ' || data[R - 1] == '\t' || data[R - 1] == '\n' || data[R - 1] == '\r')) | ||||||
|                 R--; |                 R--; | ||||||
|         } |         } | ||||||
|         return pkpy_Str__slice2(self, L, R); |         return py_Str__slice2(self, L, R); | ||||||
|     } else { |     } else { | ||||||
|         pkpy_Str tmp; |         py_Str tmp; | ||||||
|         pkpy_Str__ctor(&tmp, " \t\n\r"); |         py_Str__ctor(&tmp, " \t\n\r"); | ||||||
|         pkpy_Str retval = pkpy_Str__strip2(self, left, right, &tmp); |         py_Str retval = py_Str__strip2(self, left, right, &tmp); | ||||||
|         pkpy_Str__dtor(&tmp); |         py_Str__dtor(&tmp); | ||||||
|         return retval; |         return retval; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__strip2(const pkpy_Str *self, bool left, bool right, const pkpy_Str *chars){ | py_Str py_Str__strip2(const py_Str *self, bool left, bool right, const py_Str *chars){ | ||||||
|     int L = 0; |     int L = 0; | ||||||
|     int R = pkpy_Str__u8_length(self); |     int R = py_Str__u8_length(self); | ||||||
|     if(left) { |     if(left) { | ||||||
|         while(L < R){ |         while(L < R){ | ||||||
|             pkpy_Str tmp = pkpy_Str__u8_getitem(self, L); |             py_Str tmp = py_Str__u8_getitem(self, L); | ||||||
|             bool found = pkpy_Str__index(chars, &tmp, 0) != -1; |             bool found = py_Str__index(chars, &tmp, 0) != -1; | ||||||
|             pkpy_Str__dtor(&tmp); |             py_Str__dtor(&tmp); | ||||||
|             if(!found) break; |             if(!found) break; | ||||||
|             L++; |             L++; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if(right) { |     if(right) { | ||||||
|         while(L < R){ |         while(L < R){ | ||||||
|             pkpy_Str tmp = pkpy_Str__u8_getitem(self, R - 1); |             py_Str tmp = py_Str__u8_getitem(self, R - 1); | ||||||
|             bool found = pkpy_Str__index(chars, &tmp, 0) != -1; |             bool found = py_Str__index(chars, &tmp, 0) != -1; | ||||||
|             pkpy_Str__dtor(&tmp); |             py_Str__dtor(&tmp); | ||||||
|             if(!found) break; |             if(!found) break; | ||||||
|             R--; |             R--; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return pkpy_Str__u8_slice(self, L, R, 1); |     return py_Str__u8_slice(self, L, R, 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__replace(const pkpy_Str *self, char old, char new_){ | py_Str py_Str__replace(const py_Str *self, char old, char new_){ | ||||||
|     pkpy_Str retval = pkpy_Str__copy(self); |     py_Str retval = py_Str__copy(self); | ||||||
|     char* p = (char*)pkpy_Str__data(&retval); |     char* p = (char*)py_Str__data(&retval); | ||||||
|     for(int i = 0; i < retval.size; i++){ |     for(int i = 0; i < retval.size; i++){ | ||||||
|         if(p[i] == old) p[i] = new_; |         if(p[i] == old) p[i] = new_; | ||||||
|     } |     } | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__replace2(const pkpy_Str *self, const pkpy_Str *old, const pkpy_Str *new_){ | py_Str py_Str__replace2(const py_Str *self, const py_Str *old, const py_Str *new_){ | ||||||
|     c11_vector buffer; |     c11_vector buffer; | ||||||
|     c11_vector__ctor(&buffer, sizeof(char)); |     c11_vector__ctor(&buffer, sizeof(char)); | ||||||
|     int start = 0; |     int start = 0; | ||||||
|     while(true) { |     while(true) { | ||||||
|         int i = pkpy_Str__index(self, old, start); |         int i = py_Str__index(self, old, start); | ||||||
|         if(i == -1) break; |         if(i == -1) break; | ||||||
|         pkpy_Str tmp = pkpy_Str__slice2(self, start, i); |         py_Str tmp = py_Str__slice2(self, start, i); | ||||||
|         c11_vector__extend(char, &buffer, pkpy_Str__data(&tmp), tmp.size); |         c11_vector__extend(char, &buffer, py_Str__data(&tmp), tmp.size); | ||||||
|         pkpy_Str__dtor(&tmp); |         py_Str__dtor(&tmp); | ||||||
|         c11_vector__extend(char, &buffer, pkpy_Str__data(new_), new_->size); |         c11_vector__extend(char, &buffer, py_Str__data(new_), new_->size); | ||||||
|         start = i + old->size; |         start = i + old->size; | ||||||
|     } |     } | ||||||
|     pkpy_Str tmp = pkpy_Str__slice2(self, start, self->size); |     py_Str tmp = py_Str__slice2(self, start, self->size); | ||||||
|     c11_vector__extend(char, &buffer, pkpy_Str__data(&tmp), tmp.size); |     c11_vector__extend(char, &buffer, py_Str__data(&tmp), tmp.size); | ||||||
|     pkpy_Str__dtor(&tmp); |     py_Str__dtor(&tmp); | ||||||
|     c11_vector__push(char, &buffer, '\0'); |     c11_vector__push(char, &buffer, '\0'); | ||||||
|     pkpy_Str retval = { |     py_Str retval = { | ||||||
|         .size = buffer.count - 1, |         .size = buffer.count - 1, | ||||||
|         .is_ascii = self->is_ascii && old->is_ascii && new_->is_ascii, |         .is_ascii = self->is_ascii && old->is_ascii && new_->is_ascii, | ||||||
|         .is_sso = false, |         .is_sso = false, | ||||||
| @ -252,47 +252,47 @@ int c11_string__cmp3(c11_string self, const char *other){ | |||||||
|     return c11_string__cmp2(self, other, strlen(other)); |     return c11_string__cmp2(self, other, strlen(other)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__cmp(const pkpy_Str *self, const pkpy_Str *other){ | int py_Str__cmp(const py_Str *self, const py_Str *other){ | ||||||
|     return pkpy_Str__cmp2(self, pkpy_Str__data(other), other->size); |     return py_Str__cmp2(self, py_Str__data(other), other->size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__cmp2(const pkpy_Str *self, const char *other, int size){ | int py_Str__cmp2(const py_Str *self, const char *other, int size){ | ||||||
|     int res = strncmp(pkpy_Str__data(self), other, PK_MIN(self->size, size)); |     int res = strncmp(py_Str__data(self), other, PK_MIN(self->size, size)); | ||||||
|     if(res != 0) return res; |     if(res != 0) return res; | ||||||
|     return self->size - size; |     return self->size - size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__cmp3(const pkpy_Str *self, const char *other){ | int py_Str__cmp3(const py_Str *self, const char *other){ | ||||||
|     return strcmp(pkpy_Str__data(self), other); |     return strcmp(py_Str__data(self), other); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__u8_getitem(const pkpy_Str *self, int i){ | py_Str py_Str__u8_getitem(const py_Str *self, int i){ | ||||||
|     i = pkpy_Str__unicode_index_to_byte(self, i); |     i = py_Str__unicode_index_to_byte(self, i); | ||||||
|     int size = c11__u8_header(pkpy_Str__data(self)[i], false); |     int size = c11__u8_header(py_Str__data(self)[i], false); | ||||||
|     return pkpy_Str__slice2(self, i, i + size); |     return py_Str__slice2(self, i, i + size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Str__u8_slice(const pkpy_Str *self, int start, int stop, int step){ | py_Str py_Str__u8_slice(const py_Str *self, int start, int stop, int step){ | ||||||
|     c11_vector buffer; |     c11_vector buffer; | ||||||
|     c11_vector__ctor(&buffer, sizeof(char)); |     c11_vector__ctor(&buffer, sizeof(char)); | ||||||
|     assert(step != 0); |     assert(step != 0); | ||||||
|     if(self->is_ascii){ |     if(self->is_ascii){ | ||||||
|         const char* p = pkpy_Str__data(self); |         const char* p = py_Str__data(self); | ||||||
|         for (int i=start; step>0 ? i<stop : i>stop; i+=step) { |         for (int i=start; step>0 ? i<stop : i>stop; i+=step) { | ||||||
|             c11_vector__push(char, &buffer, p[i]); |             c11_vector__push(char, &buffer, p[i]); | ||||||
|         } |         } | ||||||
|     }else{ |     }else{ | ||||||
|         for (int i=start; step>0 ? i<stop : i>stop; i+=step) { |         for (int i=start; step>0 ? i<stop : i>stop; i+=step) { | ||||||
|             pkpy_Str unicode = pkpy_Str__u8_getitem(self, i); |             py_Str unicode = py_Str__u8_getitem(self, i); | ||||||
|             const char* p = pkpy_Str__data(&unicode); |             const char* p = py_Str__data(&unicode); | ||||||
|             for(int j = 0; j < unicode.size; j++){ |             for(int j = 0; j < unicode.size; j++){ | ||||||
|                 c11_vector__push(char, &buffer, p[j]); |                 c11_vector__push(char, &buffer, p[j]); | ||||||
|             } |             } | ||||||
|             pkpy_Str__dtor(&unicode); |             py_Str__dtor(&unicode); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     c11_vector__push(char, &buffer, '\0'); |     c11_vector__push(char, &buffer, '\0'); | ||||||
|     pkpy_Str retval = { |     py_Str retval = { | ||||||
|         .size = buffer.count - 1, |         .size = buffer.count - 1, | ||||||
|         .is_ascii = self->is_ascii, |         .is_ascii = self->is_ascii, | ||||||
|         .is_sso = false, |         .is_sso = false, | ||||||
| @ -301,13 +301,13 @@ pkpy_Str pkpy_Str__u8_slice(const pkpy_Str *self, int start, int stop, int step) | |||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__u8_length(const pkpy_Str *self){ | int py_Str__u8_length(const py_Str *self){ | ||||||
|     return pkpy_Str__byte_index_to_unicode(self, self->size); |     return py_Str__byte_index_to_unicode(self, self->size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__unicode_index_to_byte(const pkpy_Str* self, int i) { | int py_Str__unicode_index_to_byte(const py_Str* self, int i) { | ||||||
|     if(self->is_ascii) return i; |     if(self->is_ascii) return i; | ||||||
|     const char* p = pkpy_Str__data(self); |     const char* p = py_Str__data(self); | ||||||
|     int j = 0; |     int j = 0; | ||||||
|     while(i > 0) { |     while(i > 0) { | ||||||
|         j += c11__u8_header(p[j], false); |         j += c11__u8_header(p[j], false); | ||||||
| @ -316,9 +316,9 @@ int pkpy_Str__unicode_index_to_byte(const pkpy_Str* self, int i) { | |||||||
|     return j; |     return j; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__byte_index_to_unicode(const pkpy_Str* self, int n) { | int py_Str__byte_index_to_unicode(const py_Str* self, int n) { | ||||||
|     if(self->is_ascii) return n; |     if(self->is_ascii) return n; | ||||||
|     const char* p = pkpy_Str__data(self); |     const char* p = py_Str__data(self); | ||||||
|     int cnt = 0; |     int cnt = 0; | ||||||
|     for(int i = 0; i < n; i++) { |     for(int i = 0; i < n; i++) { | ||||||
|         if((p[i] & 0xC0) != 0x80) cnt++; |         if((p[i] & 0xC0) != 0x80) cnt++; | ||||||
| @ -326,11 +326,11 @@ int pkpy_Str__byte_index_to_unicode(const pkpy_Str* self, int n) { | |||||||
|     return cnt; |     return cnt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__index(const pkpy_Str *self, const pkpy_Str *sub, int start){ | int py_Str__index(const py_Str *self, const py_Str *sub, int start){ | ||||||
|     if(sub->size == 0) return start; |     if(sub->size == 0) return start; | ||||||
|     int max_end = self->size - sub->size; |     int max_end = self->size - sub->size; | ||||||
|     const char* self_data = pkpy_Str__data(self); |     const char* self_data = py_Str__data(self); | ||||||
|     const char* sub_data = pkpy_Str__data(sub); |     const char* sub_data = py_Str__data(sub); | ||||||
|     for(int i=start; i<=max_end; i++){ |     for(int i=start; i<=max_end; i++){ | ||||||
|         int res = memcmp(self_data + i, sub_data, sub->size); |         int res = memcmp(self_data + i, sub_data, sub->size); | ||||||
|         if(res == 0) return i; |         if(res == 0) return i; | ||||||
| @ -338,12 +338,12 @@ int pkpy_Str__index(const pkpy_Str *self, const pkpy_Str *sub, int start){ | |||||||
|     return -1; |     return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int pkpy_Str__count(const pkpy_Str *self, const pkpy_Str *sub){ | int py_Str__count(const py_Str *self, const py_Str *sub){ | ||||||
|     if(sub->size == 0) return self->size + 1; |     if(sub->size == 0) return self->size + 1; | ||||||
|     int cnt = 0; |     int cnt = 0; | ||||||
|     int start = 0; |     int start = 0; | ||||||
|     while(true) { |     while(true) { | ||||||
|         int i = pkpy_Str__index(self, sub, start); |         int i = py_Str__index(self, sub, start); | ||||||
|         if(i == -1) break; |         if(i == -1) break; | ||||||
|         cnt++; |         cnt++; | ||||||
|         start = i + sub->size; |         start = i + sub->size; | ||||||
| @ -351,10 +351,10 @@ int pkpy_Str__count(const pkpy_Str *self, const pkpy_Str *sub){ | |||||||
|     return cnt; |     return cnt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| c11_vector/* T=c11_string */ pkpy_Str__split(const pkpy_Str *self, char sep){ | c11_vector/* T=c11_string */ py_Str__split(const py_Str *self, char sep){ | ||||||
|     c11_vector retval; |     c11_vector retval; | ||||||
|     c11_vector__ctor(&retval, sizeof(c11_string)); |     c11_vector__ctor(&retval, sizeof(c11_string)); | ||||||
|     const char* data = pkpy_Str__data(self); |     const char* data = py_Str__data(self); | ||||||
|     int i = 0; |     int i = 0; | ||||||
|     for(int j = 0; j < self->size; j++) { |     for(int j = 0; j < self->size; j++) { | ||||||
|         if(data[j] == sep) { |         if(data[j] == sep) { | ||||||
| @ -373,13 +373,13 @@ c11_vector/* T=c11_string */ pkpy_Str__split(const pkpy_Str *self, char sep){ | |||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| c11_vector/* T=c11_string */ pkpy_Str__split2(const pkpy_Str *self, const pkpy_Str *sep){ | c11_vector/* T=c11_string */ py_Str__split2(const py_Str *self, const py_Str *sep){ | ||||||
|     c11_vector retval; |     c11_vector retval; | ||||||
|     c11_vector__ctor(&retval, sizeof(c11_string)); |     c11_vector__ctor(&retval, sizeof(c11_string)); | ||||||
|     int start = 0; |     int start = 0; | ||||||
|     const char* data = pkpy_Str__data(self); |     const char* data = py_Str__data(self); | ||||||
|     while(true) { |     while(true) { | ||||||
|         int i = pkpy_Str__index(self, sep, start); |         int i = py_Str__index(self, sep, start); | ||||||
|         if(i == -1) break; |         if(i == -1) break; | ||||||
|         c11_string tmp = {data + start, i - start}; |         c11_string tmp = {data + start, i - start}; | ||||||
|         if(tmp.size != 0) c11_vector__push(c11_string, &retval, tmp); |         if(tmp.size != 0) c11_vector__push(c11_string, &retval, tmp); | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ NameScope Compiler::name_scope() const noexcept{ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CodeObject* Compiler::push_global_context() noexcept{ | CodeObject* Compiler::push_global_context() noexcept{ | ||||||
|     CodeObject* co = CodeObject__new(lexer.src, pkpy_Str__sv(&lexer.src->filename)); |     CodeObject* co = CodeObject__new(lexer.src, py_Str__sv(&lexer.src->filename)); | ||||||
|     co->start_line = __i == 0 ? 1 : prev().line; |     co->start_line = __i == 0 ? 1 : prev().line; | ||||||
|     contexts.push_back(CodeEmitContext(vm, co, contexts.size())); |     contexts.push_back(CodeEmitContext(vm, co, contexts.size())); | ||||||
|     return co; |     return co; | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c) | |||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c){ | py_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c){ | ||||||
|     c11_string sv = pk_TokenDeserializer__read_string(self, c); |     c11_string sv = pk_TokenDeserializer__read_string(self, c); | ||||||
|     const char* s = sv.data; |     const char* s = sv.data; | ||||||
|     char* buffer = (char*)malloc(sv.size / 2 + 1); |     char* buffer = (char*)malloc(sv.size / 2 + 1); | ||||||
| @ -71,7 +71,7 @@ pkpy_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, | |||||||
|         buffer[i / 2] = c; |         buffer[i / 2] = c; | ||||||
|     } |     } | ||||||
|     buffer[sv.size / 2] = 0; |     buffer[sv.size / 2] = 0; | ||||||
|     return (pkpy_Str){ |     return (py_Str){ | ||||||
|         .size = sv.size / 2, |         .size = sv.size / 2, | ||||||
|         .is_ascii = c11__isascii(buffer, sv.size / 2), |         .is_ascii = c11__isascii(buffer, sv.size / 2), | ||||||
|         .is_sso = false, |         .is_sso = false, | ||||||
| @ -97,11 +97,11 @@ int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c){ | |||||||
| 
 | 
 | ||||||
| double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c){ | double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c){ | ||||||
|     c11_string sv = pk_TokenDeserializer__read_string(self, c); |     c11_string sv = pk_TokenDeserializer__read_string(self, c); | ||||||
|     pkpy_Str nullterm; |     py_Str nullterm; | ||||||
|     pkpy_Str__ctor2(&nullterm, sv.data, sv.size); |     py_Str__ctor2(&nullterm, sv.data, sv.size); | ||||||
|     char* end; |     char* end; | ||||||
|     double retval = strtod(pkpy_Str__data(&nullterm), &end); |     double retval = strtod(py_Str__data(&nullterm), &end); | ||||||
|     pkpy_Str__dtor(&nullterm); |     py_Str__dtor(&nullterm); | ||||||
|     assert(*end == 0); |     assert(*end == 0); | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
|  | |||||||
| @ -534,7 +534,7 @@ Error* Lexer::run() noexcept{ | |||||||
| 
 | 
 | ||||||
| Error* Lexer::from_precompiled() noexcept{ | Error* Lexer::from_precompiled() noexcept{ | ||||||
|     pk_TokenDeserializer deserializer; |     pk_TokenDeserializer deserializer; | ||||||
|     pk_TokenDeserializer__ctor(&deserializer, pkpy_Str__data(&src->source)); |     pk_TokenDeserializer__ctor(&deserializer, py_Str__data(&src->source)); | ||||||
| 
 | 
 | ||||||
|     deserializer.curr += 5;  // skip "pkpy:"
 |     deserializer.curr += 5;  // skip "pkpy:"
 | ||||||
|     c11_string version = pk_TokenDeserializer__read_string(&deserializer, '\n'); |     c11_string version = pk_TokenDeserializer__read_string(&deserializer, '\n'); | ||||||
| @ -550,9 +550,9 @@ Error* Lexer::from_precompiled() noexcept{ | |||||||
|     c11_vector* precompiled_tokens = &src->_precompiled_tokens; |     c11_vector* precompiled_tokens = &src->_precompiled_tokens; | ||||||
|     for(int i = 0; i < count; i++) { |     for(int i = 0; i < count; i++) { | ||||||
|         c11_string item = pk_TokenDeserializer__read_string(&deserializer, '\n'); |         c11_string item = pk_TokenDeserializer__read_string(&deserializer, '\n'); | ||||||
|         pkpy_Str copied_item; |         py_Str copied_item; | ||||||
|         pkpy_Str__ctor2(&copied_item, item.data, item.size); |         py_Str__ctor2(&copied_item, item.data, item.size); | ||||||
|         c11_vector__push(pkpy_Str, precompiled_tokens, copied_item); |         c11_vector__push(py_Str, precompiled_tokens, copied_item); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     count = pk_TokenDeserializer__read_count(&deserializer); |     count = pk_TokenDeserializer__read_count(&deserializer); | ||||||
| @ -561,9 +561,9 @@ Error* Lexer::from_precompiled() noexcept{ | |||||||
|         t.type = (TokenIndex)pk_TokenDeserializer__read_uint(&deserializer, ','); |         t.type = (TokenIndex)pk_TokenDeserializer__read_uint(&deserializer, ','); | ||||||
|         if(is_raw_string_used(t.type)) { |         if(is_raw_string_used(t.type)) { | ||||||
|             i64 index = pk_TokenDeserializer__read_uint(&deserializer, ','); |             i64 index = pk_TokenDeserializer__read_uint(&deserializer, ','); | ||||||
|             pkpy_Str* p = c11__at(pkpy_Str, precompiled_tokens, index); |             py_Str* p = c11__at(py_Str, precompiled_tokens, index); | ||||||
|             t.start = pkpy_Str__data(p); |             t.start = py_Str__data(p); | ||||||
|             t.length = c11__getitem(pkpy_Str, precompiled_tokens, index).size; |             t.length = c11__getitem(py_Str, precompiled_tokens, index).size; | ||||||
|         } else { |         } else { | ||||||
|             t.start = NULL; |             t.start = NULL; | ||||||
|             t.length = 0; |             t.length = 0; | ||||||
| @ -590,7 +590,7 @@ Error* Lexer::from_precompiled() noexcept{ | |||||||
|                 t.value = pk_TokenDeserializer__read_float(&deserializer, '\n'); |                 t.value = pk_TokenDeserializer__read_float(&deserializer, '\n'); | ||||||
|                 break; |                 break; | ||||||
|             case 'S': { |             case 'S': { | ||||||
|                 pkpy_Str res = pk_TokenDeserializer__read_string_from_hex(&deserializer, '\n'); |                 py_Str res = pk_TokenDeserializer__read_string_from_hex(&deserializer, '\n'); | ||||||
|                 t.value = Str(std::move(res)); |                 t.value = Str(std::move(res)); | ||||||
|             } break; |             } break; | ||||||
|             default: |             default: | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								src/error.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/error.c
									
									
									
									
									
								
							| @ -9,7 +9,7 @@ void pkpy_Exception__ctor(pkpy_Exception* self, StrName type){ | |||||||
|     self->_code_on_error = NULL; |     self->_code_on_error = NULL; | ||||||
|     self->self = NULL; |     self->self = NULL; | ||||||
| 
 | 
 | ||||||
|     pkpy_Str__ctor(&self->msg, ""); |     py_Str__ctor(&self->msg, ""); | ||||||
|     c11_vector__ctor(&self->stacktrace, sizeof(pkpy_ExceptionFrame)); |     c11_vector__ctor(&self->stacktrace, sizeof(pkpy_ExceptionFrame)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -17,9 +17,9 @@ void pkpy_Exception__dtor(pkpy_Exception* self){ | |||||||
|     for(int i=0; i<self->stacktrace.count; i++){ |     for(int i=0; i<self->stacktrace.count; i++){ | ||||||
|         pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i); |         pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i); | ||||||
|         PK_DECREF(frame->src); |         PK_DECREF(frame->src); | ||||||
|         pkpy_Str__dtor(&frame->name); |         py_Str__dtor(&frame->name); | ||||||
|     } |     } | ||||||
|     pkpy_Str__dtor(&self->msg); |     py_Str__dtor(&self->msg); | ||||||
|     c11_vector__dtor(&self->stacktrace); |     c11_vector__dtor(&self->stacktrace); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -30,10 +30,10 @@ void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int line | |||||||
|     frame->src = src; |     frame->src = src; | ||||||
|     frame->lineno = lineno; |     frame->lineno = lineno; | ||||||
|     frame->cursor = cursor; |     frame->cursor = cursor; | ||||||
|     pkpy_Str__ctor(&frame->name, name); |     py_Str__ctor(&frame->name, name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pkpy_Str pkpy_Exception__summary(pkpy_Exception* self){ | py_Str pkpy_Exception__summary(pkpy_Exception* self){ | ||||||
|     pk_SStream ss; |     pk_SStream ss; | ||||||
|     pk_SStream__ctor(&ss); |     pk_SStream__ctor(&ss); | ||||||
| 
 | 
 | ||||||
| @ -42,9 +42,9 @@ pkpy_Str pkpy_Exception__summary(pkpy_Exception* self){ | |||||||
|     } |     } | ||||||
|     for(int i=self->stacktrace.count-1; i >= 0; i--) { |     for(int i=self->stacktrace.count-1; i >= 0; i--) { | ||||||
|         pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i); |         pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i); | ||||||
|         pkpy_Str s = pkpy_SourceData__snapshot(frame->src, frame->lineno, frame->cursor, pkpy_Str__data(&frame->name)); |         py_Str s = pkpy_SourceData__snapshot(frame->src, frame->lineno, frame->cursor, py_Str__data(&frame->name)); | ||||||
|         pk_SStream__write_Str(&ss, &s); |         pk_SStream__write_Str(&ss, &s); | ||||||
|         pkpy_Str__dtor(&s); |         py_Str__dtor(&s); | ||||||
|         pk_SStream__write_cstr(&ss, "\n"); |         pk_SStream__write_cstr(&ss, "\n"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -192,7 +192,7 @@ | |||||||
| //                         if(decl->nested) {
 | //                         if(decl->nested) {
 | ||||||
| //                             NameDict* captured = frame->_locals.to_namedict();
 | //                             NameDict* captured = frame->_locals.to_namedict();
 | ||||||
| //                             obj = new_object<Function>(tp_function, decl, frame->_module, nullptr, captured);
 | //                             obj = new_object<Function>(tp_function, decl, frame->_module, nullptr, captured);
 | ||||||
| //                             uint16_t name = pk_StrName__map2(pkpy_Str__sv(&decl->code->name));
 | //                             uint16_t name = pk_StrName__map2(py_Str__sv(&decl->code->name));
 | ||||||
| //                             captured->set(name, obj);
 | //                             captured->set(name, obj);
 | ||||||
| //                         } else {
 | //                         } else {
 | ||||||
| //                             obj = new_object<Function>(tp_function, decl, frame->_module, nullptr, nullptr);
 | //                             obj = new_object<Function>(tp_function, decl, frame->_module, nullptr, nullptr);
 | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ void ValueStack__clear(ValueStack* self) { | |||||||
|     self->sp = self->begin; |     self->sp = self->begin; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyVar* FastLocals__try_get_by_name(PyVar* locals, const CodeObject* co, StrName name){ | PyVar* FastLocals__try_get_by_name(PyVar* locals, const CodeObject* co, py_Name name){ | ||||||
|     int index = c11_smallmap_n2i__get(&co->varnames_inv, name, -1); |     int index = c11_smallmap_n2i__get(&co->varnames_inv, name, -1); | ||||||
|     if(index == -1) return NULL; |     if(index == -1) return NULL; | ||||||
|     return &locals[index]; |     return &locals[index]; | ||||||
| @ -39,14 +39,14 @@ void UnwindTarget__delete(UnwindTarget* self){ | |||||||
|     free(self); |     free(self); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Frame* Frame__new(const CodeObject* co, PyObject* module, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co){ | Frame* Frame__new(const CodeObject* co, const PyVar* module, const PyVar* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co){ | ||||||
|     static_assert(sizeof(Frame) <= kPoolFrameBlockSize, "!(sizeof(Frame) <= kPoolFrameBlockSize)"); |     static_assert(sizeof(Frame) <= kPoolFrameBlockSize, "!(sizeof(Frame) <= kPoolFrameBlockSize)"); | ||||||
|     Frame* self = PoolFrame_alloc(); |     Frame* self = PoolFrame_alloc(); | ||||||
|     self->f_back = NULL; |     self->f_back = NULL; | ||||||
|     self->ip = (Bytecode*)co->codes.data - 1; |     self->ip = (Bytecode*)co->codes.data - 1; | ||||||
|     self->co = co; |     self->co = co; | ||||||
|     self->module = module; |     self->module = module->_obj; | ||||||
|     self->function = function; |     self->function = function->_obj; | ||||||
|     self->p0 = p0; |     self->p0 = p0; | ||||||
|     self->locals = locals; |     self->locals = locals; | ||||||
|     self->locals_co = locals_co; |     self->locals_co = locals_co; | ||||||
|  | |||||||
| @ -88,21 +88,23 @@ int pk_ManagedHeap__sweep(pk_ManagedHeap *self){ | |||||||
|     return freed; |     return freed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyObject* pk_ManagedHeap__new(pk_ManagedHeap *self, Type type, int size){ | PyObject* pk_ManagedHeap__new(pk_ManagedHeap *self, Type type, int slots, int size){ | ||||||
|     PyObject* obj = PyObject__new(type, size); |     PyObject* obj = PyObject__new(type, slots, size); | ||||||
|     c11_vector__push(PyObject*, &self->no_gc, obj); |     c11_vector__push(PyObject*, &self->no_gc, obj); | ||||||
|     return obj; |     return obj; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyObject* pk_ManagedHeap__gcnew(pk_ManagedHeap *self, Type type, int size){ | PyObject* pk_ManagedHeap__gcnew(pk_ManagedHeap *self, Type type, int slots, int size){ | ||||||
|     PyObject* obj = PyObject__new(type, size); |     PyObject* obj = PyObject__new(type, slots, size); | ||||||
|     c11_vector__push(PyObject*, &self->gen, obj); |     c11_vector__push(PyObject*, &self->gen, obj); | ||||||
|     self->gc_counter++; |     self->gc_counter++; | ||||||
|     return obj; |     return obj; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PyObject* PyObject__new(Type type, int size){ | PyObject* PyObject__new(Type type, int slots, int size){ | ||||||
|  |     assert(slots >= 0 || slots == -1); | ||||||
|     PyObject* self; |     PyObject* self; | ||||||
|  |     size += PK_OBJ_HEADER_SIZE(slots); | ||||||
|     if(size <= kPoolObjectBlockSize){ |     if(size <= kPoolObjectBlockSize){ | ||||||
|         self = PoolObject_alloc(); |         self = PoolObject_alloc(); | ||||||
|         self->gc_is_large = false; |         self->gc_is_large = false; | ||||||
| @ -112,6 +114,6 @@ PyObject* PyObject__new(Type type, int size){ | |||||||
|     } |     } | ||||||
|     self->type = type; |     self->type = type; | ||||||
|     self->gc_marked = false; |     self->gc_marked = false; | ||||||
|     self->dict = NULL; |     self->slots = slots; | ||||||
|     return self; |     return self; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| #include "pocketpy/interpreter/vm.h" | #include "pocketpy/interpreter/vm.h" | ||||||
| #include "pocketpy/common/memorypool.h" | #include "pocketpy/common/memorypool.h" | ||||||
|  | #include "pocketpy/common/sstream.h" | ||||||
|  | #include "pocketpy/pocketpy.h" | ||||||
| 
 | 
 | ||||||
| static unsigned char* pk_default_import_file(const char* path){ | static unsigned char* pk_default_import_file(const char* path){ | ||||||
|     return NULL; |     return NULL; | ||||||
| @ -15,7 +17,7 @@ static void pk_default_stderr(const char* s){ | |||||||
|     fflush(stderr); |     fflush(stderr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_TypeInfo__ctor(pk_TypeInfo *self, StrName name, Type base, PyObject* obj, const PyVar* module, bool subclass_enabled){ | void pk_TypeInfo__ctor(pk_TypeInfo *self, py_Name name, Type base, PyObject* obj, const PyVar* module, bool subclass_enabled){ | ||||||
|     memset(self, 0, sizeof(pk_TypeInfo)); |     memset(self, 0, sizeof(pk_TypeInfo)); | ||||||
|      |      | ||||||
|     self->name = name; |     self->name = name; | ||||||
| @ -25,22 +27,57 @@ void pk_TypeInfo__ctor(pk_TypeInfo *self, StrName name, Type base, PyObject* obj | |||||||
|     self->module = module ? *module : PY_NULL; |     self->module = module ? *module : PY_NULL; | ||||||
|     self->subclass_enabled = subclass_enabled; |     self->subclass_enabled = subclass_enabled; | ||||||
| 
 | 
 | ||||||
|     c11_vector__ctor(&self->annotated_fields, sizeof(StrName)); |     c11_vector__ctor(&self->annotated_fields, sizeof(py_Name)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_TypeInfo__dtor(pk_TypeInfo *self){ | void pk_TypeInfo__dtor(pk_TypeInfo *self){ | ||||||
|     c11_vector__dtor(&self->annotated_fields); |     c11_vector__dtor(&self->annotated_fields); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int _hello(const PyVar* args, int argc){ | // static int _py_print(const py_Ref args, int argc){
 | ||||||
|     return 0; | //     int length = py_tuple__len(args+0);
 | ||||||
| } | //     py_Str* sep;
 | ||||||
|  | //     py_Str* end;
 | ||||||
|  | 
 | ||||||
|  | //     int err;
 | ||||||
|  | //     err = py_tostr(args+1, &sep);
 | ||||||
|  | //     if(err) return err;
 | ||||||
|  | //     err = py_tostr(args+2, &end);
 | ||||||
|  | //     if(err) return err;
 | ||||||
|  | 
 | ||||||
|  | //     pk_SStream ss;
 | ||||||
|  | //     pk_SStream__ctor(&ss);
 | ||||||
|  | 
 | ||||||
|  | //     for(int i=0; i<length; i++){
 | ||||||
|  | //         const py_Ref item = py_tuple__getitem(args+0, i);
 | ||||||
|  | //         py_Str tmp;
 | ||||||
|  | //         int err = py_str(item, &tmp);
 | ||||||
|  | //         if(!err){
 | ||||||
|  | //             pk_SStream__write_Str(&ss, &tmp);
 | ||||||
|  | //             py_Str__dtor(&tmp);
 | ||||||
|  | //             if(i != length-1){
 | ||||||
|  | //                 pk_SStream__write_Str(&ss, sep);
 | ||||||
|  | //             }
 | ||||||
|  | //         }else{
 | ||||||
|  | //             py_Str__dtor(&tmp);
 | ||||||
|  | //             pk_SStream__dtor(&ss);
 | ||||||
|  | //             return err;
 | ||||||
|  | //         }
 | ||||||
|  | //     }
 | ||||||
|  | //     pk_SStream__write_Str(&ss, end);
 | ||||||
|  | //     py_Str out = pk_SStream__submit(&ss);
 | ||||||
|  | //     pk_current_vm->_stdout(py_Str__data(&out));
 | ||||||
|  | //     py_Str__dtor(&out);
 | ||||||
|  | //     return 0;
 | ||||||
|  | // }
 | ||||||
| 
 | 
 | ||||||
| static void do_builtin_bindings(){ | static void do_builtin_bindings(){ | ||||||
|     pk_VM* vm = pk_current_vm; |     // py_Ref builtins = py_getmodule("builtins");
 | ||||||
| 
 |     // py_newfunction(py_reg(0), _py_print,
 | ||||||
|     py_new_nativefunc(&vm->reg[0], _hello, 2, BindType_FUNCTION); |     //     "print(*args, sep=' ', end='\\n')",
 | ||||||
|     py_setattr(&vm->builtins, pk_StrName__map("hello"), &vm->reg[0]); |     //     BindType_FUNCTION
 | ||||||
|  |     // );
 | ||||||
|  |     // py_setdict(builtins, py_name("hello"), py_reg(0));
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_VM__ctor(pk_VM* self){ | void pk_VM__ctor(pk_VM* self){ | ||||||
| @ -69,19 +106,19 @@ void pk_VM__ctor(pk_VM* self){ | |||||||
|     ValueStack__ctor(&self->stack); |     ValueStack__ctor(&self->stack); | ||||||
| 
 | 
 | ||||||
|     self->True = (PyVar){.type=tp_bool, .is_ptr=true, .extra=1, |     self->True = (PyVar){.type=tp_bool, .is_ptr=true, .extra=1, | ||||||
|         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 1), |         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1), | ||||||
|     }; |     }; | ||||||
|     self->False = (PyVar){.type=tp_bool, .is_ptr=true, .extra=0, |     self->False = (PyVar){.type=tp_bool, .is_ptr=true, .extra=0, | ||||||
|         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 1), |         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_bool, 0, 1), | ||||||
|     }; |     }; | ||||||
|     self->None = (PyVar){.type=tp_none_type, .is_ptr=true, |     self->None = (PyVar){.type=tp_none_type, .is_ptr=true, | ||||||
|         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 1), |         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_none_type, 0, 1), | ||||||
|     }; |     }; | ||||||
|     self->NotImplemented = (PyVar){.type=tp_not_implemented_type, .is_ptr=true, |     self->NotImplemented = (PyVar){.type=tp_not_implemented_type, .is_ptr=true, | ||||||
|         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 1), |         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_not_implemented_type, 0, 1), | ||||||
|     }; |     }; | ||||||
|     self->Ellipsis = (PyVar){.type=tp_ellipsis, .is_ptr=true, |     self->Ellipsis = (PyVar){.type=tp_ellipsis, .is_ptr=true, | ||||||
|         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 1), |         ._obj=pk_ManagedHeap__gcnew(&self->heap, tp_ellipsis, 0, 1), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /* Init Builtin Types */ |     /* Init Builtin Types */ | ||||||
| @ -132,7 +169,7 @@ void pk_VM__ctor(pk_VM* self){ | |||||||
|     #undef validate |     #undef validate | ||||||
| 
 | 
 | ||||||
|     self->StopIteration = c11__at(pk_TypeInfo, &self->types, tp_stop_iteration)->self; |     self->StopIteration = c11__at(pk_TypeInfo, &self->types, tp_stop_iteration)->self; | ||||||
|     self->builtins = py_new_module("builtins"); |     self->builtins = *py_newmodule("builtins", NULL); | ||||||
|      |      | ||||||
|     /* Setup Public Builtin Types */ |     /* Setup Public Builtin Types */ | ||||||
|     Type public_types[] = { |     Type public_types[] = { | ||||||
| @ -147,13 +184,13 @@ void pk_VM__ctor(pk_VM* self){ | |||||||
|     for(int i=0; i<PK_ARRAY_COUNT(public_types); i++){ |     for(int i=0; i<PK_ARRAY_COUNT(public_types); i++){ | ||||||
|         Type t = public_types[i]; |         Type t = public_types[i]; | ||||||
|         pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t); |         pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, t); | ||||||
|         pk_NameDict__set(self->builtins._obj->dict, ti->name, ti->self); |         py_setdict(&self->builtins, ti->name, &ti->self); | ||||||
|     } |     } | ||||||
|     pk_NameDict__set(self->builtins._obj->dict, pk_StrName__map("NotImplemented"), self->NotImplemented); |     py_setdict(&self->builtins, py_name("NotImplemented"), &self->NotImplemented); | ||||||
| 
 | 
 | ||||||
|     /* Do Buildin Bindings*/ |     /* Do Buildin Bindings*/ | ||||||
|     do_builtin_bindings(); |     do_builtin_bindings(); | ||||||
|     self->main = py_new_module("__main__"); |     self->main = *py_newmodule("__main__", NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pk_VM__dtor(pk_VM* self){ | void pk_VM__dtor(pk_VM* self){ | ||||||
| @ -186,17 +223,18 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self){ | |||||||
| Type pk_VM__new_type(pk_VM* self, const char* name, Type base, const PyVar* module, bool subclass_enabled){ | Type pk_VM__new_type(pk_VM* self, const char* name, Type base, const PyVar* module, bool subclass_enabled){ | ||||||
|     Type type = self->types.count; |     Type type = self->types.count; | ||||||
|     pk_TypeInfo* ti = c11_vector__emplace(&self->types); |     pk_TypeInfo* ti = c11_vector__emplace(&self->types); | ||||||
|     PyObject* typeobj = pk_ManagedHeap__gcnew(&self->heap, tp_type, PK_OBJ_SIZEOF(Type)); |     PyObject* typeobj = pk_ManagedHeap__gcnew(&self->heap, tp_type, 0, sizeof(Type)); | ||||||
|     *PyObject__as(Type, typeobj) = type; |     Type* value = PyObject__value(typeobj); | ||||||
|     pk_TypeInfo__ctor(ti, pk_StrName__map(name), base, typeobj, module, subclass_enabled); |     *value = type; | ||||||
|  |     pk_TypeInfo__ctor(ti, py_name(name), base, typeobj, module, subclass_enabled); | ||||||
|     return type; |     return type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /****************************************/ | /****************************************/ | ||||||
| void PyObject__delete(PyObject *self){ | void PyObject__delete(PyObject *self){ | ||||||
|     pk_TypeInfo* ti = c11__getitem(pk_TypeInfo*, &pk_current_vm->types, self->type); |     pk_TypeInfo* ti = c11__getitem(pk_TypeInfo*, &pk_current_vm->types, self->type); | ||||||
|     if(ti->dtor) ti->dtor(PyObject__value_ptr(self)); |     if(ti->dtor) ti->dtor(PyObject__value(self)); | ||||||
|     if(self->dict) pk_NameDict__delete(self->dict); |     if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self)); | ||||||
|     if(self->gc_is_large){ |     if(self->gc_is_large){ | ||||||
|         free(self); |         free(self); | ||||||
|     }else{ |     }else{ | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ void FuncDecl__add_kwarg(FuncDecl* self, int index, uint16_t key, const PyVar* v | |||||||
| CodeObject* CodeObject__new(pkpy_SourceData_ src, c11_string name){ | CodeObject* CodeObject__new(pkpy_SourceData_ src, c11_string name){ | ||||||
|     CodeObject* self = malloc(sizeof(CodeObject)); |     CodeObject* self = malloc(sizeof(CodeObject)); | ||||||
|     self->src = src; PK_INCREF(src); |     self->src = src; PK_INCREF(src); | ||||||
|     pkpy_Str__ctor2(&self->name, name.data, name.size); |     py_Str__ctor2(&self->name, name.data, name.size); | ||||||
| 
 | 
 | ||||||
|     c11_vector__ctor(&self->codes, sizeof(Bytecode)); |     c11_vector__ctor(&self->codes, sizeof(Bytecode)); | ||||||
|     c11_vector__ctor(&self->codes_ex, sizeof(BytecodeEx)); |     c11_vector__ctor(&self->codes_ex, sizeof(BytecodeEx)); | ||||||
| @ -74,7 +74,7 @@ CodeObject* CodeObject__new(pkpy_SourceData_ src, c11_string name){ | |||||||
| 
 | 
 | ||||||
| void CodeObject__delete(CodeObject* self){ | void CodeObject__delete(CodeObject* self){ | ||||||
|     PK_DECREF(self->src); |     PK_DECREF(self->src); | ||||||
|     pkpy_Str__dtor(&self->name); |     py_Str__dtor(&self->name); | ||||||
|      |      | ||||||
|     c11_vector__dtor(&self->codes); |     c11_vector__dtor(&self->codes); | ||||||
|     c11_vector__dtor(&self->codes_ex); |     c11_vector__dtor(&self->codes_ex); | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include "pocketpy/objects/dict.h" | #include "pocketpy/objects/dict.h" | ||||||
| #include "pocketpy/common/utils.h" | #include "pocketpy/common/utils.h" | ||||||
|  | #include <stdint.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @ -113,14 +114,18 @@ static void pkpy_Dict__extendht(pkpy_Dict* self) { | |||||||
|         struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, i); |         struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, i); | ||||||
|         if(pkpy_Var__is_null(&entry->key)) continue; |         if(pkpy_Var__is_null(&entry->key)) continue; | ||||||
| 
 | 
 | ||||||
|         int rhash = DICT_HASH_TRANS(py_hash(&entry->key)); |         int64_t out; | ||||||
|  |         int err = py_hash(&entry->key, &out); | ||||||
|  |         int rhash = DICT_HASH_TRANS(out); | ||||||
|         int h = pkpy_Dict__probe0(self, entry->key, rhash); |         int h = pkpy_Dict__probe0(self, entry->key, rhash); | ||||||
|         pkpy_Dict__htset(self, h, i); |         pkpy_Dict__htset(self, h, i); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool pkpy_Dict__set(pkpy_Dict* self, PyVar key, PyVar val) { | bool pkpy_Dict__set(pkpy_Dict* self, PyVar key, PyVar val) { | ||||||
|     int hash = DICT_HASH_TRANS(py_hash(&key)); |     int64_t out; | ||||||
|  |     int err = py_hash(&key, &out); | ||||||
|  |     int hash = DICT_HASH_TRANS(out); | ||||||
|     int h = pkpy_Dict__probe1(self, key, hash); |     int h = pkpy_Dict__probe1(self, key, hash); | ||||||
| 
 | 
 | ||||||
|     int idx = pkpy_Dict__htget(self, h); |     int idx = pkpy_Dict__htget(self, h); | ||||||
| @ -155,7 +160,9 @@ bool pkpy_Dict__set(pkpy_Dict* self, PyVar key, PyVar val) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool pkpy_Dict__contains(const pkpy_Dict* self, PyVar key) { | bool pkpy_Dict__contains(const pkpy_Dict* self, PyVar key) { | ||||||
|     int hash = DICT_HASH_TRANS(py_hash(&key)); |     int64_t out; | ||||||
|  |     int err = py_hash(&key, &out); | ||||||
|  |     int hash = DICT_HASH_TRANS(out); | ||||||
|     int h = pkpy_Dict__probe1(self, key, hash); |     int h = pkpy_Dict__probe1(self, key, hash); | ||||||
| 
 | 
 | ||||||
|     int idx = pkpy_Dict__htget(self, h); |     int idx = pkpy_Dict__htget(self, h); | ||||||
| @ -187,7 +194,9 @@ static bool pkpy_Dict__refactor(pkpy_Dict* self) { | |||||||
|         struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, i); |         struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_entries, i); | ||||||
|         if(pkpy_Var__is_null(&entry->key)) continue; |         if(pkpy_Var__is_null(&entry->key)) continue; | ||||||
| 
 | 
 | ||||||
|         int rhash = DICT_HASH_TRANS(py_hash(&entry->key)); |         int64_t out; | ||||||
|  |         py_hash(&entry->key, &out); | ||||||
|  |         int rhash = DICT_HASH_TRANS(out); | ||||||
|         int h = pkpy_Dict__probe0(self, entry->key, rhash); |         int h = pkpy_Dict__probe0(self, entry->key, rhash); | ||||||
|         pkpy_Dict__htset(self, h, i); |         pkpy_Dict__htset(self, h, i); | ||||||
|     } |     } | ||||||
| @ -195,7 +204,9 @@ static bool pkpy_Dict__refactor(pkpy_Dict* self) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool pkpy_Dict__del(pkpy_Dict* self, PyVar key) { | bool pkpy_Dict__del(pkpy_Dict* self, PyVar key) { | ||||||
|     int hash = DICT_HASH_TRANS(py_hash(&key)); |     int64_t out; | ||||||
|  |     int err = py_hash(&key, &out); | ||||||
|  |     int hash = DICT_HASH_TRANS(out); | ||||||
|     int h = pkpy_Dict__probe1(self, key, hash); |     int h = pkpy_Dict__probe1(self, key, hash); | ||||||
|     int idx = pkpy_Dict__htget(self, h), null = pkpy_Dict__idx_null(self); |     int idx = pkpy_Dict__htget(self, h), null = pkpy_Dict__idx_null(self); | ||||||
|     if(idx == null) return false; |     if(idx == null) return false; | ||||||
| @ -208,7 +219,9 @@ bool pkpy_Dict__del(pkpy_Dict* self, PyVar key) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const PyVar *pkpy_Dict__try_get(const pkpy_Dict* self, PyVar key) { | const PyVar *pkpy_Dict__try_get(const pkpy_Dict* self, PyVar key) { | ||||||
|     int hash = DICT_HASH_TRANS(py_hash(&key)); |     int64_t out; | ||||||
|  |     int err = py_hash(&key, &out); | ||||||
|  |     int hash = DICT_HASH_TRANS(out); | ||||||
|     int h = pkpy_Dict__probe1(self, key, hash); |     int h = pkpy_Dict__probe1(self, key, hash); | ||||||
|      |      | ||||||
|     int idx = pkpy_Dict__htget(self, h); |     int idx = pkpy_Dict__htget(self, h); | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| #include "pocketpy/objects/object.h" | #include "pocketpy/objects/object.h" | ||||||
|  | #include "pocketpy/pocketpy.h" | ||||||
|  | #include <assert.h> | ||||||
| 
 | 
 | ||||||
| void PyVar__ctor3(PyVar* self, PyObject* existing){ | void PyVar__ctor3(PyVar* self, PyObject* existing){ | ||||||
|     assert(existing); |     assert(existing); | ||||||
| @ -6,3 +8,17 @@ void PyVar__ctor3(PyVar* self, PyObject* existing){ | |||||||
|     self->is_ptr = true; |     self->is_ptr = true; | ||||||
|     self->_obj = existing; |     self->_obj = existing; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void* PyObject__value(PyObject* self){ | ||||||
|  |     return (char*)self + PK_OBJ_HEADER_SIZE(self->slots); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pk_NameDict* PyObject__dict(PyObject* self){ | ||||||
|  |     assert(self->slots == -1); | ||||||
|  |     return (pk_NameDict*)((char*)self + 8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PyVar* PyObject__slots(PyObject* self){ | ||||||
|  |     assert(self->slots >= 0); | ||||||
|  |     return (PyVar*)((char*)self + 8); | ||||||
|  | } | ||||||
							
								
								
									
										108
									
								
								src/pocketpy.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/pocketpy.c
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | |||||||
| #include "pocketpy/pocketpy.h" | #include "pocketpy/pocketpy.h" | ||||||
|  | #include "pocketpy/common/utils.h" | ||||||
| #include "pocketpy/objects/object.h" | #include "pocketpy/objects/object.h" | ||||||
| #include "pocketpy/interpreter/vm.h" | #include "pocketpy/interpreter/vm.h" | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| @ -14,12 +15,12 @@ void py_initialize(){ | |||||||
|     pk_VM__ctor(&pk_default_vm); |     pk_VM__ctor(&pk_default_vm); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| py_Error* py_exec_simple(const char* source){ | int py_exec_simple(const char* source){ | ||||||
|     CodeObject* co = NULL; |     CodeObject* co = NULL; | ||||||
|     pk_VM* vm = pk_current_vm; |     pk_VM* vm = pk_current_vm; | ||||||
|     Frame* frame = Frame__new( |     Frame* frame = Frame__new( | ||||||
|         co, |         co, | ||||||
|         vm->main, |         &vm->main, | ||||||
|         NULL, |         NULL, | ||||||
|         vm->stack.sp, |         vm->stack.sp, | ||||||
|         vm->stack.sp, |         vm->stack.sp, | ||||||
| @ -27,11 +28,75 @@ py_Error* py_exec_simple(const char* source){ | |||||||
|     ); |     ); | ||||||
|     pk_VM__push_frame(vm, frame); |     pk_VM__push_frame(vm, frame); | ||||||
|     pk_FrameResult res = pk_VM__run_top_frame(vm); |     pk_FrameResult res = pk_VM__run_top_frame(vm); | ||||||
|     if(res == RES_ERROR) return vm->last_error; |     if(res == RES_ERROR) return vm->last_error->type; | ||||||
|     if(res == RES_RETURN) return NULL; // vm->last_retval;
 |     if(res == RES_RETURN) return 0; // vm->last_retval;
 | ||||||
|     assert(0);  // unreachable
 |     assert(0);  // unreachable
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | py_Ref py_getmodule(const char *name){ | ||||||
|  |     pk_VM* vm = pk_current_vm; | ||||||
|  |     return pk_NameDict__try_get(&vm->modules, py_name(name)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | py_Ref py_newmodule(const char *name, const char *package){ | ||||||
|  |     pk_ManagedHeap* heap = &pk_current_vm->heap; | ||||||
|  |     PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_module, -1, 0); | ||||||
|  | 
 | ||||||
|  |     py_Ref r0 = py_sysreg(0); | ||||||
|  |     py_Ref r1 = py_sysreg(1); | ||||||
|  | 
 | ||||||
|  |     *r0 = PyVar__fromobj(obj); | ||||||
|  | 
 | ||||||
|  |     py_newstr(r1, name); | ||||||
|  |     py_setdict(r0, __name__, r1); | ||||||
|  | 
 | ||||||
|  |     package = package ? package : ""; | ||||||
|  | 
 | ||||||
|  |     py_newstr(r1, package); | ||||||
|  |     py_setdict(r0, __package__, r1); | ||||||
|  | 
 | ||||||
|  |     // convert to fullname
 | ||||||
|  |     if(package[0] != '\0'){ | ||||||
|  |         // package.name
 | ||||||
|  |         char buf[256]; | ||||||
|  |         snprintf(buf, sizeof(buf), "%s.%s", package, name); | ||||||
|  |         name = buf; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     py_newstr(r1, name); | ||||||
|  |     py_setdict(r0, __path__, r1); | ||||||
|  | 
 | ||||||
|  |     // we do not allow override in order to avoid memory leak
 | ||||||
|  |     // it is because Module objects are not garbage collected
 | ||||||
|  |     bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name)); | ||||||
|  |     if(exists) abort(); | ||||||
|  |     pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0); | ||||||
|  |     return py_getmodule(name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | py_Error* py_getlasterror(){ | ||||||
|  |     return pk_current_vm->last_error; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void py_Error__print(py_Error* self){ | ||||||
|  |     abort(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | py_Ref py_reg(int i){ | ||||||
|  |     assert(i >= 0 && i < 8); | ||||||
|  |     return &pk_current_vm->reg[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | py_Ref py_sysreg(int i){ | ||||||
|  |     assert(i >= 0 && i < 8); | ||||||
|  |     return &pk_current_vm->sysreg[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | py_Ref py_stack(int i){ | ||||||
|  |     assert(i < 0); | ||||||
|  |     return &pk_current_vm->stack.sp[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void py_finalize(){ | void py_finalize(){ | ||||||
|     pk_VM__dtor(&pk_default_vm); |     pk_VM__dtor(&pk_default_vm); | ||||||
|     pk_current_vm = NULL; |     pk_current_vm = NULL; | ||||||
| @ -39,31 +104,36 @@ void py_finalize(){ | |||||||
|     Pools_finalize(); |     Pools_finalize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void py_newint(PyVar* self, int64_t val){ | void py_setdict(py_Ref self, py_Name name, const py_Ref val){ | ||||||
|  |     pk_NameDict__set( | ||||||
|  |         PyObject__dict(self->_obj), | ||||||
|  |         name, | ||||||
|  |         *val | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void py_newint(py_Ref self, int64_t val){ | ||||||
|     self->type = tp_int; |     self->type = tp_int; | ||||||
|     self->is_ptr = false; |     self->is_ptr = false; | ||||||
|     self->_i64 = val; |     self->_i64 = val; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void py_newfloat(PyVar* self, double val){ | void py_newfloat(py_Ref self, double val){ | ||||||
|     self->type = tp_float; |     self->type = tp_float; | ||||||
|     self->is_ptr = false; |     self->is_ptr = false; | ||||||
|     self->_f64 = val; |     self->_f64 = val; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void py_newbool(PyVar* self, bool val){ | void py_newbool(py_Ref self, bool val){ | ||||||
|     // return a global singleton
 |     pk_VM* vm = pk_current_vm; | ||||||
|  |     *self = val ? vm->True : vm->False; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void py_newnone(PyVar* self){ | void py_newstr(py_Ref self, const char* val){ | ||||||
|     // return a heap object
 |     pk_VM* vm = pk_current_vm; | ||||||
|  |     PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_str, 0, sizeof(py_Str)); | ||||||
|  |     py_Str__ctor((py_Str*)PyObject__value(obj), val); | ||||||
|  |     self->type = tp_str; | ||||||
|  |     self->is_ptr = true; | ||||||
|  |     self->_obj = obj; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| void py_newstr(PyVar* self, const char* val){ |  | ||||||
|     // return a heap object
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void py_newstr2(PyVar*, const char*, int); |  | ||||||
| 
 |  | ||||||
| void py_newbytes(PyVar*, const uint8_t*, int); |  | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include "pocketpy.h" | #include "pocketpy.h" | ||||||
|  | #include "pocketpy/pocketpy.h" | ||||||
| 
 | 
 | ||||||
| char* read_file(const char* path) { | char* read_file(const char* path) { | ||||||
|     FILE* file = fopen(path, "r"); |     FILE* file = fopen(path, "r"); | ||||||
| @ -27,10 +28,9 @@ int main(int argc, char** argv) { | |||||||
|     char* source = read_file(argv[1]); |     char* source = read_file(argv[1]); | ||||||
|     py_initialize(); |     py_initialize(); | ||||||
| 
 | 
 | ||||||
|     py_Error* err = py_exec_simple(source); |     if(py_exec_simple(source)){ | ||||||
|     if(err){ |         py_Error* err = py_getlasterror(); | ||||||
|         py_Error__print(err); |         py_Error__print(err); | ||||||
|         py_Error__delete(err); |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     py_finalize(); |     py_finalize(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user