mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-27 15:00:18 +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