mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-11-04 10:40:19 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "a9d6242a4304643a00f72d93a8884f0b86531d98" and "f22191faa6c532da36d89777a1ddc5d949ad2199" have entirely different histories.
		
	
	
		
			a9d6242a43
			...
			f22191faa6
		
	
		
@ -14,13 +14,39 @@ typedef struct pk_SStream {
 | 
			
		||||
    c11_vector data;
 | 
			
		||||
} pk_SStream;
 | 
			
		||||
 | 
			
		||||
typedef struct pk_AnyStr {
 | 
			
		||||
    int type;
 | 
			
		||||
    union {
 | 
			
		||||
        int _int;
 | 
			
		||||
        int64_t _i64;
 | 
			
		||||
        float _float;
 | 
			
		||||
        double _double;
 | 
			
		||||
        char _char;
 | 
			
		||||
        const py_Str* _str;
 | 
			
		||||
        c11_string _sv;
 | 
			
		||||
        const char* _cstr;
 | 
			
		||||
        void* _ptr;
 | 
			
		||||
    };
 | 
			
		||||
} pk_AnyStr;
 | 
			
		||||
 | 
			
		||||
PK_INLINE pk_AnyStr pk_AnyStr__int(int x) { pk_AnyStr s; s.type = 1; s._int = x; return s; }
 | 
			
		||||
PK_INLINE pk_AnyStr pk_AnyStr__i64(int64_t x) { pk_AnyStr s; s.type = 2; s._i64 = 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__char(char x) { pk_AnyStr s; s.type = 5; s._char = 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__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; }
 | 
			
		||||
 | 
			
		||||
void pk_SStream__ctor(pk_SStream* self);
 | 
			
		||||
void pk_SStream__ctor2(pk_SStream* self, int capacity);
 | 
			
		||||
void pk_SStream__dtor(pk_SStream* self);
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_int(pk_SStream* self, int);
 | 
			
		||||
void pk_SStream__write_i64(pk_SStream* self, int64_t);
 | 
			
		||||
void pk_SStream__write_f64(pk_SStream* self, double, 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_char(pk_SStream* self, char);
 | 
			
		||||
void pk_SStream__write_Str(pk_SStream* self, const py_Str*);
 | 
			
		||||
void pk_SStream__write_sv(pk_SStream* self, c11_string);
 | 
			
		||||
@ -28,11 +54,35 @@ 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_hex(pk_SStream* self, unsigned char, bool non_zero);
 | 
			
		||||
void pk_SStream__write_ptr(pk_SStream* self, void*);
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_any(pk_SStream* self, 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
 | 
			
		||||
py_Str pk_SStream__submit(pk_SStream* self);
 | 
			
		||||
 | 
			
		||||
void pk_vsprintf(pk_SStream* ss, const char* fmt, va_list args);
 | 
			
		||||
void pk_sprintf(pk_SStream* ss, const char* fmt, ...);
 | 
			
		||||
#define pk__anystr(x) _Generic((x), \
 | 
			
		||||
    int: pk_AnyStr__int, \
 | 
			
		||||
    int64_t: pk_AnyStr__i64, \
 | 
			
		||||
    float: pk_AnyStr__float, \
 | 
			
		||||
    double: pk_AnyStr__double, \
 | 
			
		||||
    char: pk_AnyStr__char, \
 | 
			
		||||
    const py_Str*: pk_AnyStr__str, \
 | 
			
		||||
    c11_string: pk_AnyStr__sv, \
 | 
			
		||||
    const char*: pk_AnyStr__cstr, \
 | 
			
		||||
    void*: pk_AnyStr__ptr \
 | 
			
		||||
)(x)
 | 
			
		||||
 | 
			
		||||
#define pk__anystr_list_1(a) (pk_AnyStr[]){pk__anystr(a)}, 1
 | 
			
		||||
#define pk__anystr_list_2(a, b) (pk_AnyStr[]){pk__anystr(a), pk__anystr(b)}, 2
 | 
			
		||||
#define pk__anystr_list_3(a, b, c) (pk_AnyStr[]){pk__anystr(a), pk__anystr(b), pk__anystr(c)}, 3
 | 
			
		||||
#define pk__anystr_list_4(a, b, c, d) (pk_AnyStr[]){pk__anystr(a), pk__anystr(b), pk__anystr(c), pk__anystr(d)}, 4
 | 
			
		||||
 | 
			
		||||
#define pk__anystr_list_dispatcher(...) PK_NARGS_SEQ(__VA_ARGS__, pk__anystr_list_4, pk__anystr_list_3, pk__anystr_list_2, pk__anystr_list_1, 0)
 | 
			
		||||
#define pk__anystr_list(...) pk__anystr_list_dispatcher(__VA_ARGS__)(__VA_ARGS__) 
 | 
			
		||||
 | 
			
		||||
#define pk_SStream__write(self, fmt, ...) pk_SStream__write_any(self, fmt, pk__anystr_list(__VA_ARGS__))
 | 
			
		||||
#define pk_format(fmt, ...) pk_format_any(fmt, pk__anystr_list(__VA_ARGS__))
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
/************* Public Types *************/
 | 
			
		||||
typedef struct py_TValue py_TValue;
 | 
			
		||||
@ -105,7 +104,6 @@ bool py_tobool(const py_Ref);
 | 
			
		||||
py_Type py_totype(const py_Ref);
 | 
			
		||||
const char* py_tostr(const py_Ref);
 | 
			
		||||
const char* py_tostrn(const py_Ref, int* size);
 | 
			
		||||
const unsigned char* py_tobytes(const py_Ref, int* size);
 | 
			
		||||
 | 
			
		||||
void* py_touserdata(const py_Ref);
 | 
			
		||||
 | 
			
		||||
@ -143,6 +141,7 @@ void py_bindmethod2(py_Type type, const char* name, py_CFunction f, BindType bt)
 | 
			
		||||
void py_bindnativefunc(py_Ref obj, const char* name, py_CFunction f);
 | 
			
		||||
 | 
			
		||||
/// Get the reference to the i-th register.
 | 
			
		||||
/// @lifespan: Permanent.
 | 
			
		||||
py_GlobalRef py_reg(int i);
 | 
			
		||||
 | 
			
		||||
/// Get the reference of the object's `__dict__`.
 | 
			
		||||
@ -303,27 +302,14 @@ typedef struct pk_TypeInfo pk_TypeInfo;
 | 
			
		||||
pk_TypeInfo* pk_tpinfo(const py_Ref self);
 | 
			
		||||
 | 
			
		||||
/// Search the magic method from the given type to the base type.
 | 
			
		||||
/// Return the reference or NULL if not found.
 | 
			
		||||
/// Returns the reference or NULL if not found.
 | 
			
		||||
/// @lifespan: Permanent.
 | 
			
		||||
py_GlobalRef py_tpfindmagic(py_Type, py_Name name);
 | 
			
		||||
 | 
			
		||||
/// Get the type object of the given type.
 | 
			
		||||
/// @lifespan: Permanent.
 | 
			
		||||
py_GlobalRef py_tpobject(py_Type type);
 | 
			
		||||
 | 
			
		||||
/// Get the type name.
 | 
			
		||||
const char* py_tpname(py_Type type);
 | 
			
		||||
 | 
			
		||||
/// Python favored string formatting.
 | 
			
		||||
/// %d: int
 | 
			
		||||
/// %i: py_i64 (int64_t)
 | 
			
		||||
/// %f: py_f64 (double)
 | 
			
		||||
/// %s: const char*
 | 
			
		||||
/// %q: single quoted %s
 | 
			
		||||
/// %c: char
 | 
			
		||||
/// %p: void*
 | 
			
		||||
/// %t: py_Type
 | 
			
		||||
/// %n: py_Name
 | 
			
		||||
const char* py_fmt(const char* fmt, ...);
 | 
			
		||||
 | 
			
		||||
#define MAGIC_METHOD(x) extern uint16_t x;
 | 
			
		||||
#include "pocketpy/xmacros/magics.h"
 | 
			
		||||
#undef MAGIC_METHOD
 | 
			
		||||
 | 
			
		||||
@ -5,10 +5,10 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static void pk_SourceData__ctor(struct pk_SourceData* self,
 | 
			
		||||
                                const char* source,
 | 
			
		||||
                                const char* filename,
 | 
			
		||||
                                enum CompileMode mode,
 | 
			
		||||
                                bool is_dynamic) {
 | 
			
		||||
                           const char* source,
 | 
			
		||||
                           const char* filename,
 | 
			
		||||
                           enum CompileMode mode,
 | 
			
		||||
                           bool is_dynamic) {
 | 
			
		||||
    py_Str__ctor(&self->filename, filename);
 | 
			
		||||
    self->mode = mode;
 | 
			
		||||
    c11_vector__ctor(&self->line_starts, sizeof(const char*));
 | 
			
		||||
@ -19,7 +19,7 @@ static void pk_SourceData__ctor(struct pk_SourceData* self,
 | 
			
		||||
    // Drop all '\r'
 | 
			
		||||
    pk_SStream ss;
 | 
			
		||||
    pk_SStream__ctor(&ss);
 | 
			
		||||
    while(true) {
 | 
			
		||||
    while(true){
 | 
			
		||||
        char c = *source;
 | 
			
		||||
        if(c == '\0') break;
 | 
			
		||||
        if(c != '\r') pk_SStream__write_char(&ss, c);
 | 
			
		||||
@ -36,27 +36,21 @@ static void pk_SourceData__dtor(struct pk_SourceData* self) {
 | 
			
		||||
    py_Str__dtor(&self->source);
 | 
			
		||||
    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++){
 | 
			
		||||
        py_Str__dtor(c11__at(py_Str, &self->_precompiled_tokens, i));
 | 
			
		||||
    }
 | 
			
		||||
    c11_vector__dtor(&self->_precompiled_tokens);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pk_SourceData_ pk_SourceData__rcnew(const char* source,
 | 
			
		||||
                                    const char* filename,
 | 
			
		||||
                                    enum CompileMode mode,
 | 
			
		||||
                                    bool is_dynamic) {
 | 
			
		||||
pk_SourceData_ pk_SourceData__rcnew(const char* source, const char* filename, enum CompileMode mode, bool is_dynamic) {
 | 
			
		||||
    pk_SourceData_ self = malloc(sizeof(struct pk_SourceData));
 | 
			
		||||
    pk_SourceData__ctor(self, source, filename, mode, is_dynamic);
 | 
			
		||||
    self->rc.count = 1;
 | 
			
		||||
    self->rc.dtor = (void (*)(void*))pk_SourceData__dtor;
 | 
			
		||||
    self->rc.dtor = (void(*)(void*))pk_SourceData__dtor;
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pk_SourceData__get_line(const struct pk_SourceData* self,
 | 
			
		||||
                             int lineno,
 | 
			
		||||
                             const char** st,
 | 
			
		||||
                             const char** ed) {
 | 
			
		||||
bool pk_SourceData__get_line(const struct pk_SourceData* self, int lineno, const char** st, const char** ed) {
 | 
			
		||||
    if(self->is_precompiled || lineno == -1) { return false; }
 | 
			
		||||
    lineno -= 1;
 | 
			
		||||
    if(lineno < 0) lineno = 0;
 | 
			
		||||
@ -70,14 +64,20 @@ bool pk_SourceData__get_line(const struct pk_SourceData* self,
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
py_Str pk_SourceData__snapshot(const struct pk_SourceData* self,
 | 
			
		||||
                               int lineno,
 | 
			
		||||
                               const char* cursor,
 | 
			
		||||
                               const char* name) {
 | 
			
		||||
py_Str pk_SourceData__snapshot(const struct pk_SourceData* self, int lineno, const char* cursor, const char* name) {
 | 
			
		||||
    pk_SStream ss;
 | 
			
		||||
    pk_SStream__ctor(&ss);
 | 
			
		||||
 | 
			
		||||
    pk_sprintf(&ss, "  File \"%S\", line %d", &self->filename, lineno);
 | 
			
		||||
    // pk_SStream__write_cstr(&ss, "  File \"");
 | 
			
		||||
    // pk_SStream__write_Str(&ss, &self->filename);
 | 
			
		||||
    // pk_SStream__write_cstr(&ss, "\", line ");
 | 
			
		||||
    // pk_SStream__write_int(&ss, lineno);
 | 
			
		||||
 | 
			
		||||
    pk_SStream__write(&ss,
 | 
			
		||||
        "  File \"{}\", line {}",
 | 
			
		||||
        &self->filename,
 | 
			
		||||
        lineno
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if(name && *name) {
 | 
			
		||||
        pk_SStream__write_cstr(&ss, ", in ");
 | 
			
		||||
 | 
			
		||||
@ -1,27 +1,31 @@
 | 
			
		||||
#include "pocketpy/common/sstream.h"
 | 
			
		||||
#include "pocketpy/common/config.h"
 | 
			
		||||
#include "pocketpy/common/utils.h"
 | 
			
		||||
#include "pocketpy/pocketpy.h"
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
void pk_SStream__ctor(pk_SStream* self) { c11_vector__ctor(&self->data, sizeof(char)); }
 | 
			
		||||
void pk_SStream__ctor(pk_SStream* self) {
 | 
			
		||||
    c11_vector__ctor(&self->data, sizeof(char));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__ctor2(pk_SStream* self, int capacity) {
 | 
			
		||||
    c11_vector__ctor(&self->data, sizeof(char));
 | 
			
		||||
    c11_vector__reserve(&self->data, capacity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__dtor(pk_SStream* self) { c11_vector__dtor(&self->data); }
 | 
			
		||||
void pk_SStream__dtor(pk_SStream* self) {
 | 
			
		||||
    c11_vector__dtor(&self->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_char(pk_SStream* self, char c) { c11_vector__push(char, &self->data, c); }
 | 
			
		||||
void pk_SStream__write_char(pk_SStream* self, char c) {
 | 
			
		||||
    c11_vector__push(char, &self->data, c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_int(pk_SStream* self, int i) {
 | 
			
		||||
    char buf[12];  // sign + 10 digits + null terminator
 | 
			
		||||
    char buf[12]; // sign + 10 digits + null terminator
 | 
			
		||||
    snprintf(buf, sizeof(buf), "%d", i);
 | 
			
		||||
    pk_SStream__write_cstr(self, buf);
 | 
			
		||||
}
 | 
			
		||||
@ -30,16 +34,16 @@ void pk_SStream__write_i64(pk_SStream* self, int64_t val) {
 | 
			
		||||
    // sign + 21 digits + null terminator
 | 
			
		||||
    // str(-2**64).__len__() == 21
 | 
			
		||||
    c11_vector__reserve(&self->data, self->data.count + 23);
 | 
			
		||||
    if(val == 0) {
 | 
			
		||||
    if(val == 0){
 | 
			
		||||
        pk_SStream__write_char(self, '0');
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if(val < 0) {
 | 
			
		||||
    if(val < 0){
 | 
			
		||||
        pk_SStream__write_char(self, '-');
 | 
			
		||||
        val = -val;
 | 
			
		||||
    }
 | 
			
		||||
    int start = self->data.count;
 | 
			
		||||
    while(val) {
 | 
			
		||||
    while(val){
 | 
			
		||||
        c11_vector__push(char, &self->data, '0' + val % 10);
 | 
			
		||||
        val /= 10;
 | 
			
		||||
    }
 | 
			
		||||
@ -47,7 +51,11 @@ void pk_SStream__write_i64(pk_SStream* self, int64_t val) {
 | 
			
		||||
    c11_vector__reverse(char, &self->data, start, end);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_f64(pk_SStream* self, double val, int precision) {
 | 
			
		||||
void pk_SStream__write_float(pk_SStream* self, float val, int precision){
 | 
			
		||||
    pk_SStream__write_double(self, val, precision);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_double(pk_SStream* self, double val, int precision){
 | 
			
		||||
    if(isinf(val)) {
 | 
			
		||||
        pk_SStream__write_cstr(self, val > 0 ? "inf" : "-inf");
 | 
			
		||||
        return;
 | 
			
		||||
@ -67,11 +75,8 @@ void pk_SStream__write_f64(pk_SStream* self, double val, int precision) {
 | 
			
		||||
    }
 | 
			
		||||
    pk_SStream__write_cstr(self, b);
 | 
			
		||||
    bool all_is_digit = true;
 | 
			
		||||
    for(int i = 1; i < size; i++) {
 | 
			
		||||
        if(!isdigit(b[i])) {
 | 
			
		||||
            all_is_digit = false;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    for(int i = 1; i < size; i++){
 | 
			
		||||
        if(!isdigit(b[i])){ all_is_digit = false; break; }
 | 
			
		||||
    }
 | 
			
		||||
    if(all_is_digit) pk_SStream__write_cstr(self, ".0");
 | 
			
		||||
}
 | 
			
		||||
@ -119,113 +124,53 @@ void pk_SStream__write_ptr(pk_SStream* self, void* p) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_SStream__write_any(pk_SStream* self, const char* fmt, const pk_AnyStr* args, int n){
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    while(*fmt){
 | 
			
		||||
        if(*fmt == '{' && fmt[1] == '}'){
 | 
			
		||||
            assert(i < n);
 | 
			
		||||
            switch(args[i].type){
 | 
			
		||||
                case 1: pk_SStream__write_int(self, args[i]._int); break;
 | 
			
		||||
                case 2: pk_SStream__write_i64(self, args[i]._i64); break;
 | 
			
		||||
                case 3: pk_SStream__write_float(self, args[i]._float, -1); break;
 | 
			
		||||
                case 4: pk_SStream__write_double(self, args[i]._double, -1); break;
 | 
			
		||||
                case 5: pk_SStream__write_char(self, args[i]._char); break;
 | 
			
		||||
                case 6: pk_SStream__write_Str(self, args[i]._str); break;
 | 
			
		||||
                case 7: pk_SStream__write_sv(self, args[i]._sv); break;
 | 
			
		||||
                case 8: pk_SStream__write_cstr(self, args[i]._cstr); break;
 | 
			
		||||
                case 9: pk_SStream__write_ptr(self, args[i]._ptr); break;
 | 
			
		||||
                default: assert(0); break;
 | 
			
		||||
            }
 | 
			
		||||
            fmt += 2;
 | 
			
		||||
            i++;
 | 
			
		||||
        }else{
 | 
			
		||||
            pk_SStream__write_char(self, *fmt);
 | 
			
		||||
            fmt++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
py_Str pk_SStream__submit(pk_SStream* self) {
 | 
			
		||||
    c11_vector__push(char, &self->data, '\0');
 | 
			
		||||
    c11_array a = c11_vector__submit(&self->data);
 | 
			
		||||
    // TODO: optimize c11__isascii
 | 
			
		||||
    py_Str retval = {.size = a.count - 1,
 | 
			
		||||
                     .is_ascii = c11__isascii((char*)a.data, a.count),
 | 
			
		||||
                     .is_sso = false,
 | 
			
		||||
                     ._ptr = (char*)a.data};
 | 
			
		||||
    py_Str retval = {
 | 
			
		||||
        .size = a.count - 1,
 | 
			
		||||
        .is_ascii = c11__isascii((char*)a.data, a.count),
 | 
			
		||||
        .is_sso = false,
 | 
			
		||||
        ._ptr = (char*)a.data
 | 
			
		||||
    };
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_vsprintf(pk_SStream* ss, const char* fmt, va_list args) {
 | 
			
		||||
    while(fmt) {
 | 
			
		||||
        char c = *fmt;
 | 
			
		||||
        if(c != '%') {
 | 
			
		||||
            pk_SStream__write_char(ss, c);
 | 
			
		||||
            fmt++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fmt++;
 | 
			
		||||
        c = *fmt;
 | 
			
		||||
 | 
			
		||||
        switch(c) {
 | 
			
		||||
            case 'd': {
 | 
			
		||||
                int i = va_arg(args, int);
 | 
			
		||||
                pk_SStream__write_int(ss, i);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'i': {
 | 
			
		||||
                int64_t i = va_arg(args, int64_t);
 | 
			
		||||
                pk_SStream__write_i64(ss, i);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'f': {
 | 
			
		||||
                double d = va_arg(args, double);
 | 
			
		||||
                pk_SStream__write_f64(ss, d, -1);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 's': {
 | 
			
		||||
                const char* s = va_arg(args, const char*);
 | 
			
		||||
                pk_SStream__write_cstr(ss, s);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'q': {
 | 
			
		||||
                const char* s = va_arg(args, const char*);
 | 
			
		||||
                py_Str tmp, tmp2;
 | 
			
		||||
                py_Str__ctor(&tmp, s);
 | 
			
		||||
                tmp2 = py_Str__escape(&tmp, '\'');
 | 
			
		||||
                pk_SStream__write_Str(ss, &tmp2);
 | 
			
		||||
                py_Str__dtor(&tmp);
 | 
			
		||||
                py_Str__dtor(&tmp2);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'S': {
 | 
			
		||||
                const py_Str* s = va_arg(args, const py_Str*);
 | 
			
		||||
                pk_SStream__write_Str(ss, s);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'c': {
 | 
			
		||||
                char c = va_arg(args, int);
 | 
			
		||||
                pk_SStream__write_char(ss, c);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'p': {
 | 
			
		||||
                void* p = va_arg(args, void*);
 | 
			
		||||
                pk_SStream__write_ptr(ss, p);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 't': {
 | 
			
		||||
                py_Type t = va_arg(args, int);
 | 
			
		||||
                pk_SStream__write_cstr(ss, py_tpname(t));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'n': {
 | 
			
		||||
                py_Name n = va_arg(args, int);
 | 
			
		||||
                pk_SStream__write_cstr(ss, py_name2str(n));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case '%': pk_SStream__write_char(ss, '%'); break;
 | 
			
		||||
            default:
 | 
			
		||||
                pk_SStream__write_char(ss, c);
 | 
			
		||||
                assert(false);  // invalid format
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        fmt++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pk_sprintf(pk_SStream* ss, const char* fmt, ...) {
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, fmt);
 | 
			
		||||
    pk_vsprintf(ss, fmt, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* py_fmt(const char* fmt, ...) {
 | 
			
		||||
const char* pk_format_any(const char* fmt, const pk_AnyStr* args, int n){
 | 
			
		||||
    PK_THREAD_LOCAL pk_SStream ss;
 | 
			
		||||
    if(ss.data.elem_size == 0) {
 | 
			
		||||
        pk_SStream__ctor2(&ss, 256);
 | 
			
		||||
    } else {
 | 
			
		||||
    if(ss.data.elem_size == 0){
 | 
			
		||||
        pk_SStream__ctor2(&ss, 128);
 | 
			
		||||
    }else{
 | 
			
		||||
        c11_vector__clear(&ss.data);
 | 
			
		||||
    }
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, fmt);
 | 
			
		||||
    pk_vsprintf(&ss, fmt, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
    pk_SStream__write_any(&ss, fmt, args, n);
 | 
			
		||||
    pk_SStream__write_char(&ss, '\0');
 | 
			
		||||
    return (const char*)ss.data.data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -823,7 +823,7 @@ Error* pk_Lexer__process_and_dump(pk_SourceData_ src, py_Str* out) {
 | 
			
		||||
                break;
 | 
			
		||||
            case TokenValue_F64:
 | 
			
		||||
                pk_SStream__write_char(&ss, 'F');
 | 
			
		||||
                pk_SStream__write_f64(&ss, token->value._f64, -1);
 | 
			
		||||
                pk_SStream__write_float(&ss, token->value._f64, -1);
 | 
			
		||||
                break;
 | 
			
		||||
            case TokenValue_STR: {
 | 
			
		||||
                pk_SStream__write_char(&ss, 'S');
 | 
			
		||||
 | 
			
		||||
@ -51,13 +51,6 @@ const char* py_tostrn(const py_Ref self, int* size){
 | 
			
		||||
    return py_Str__data(ud);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const unsigned char* py_tobytes(const py_Ref self, int* size){
 | 
			
		||||
    assert(self->type == tp_bytes);
 | 
			
		||||
    int* ud = PyObject__value(self->_obj);
 | 
			
		||||
    *size = *ud;
 | 
			
		||||
    return (unsigned char*)(ud + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* py_touserdata(const py_Ref self){
 | 
			
		||||
    assert(self && self->is_ptr);
 | 
			
		||||
    return PyObject__value(self->_obj);
 | 
			
		||||
 | 
			
		||||
@ -87,12 +87,6 @@ py_Ref py_tpobject(py_Type type) {
 | 
			
		||||
    return &c11__at(pk_TypeInfo, &vm->types, type)->self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* py_tpname(py_Type type) {
 | 
			
		||||
    pk_VM* vm = pk_current_vm;
 | 
			
		||||
    py_Name name = c11__at(pk_TypeInfo, &vm->types, type)->name;
 | 
			
		||||
    return py_name2str(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool py_callmagic(py_Name name, int argc, py_Ref argv) {
 | 
			
		||||
    assert(argc >= 1);
 | 
			
		||||
    assert(py_ismagicname(name));
 | 
			
		||||
@ -100,4 +94,4 @@ bool py_callmagic(py_Name name, int argc, py_Ref argv) {
 | 
			
		||||
    if(!tmp) return TypeError(name);
 | 
			
		||||
    if(tmp->type == tp_nativefunc) return tmp->_cfunc(argc, argv);
 | 
			
		||||
    return py_call(tmp, argc, argv);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user