Просмотр исходного кода

Squashed commit of the following:

commit b584de5c3d4603a476cdd60830289104784a4942
Author: blueloveTH <blueloveth@foxmail.com>
Date:   Thu Jun 13 10:46:07 2024 +0800

    some fix

commit 1fe8a3280949d724ddab9c6b1476e1b55c5beb9d
Author: blueloveTH <blueloveth@foxmail.com>
Date:   Wed Jun 12 22:08:09 2024 +0800

    backup
blueloveTH 1 год назад
Родитель
Сommit
9d6f044d33

+ 1 - 2
compile_flags.txt

@@ -1,9 +1,8 @@
--xc++
-
 -Wall
 -W*
 
 -std=c++17
+-std=c11
 -stdlib=libc++
 
 -Iinclude/

+ 63 - 7
include/pocketpy/common/sstream.h

@@ -6,21 +6,77 @@ extern "C" {
 
 #include "pocketpy/common/vector.h"
 #include "pocketpy/common/str.h"
+#include "pocketpy/common/utils.h"
+
 #include <stdint.h>
 
 typedef struct pkpy_SStream {
     c11_vector data;
 } pkpy_SStream;
 
+typedef struct pkpy_AnyStr {
+    int type;
+    union {
+        int _int;
+        int64_t _int64;
+        float _float;
+        double _double;
+        char _char;
+        unsigned char _hex;
+        const pkpy_Str* _str;
+        c11_string _sv;
+        const char* _cstr;
+        void* _ptr;
+    };
+} pkpy_AnyStr;
+
+inline pkpy_AnyStr pkpy_AnyStr__int(int x) { return (pkpy_AnyStr){.type = 1, ._int = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__int64(int64_t x) { return (pkpy_AnyStr){.type = 2, ._int64 = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__float(float x) { return (pkpy_AnyStr){.type = 3, ._float = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__double(double x) { return (pkpy_AnyStr){.type = 4, ._double = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__char(char x) { return (pkpy_AnyStr){.type = 5, ._char = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__hex(unsigned char x) { return (pkpy_AnyStr){.type = 6, ._hex = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { return (pkpy_AnyStr){.type = 7, ._str = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { return (pkpy_AnyStr){.type = 8, ._sv = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { return (pkpy_AnyStr){.type = 9, ._cstr = x}; }
+inline pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { return (pkpy_AnyStr){.type = 10, ._ptr = x}; }
+
 void pkpy_SStream__ctor(pkpy_SStream* self);
 void pkpy_SStream__dtor(pkpy_SStream* self);
-void pkpy_SStream__append_cstr(pkpy_SStream* self, const char* str);
-void pkpy_SStream__append_cstrn(pkpy_SStream* self, const char* str, int n);
-void pkpy_SStream__append_Str(pkpy_SStream* self, const pkpy_Str* str);
-void pkpy_SStream__append_char(pkpy_SStream* self, char c);
-void pkpy_SStream__append_int(pkpy_SStream* self, int i);
-void pkpy_SStream__append_int64(pkpy_SStream* self, int64_t i);
-pkpy_Str pkpy_SStream__to_Str(const pkpy_SStream* self);
+void pkpy_SStream__write_char(pkpy_SStream* self, char);
+void pkpy_SStream__write_int(pkpy_SStream* self, int);
+void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t);
+void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str*);
+void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string);
+void pkpy_SStream__write_cstr(pkpy_SStream* self, const char*);
+void pkpy_SStream__write_cstrn(pkpy_SStream* self, const char*, int);
+void pkpy_SStream__write_any(pkpy_SStream* self, const char* fmt, const pkpy_AnyStr* args, int n);
+
+// Submit the stream and return the final string. The stream becomes invalid after this call
+pkpy_Str pkpy_SStream__submit(pkpy_SStream* self);
+
+#define pkpy__anystr(x) _Generic((x), \
+    int: pkpy_AnyStr__int, \
+    int64_t: pkpy_AnyStr__int64, \
+    float: pkpy_AnyStr__float, \
+    double: pkpy_AnyStr__double, \
+    char: pkpy_AnyStr__char, \
+    unsigned char: pkpy_AnyStr__hex, \
+    const pkpy_Str*: pkpy_AnyStr__str, \
+    c11_string: pkpy_AnyStr__sv, \
+    const char*: pkpy_AnyStr__cstr, \
+    void*: pkpy_AnyStr__ptr \
+)(x)
+
+#define pkpy__anystr_list_1(a) (pkpy_AnyStr[]){pkpy__anystr(a)}, 1
+#define pkpy__anystr_list_2(a, b) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b)}, 2
+#define pkpy__anystr_list_3(a, b, c) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b), pkpy__anystr(c)}, 3
+#define pkpy__anystr_list_4(a, b, c, d) (pkpy_AnyStr[]){pkpy__anystr(a), pkpy__anystr(b), pkpy__anystr(c), pkpy__anystr(d)}, 4
+
+#define pkpy__anystr_list_dispatcher(...) PK_NARGS_SEQ(__VA_ARGS__, pkpy__anystr_list_4, pkpy__anystr_list_3, pkpy__anystr_list_2, pkpy__anystr_list_1, 0)
+#define pkpy__anystr_list(...) pkpy__anystr_list_dispatcher(__VA_ARGS__)(__VA_ARGS__) 
+
+#define pkpy_SStream__write(self, fmt, ...) pkpy_SStream__write_any(self, fmt, pkpy__anystr_list(__VA_ARGS__))
 
 #ifdef __cplusplus
 }

+ 5 - 0
include/pocketpy/common/utils.h

@@ -24,6 +24,11 @@ extern const char* kPlatformStrings[];
 #define PK_MIN(a, b) ((a) < (b) ? (a) : (b))
 #define PK_MAX(a, b) ((a) > (b) ? (a) : (b))
 
+// NARGS
+#define PK_NARGS_SEQ(_1, _2, _3, _4, N, ...) N
+#define PK_NARGS(...) PK_NARGS_SEQ(__VA_ARGS__, 4, 3, 2, 1, 0)
+#define PK_NPTRS(...) PK_NARGS_SEQ(__VA_ARGS__, int****, int***, int**, int*, int)
+
 #ifdef __cplusplus
 }
 #endif

+ 3 - 0
include/pocketpy/common/vector.h

@@ -4,6 +4,9 @@
 extern "C" {
 #endif
 
+#include <string.h>
+#include <stdlib.h>
+
 typedef struct c11_array{
     void* data;
     int count;

+ 22 - 17
src/common/sourcedata.c

@@ -22,7 +22,7 @@ void pkpy_SourceData__ctor(struct pkpy_SourceData* self,
     for(int i = 0; i < source_size; ++i)
         len -= (source[i] == '\r');
 
-    char *buf = malloc(len + 1), *p = buf;
+    char *buf = (char*)malloc(len + 1), *p = buf;
     buf[len] = '\0';
     for(; index < source_size; ++index) {
         if(source[index] != '\r') *(p++) = source[index];
@@ -57,39 +57,44 @@ bool pkpy_SourceData__get_line(const struct pkpy_SourceData* self, int lineno, c
 pkpy_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData* self, int lineno, const char* cursor, const char* name) {
     pkpy_SStream ss;
     pkpy_SStream__ctor(&ss);
-    pkpy_SStream__append_cstr(&ss, "  File \"");
-    pkpy_SStream__append_Str(&ss, &self->filename);
-    pkpy_SStream__append_cstr(&ss, "\", line ");
-    pkpy_SStream__append_int(&ss, lineno);
+
+    // pkpy_SStream__write_cstr(&ss, "  File \"");
+    // pkpy_SStream__write_Str(&ss, &self->filename);
+    // pkpy_SStream__write_cstr(&ss, "\", line ");
+    // pkpy_SStream__write_int(&ss, lineno);
+
+    pkpy_SStream__write(&ss,
+        "  File \"{}\", line {}",
+        &self->filename,
+        lineno
+    );
 
     if(name) {
-        pkpy_SStream__append_cstr(&ss, ", in ");
-        pkpy_SStream__append_cstr(&ss, name);
+        pkpy_SStream__write_cstr(&ss, ", in ");
+        pkpy_SStream__write_cstr(&ss, name);
     }
 
     if(!self->is_precompiled) {
-        pkpy_SStream__append_char(&ss, '\n');
+        pkpy_SStream__write_char(&ss, '\n');
         const char *st = NULL, *ed;
         if(pkpy_SourceData__get_line(self, lineno, &st, &ed)) {
             while(st < ed && isblank(*st))
                 ++st;
             if(st < ed) {
-                pkpy_SStream__append_cstr(&ss, "    ");
-                pkpy_SStream__append_cstrn(&ss, st, ed - st);
+                pkpy_SStream__write_cstr(&ss, "    ");
+                pkpy_SStream__write_cstrn(&ss, st, ed - st);
                 if(cursor && st <= cursor && cursor <= ed) {
-                    pkpy_SStream__append_cstr(&ss, "\n    ");
+                    pkpy_SStream__write_cstr(&ss, "\n    ");
                     for(int i = 0; i < (cursor - st); ++i)
-                        pkpy_SStream__append_char(&ss, ' ');
-                    pkpy_SStream__append_cstr(&ss, "^");
+                        pkpy_SStream__write_char(&ss, ' ');
+                    pkpy_SStream__write_cstr(&ss, "^");
                 }
             } else {
                 st = NULL;
             }
         }
 
-        if(!st) { pkpy_SStream__append_cstr(&ss, "    <?>"); }
+        if(!st) { pkpy_SStream__write_cstr(&ss, "    <?>"); }
     }
-    pkpy_Str res = pkpy_SStream__to_Str(&ss);
-    pkpy_SStream__dtor(&ss);
-    return res;
+    return pkpy_SStream__submit(&ss);
 }

+ 59 - 24
src/common/sstream.c

@@ -1,5 +1,8 @@
 #include "pocketpy/common/sstream.h"
+#include "pocketpy/common/utils.h"
+
 #include <stdio.h>
+#include <assert.h>
 
 void pkpy_SStream__ctor(pkpy_SStream* self) {
     c11_vector__ctor(&self->data, sizeof(char));
@@ -9,40 +12,72 @@ void pkpy_SStream__dtor(pkpy_SStream* self) {
     c11_vector__dtor(&self->data);
 }
 
-void pkpy_SStream__append_cstr(pkpy_SStream* self, const char* str) {
-    for (int i = 0; str[i] != '\0'; i++) {
-        c11_vector__push(char, &self->data, str[i]);
-    }
+void pkpy_SStream__write_char(pkpy_SStream* self, char c) {
+    c11_vector__push(char, &self->data, c);
 }
 
-void pkpy_SStream__append_cstrn(pkpy_SStream* self, const char* str, int n) {
-    for (int i = 0; i < n; i++) {
-        c11_vector__push(char, &self->data, str[i]);
-    }
+void pkpy_SStream__write_int(pkpy_SStream* self, int i) {
+    char buf[12]; // sign + 10 digits + null terminator
+    snprintf(buf, sizeof(buf), "%d", i);
+    pkpy_SStream__write_cstr(self, buf);
 }
 
-void pkpy_SStream__append_Str(pkpy_SStream* self, const pkpy_Str* str) {
-    pkpy_SStream__append_cstr(self, pkpy_Str__data(str));
+void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t i) {
+    char buf[23]; // sign + 21 digits + null terminator
+    snprintf(buf, sizeof(buf), "%lld", i);
+    pkpy_SStream__write_cstr(self, buf);
 }
 
-void pkpy_SStream__append_char(pkpy_SStream* self, char c) {
-    c11_vector__push(char, &self->data, c);
+void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str* str) {
+    pkpy_SStream__write_cstr(self, pkpy_Str__data(str));
 }
 
-void pkpy_SStream__append_int(pkpy_SStream* self, int i) {
-    char str[12]; // sign + 10 digits + null terminator
-    sprintf(str, "%d", i);
-    pkpy_SStream__append_cstr(self, str);
+void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string sv) {
+    pkpy_SStream__write_cstrn(self, sv.data, sv.size);
 }
 
-void pkpy_SStream__append_int64(pkpy_SStream* self, int64_t i) {
-    char str[23]; // sign + 21 digits + null terminator
-    sprintf(str, "%lld", i);
-    pkpy_SStream__append_cstr(self, str);
+void pkpy_SStream__write_cstr(pkpy_SStream* self, const char* str) {
+    pkpy_SStream__write_cstrn(self, str, strlen(str));
+}
+
+void pkpy_SStream__write_cstrn(pkpy_SStream* self, const char* str, int n) {
+    c11_vector__extend(char, &self->data, str, n);
+}
+
+void pkpy_SStream__write_any(pkpy_SStream* self, const char* fmt, const pkpy_AnyStr* args, int n){
+    int i = 0;
+    while(*fmt){
+        if(*fmt == '{' && fmt[1] == '}'){
+            assert(i < n);
+            switch(args[i].type){
+                case 1: pkpy_SStream__write_int(self, args[i]._int); break;
+                case 2: pkpy_SStream__write_int64(self, args[i]._int64); break;
+                case 3: assert(0); break;
+                case 4: assert(0); break;
+                case 5: pkpy_SStream__write_char(self, args[i]._char); break;
+                case 6: assert(0); break;
+                case 7: pkpy_SStream__write_Str(self, args[i]._str); break;
+                case 8: pkpy_SStream__write_sv(self, args[i]._sv); break;
+                case 9: pkpy_SStream__write_cstr(self, args[i]._cstr); break;
+                case 10: assert(0); break;
+                default: assert(0); break;
+            }
+            fmt += 2;
+            i++;
+        }else{
+            pkpy_SStream__write_char(self, *fmt);
+            fmt++;
+        }
+    }
 }
 
-pkpy_Str pkpy_SStream__to_Str(const pkpy_SStream* self) {
-    pkpy_Str res;
-    pkpy_Str__ctor2(&res, self->data.data, self->data.count);
-    return res;
+pkpy_Str pkpy_SStream__submit(pkpy_SStream* self) {
+    c11_vector__push(char, &self->data, '\0');
+    pkpy_Str retval = {
+        .size = self->data.count - 1,
+        .is_ascii = false,  // need to check
+        .is_sso = false,
+        ._ptr = (char*)self->data.data
+    };
+    return retval;
 }

+ 8 - 3
tests/80_traceback.py

@@ -4,11 +4,16 @@ try:
     a = {'123': 4}
     b = a[6]
 except KeyError:
-    s = traceback.format_exc()
+    actual = traceback.format_exc()
 
-ok = s == '''Traceback (most recent call last):
+expected = '''Traceback (most recent call last):
   File "80_traceback.py", line 5
     b = a[6]
 KeyError: 6'''
 
-assert ok, s
+if actual != expected:
+    print('--- ACTUAL RESULT -----')
+    print(actual)
+    print('--- EXPECTED RESULT ---')
+    print(expected)
+    exit(1)