blueloveTH 1 год назад
Родитель
Сommit
2d0db3dc71

+ 3 - 8
include/pocketpy/common/algorithm.h

@@ -9,15 +9,10 @@ extern "C" {
 void *c11__lower_bound(const void *key, const void *ptr, int count, int size,
                        bool (*less)(const void *, const void *));
 
+int *c11__lower_bound_int(int key, const int *ptr, int count);
+double *c11__lower_bound_double(double key, const double *ptr, int count);
+
 #ifdef __cplusplus
 }
 
-namespace pkpy{
-template<typename T>
-    T* lower_bound(T* begin, T* end, const T& value){
-        return (T*)c11__lower_bound(&value, begin, end - begin, sizeof(T), [](const void* a, const void* b){
-            return *(T*)a < *(T*)b;
-        });
-    }
-}   // namespace pkpy
 #endif

+ 5 - 4
include/pocketpy/common/sstream.h

@@ -1,15 +1,15 @@
 #pragma once
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include "pocketpy/common/vector.h"
 #include "pocketpy/common/str.h"
 #include "pocketpy/common/utils.h"
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct pkpy_SStream {
     c11_vector data;
 } pkpy_SStream;
@@ -40,6 +40,7 @@ PK_INLINE pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { pkpy_AnyStr s; s.type =
 PK_INLINE pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { pkpy_AnyStr s; s.type = 9; s._ptr = x; return s; }
 
 void pkpy_SStream__ctor(pkpy_SStream* self);
+void pkpy_SStream__ctor2(pkpy_SStream* self, int capacity);
 void pkpy_SStream__dtor(pkpy_SStream* self);
 
 void pkpy_SStream__write_int(pkpy_SStream* self, int);

+ 8 - 6
include/pocketpy/common/str.h

@@ -1,14 +1,13 @@
 #pragma once
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include <stdbool.h>
-
 #include "pocketpy/common/vector.h"
 #include "pocketpy/common/utils.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* string_view */
 typedef struct c11_string{
     const char* data;
@@ -29,7 +28,6 @@ PK_INLINE const char* pkpy_Str__data(const pkpy_Str* self){
     return self->is_sso ? self->_inlined : self->_ptr;
 }
 
-int pkpy_utils__u8_header(unsigned char c, bool suppress);
 void pkpy_Str__ctor(pkpy_Str* self, const char* data);
 void pkpy_Str__ctor2(pkpy_Str* self, const char* data, int size);
 void pkpy_Str__dtor(pkpy_Str* self);
@@ -57,6 +55,10 @@ int pkpy_Str__count(const pkpy_Str* self, const pkpy_Str* sub);
 c11_vector/* T=c11_string */ pkpy_Str__split(const pkpy_Str* self, char sep);
 c11_vector/* T=c11_string */ pkpy_Str__split2(const pkpy_Str* self, const pkpy_Str* sep);
 
+bool c11__isascii(const char* p, int size);
+bool c11__is_unicode_Lo_char(int c);
+int c11__u8_header(unsigned char c, bool suppress);
+
 #ifdef __cplusplus
 }
 #endif

+ 19 - 8
include/pocketpy/common/vector.h

@@ -1,14 +1,13 @@
 #pragma once
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include <string.h>
 #include <stdlib.h>
-
 #include "pocketpy/common/algorithm.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct c11_array{
     void* data;
     int count;
@@ -60,17 +59,29 @@ void c11_vector__clear(c11_vector* self);
 #define c11_vector__insert(T, self, index, elem) \
     do{ \
         if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \
-        memmove((T*)(self)->data + (index) + 1, (T*)(self)->data + (index), ((self)->count - (index)) * sizeof(T)); \
-        ((T*)(self)->data)[index] = (elem); \
+        T* p = (T*)(self)->data + (index); \
+        memmove(p + 1, p, ((self)->count - (index)) * sizeof(T)); \
+        *p = (elem); \
         (self)->count++; \
     }while(0)
 
 #define c11_vector__erase(T, self, index) \
     do{ \
-        memmove((T*)(self)->data + (index), (T*)(self)->data + (index) + 1, ((self)->count - (index) - 1) * sizeof(T)); \
+        T* p = (T*)(self)->data + (index); \
+        memmove(p, p + 1, ((self)->count - (index) - 1) * sizeof(T)); \
         (self)->count--; \
     }while(0)
 
+#define c11_vector__reverse(T, self, start, end) \
+    do{ \
+        T* p = (T*)(self)->data + (start); \
+        T* q = (T*)(self)->data + (end); \
+        while(p < q){ \
+            T tmp = *p; *p = *q; *q = tmp; \
+            p++; q--; \
+        } \
+    }while(0)
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 2
include/pocketpy/common/vector.hpp

@@ -428,13 +428,13 @@ struct small_map {
     Item* data() const { return _data.data(); }
 
     void insert(const K& key, const V& value) {
-        Item* it = lower_bound(_data.begin(), _data.end(), key);
+        Item* it = std::lower_bound(_data.begin(), _data.end(), key);
         assert(it == _data.end() || it->first != key);
         _data.insert(it, {key, value});
     }
 
     V* try_get(const K& key) const {
-        auto it = lower_bound(_data.begin(), _data.end(), key);
+        auto it = std::lower_bound(_data.begin(), _data.end(), key);
         if(it == _data.end() || it->first != key) return nullptr;
         return &it->second;
     }

+ 3 - 3
include/pocketpy/objects/sourcedata.h

@@ -17,11 +17,11 @@ struct pkpy_SourceData {
     pkpy_Str filename;
     pkpy_Str source;
 
-    c11_vector line_starts;     // contains "const char *"
-    c11_vector _precompiled_tokens;  // contains "pkpy_Str"
+    c11_vector/*T=const char* */ line_starts;
+    c11_vector/*T=pkpy_Str*/ _precompiled_tokens;
 };
 
-void pkpy_SourceData__ctor(struct pkpy_SourceData *self, const char *source, int source_size, const pkpy_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__dtor(struct pkpy_SourceData* self);
 
 bool pkpy_SourceData__get_line(const struct pkpy_SourceData *self, int lineno, const char **st, const char **ed);

+ 1 - 1
include/pocketpy/objects/sourcedata.hpp

@@ -8,7 +8,7 @@ namespace pkpy {
 
 struct SourceData : public pkpy_SourceData {
     SourceData(std::string_view source, const Str& filename, CompileMode mode) {
-        pkpy_SourceData__ctor(this, source.data(), source.size(), &filename, mode);
+        pkpy_SourceData__ctor(this, {source.data(), (int)source.size()}, &filename, mode);
     }
 
     ~SourceData() {

+ 22 - 3
src/common/algorithm.c

@@ -6,15 +6,34 @@ void *c11__lower_bound(const void *key, const void *ptr, int count, int size,
     int __len = count;
 
     while(__len != 0){
-        int __l2 = (int)((unsigned int)__len >> 1);
+        int __l2 = (int)((unsigned int)__len / 2);
         char* __m = __first + __l2 * size;
         if(less(__m, key)){
-            __first = __m;
             __m += size;
+            __first = __m;
             __len -= __l2 + 1;
         }else{
             __len = __l2;
         }
     }
     return __first;
-}
+}
+
+static bool c11__less_int(const void* a, const void* b){
+    return *(int*)a < *(int*)b;
+}
+
+static bool c11__less_double(const void* a, const void* b){
+    return *(double*)a < *(double*)b;
+}
+
+int *c11__lower_bound_int(int key, const int *ptr, int count) {
+    void* res = c11__lower_bound(&key, ptr, count, sizeof(int), c11__less_int);
+    return (int*)res;
+}
+
+double *c11__lower_bound_double(double key, const double *ptr, int count) {
+    void* res = c11__lower_bound(&key, ptr, count, sizeof(double), c11__less_double);
+    return (double*)res;
+}
+

+ 12 - 16
src/common/sourcedata.c

@@ -4,31 +4,27 @@
 #include <stdlib.h>
 #include <string.h>
 
-void pkpy_Str__take_buf(pkpy_Str *self, char *data, int size);
-
 void pkpy_SourceData__ctor(struct pkpy_SourceData* self,
-                           const char* source,
-                           int source_size,
+                           c11_string source,       // may not be null-terminated
                            const pkpy_Str* filename,
                            enum CompileMode mode) {
     self->filename = pkpy_Str__copy(filename);  // OPTIMIZEME?
     self->mode = mode;
-
     c11_vector__ctor(&self->line_starts, sizeof(const char*));
     c11_vector__ctor(&self->_precompiled_tokens, sizeof(pkpy_Str));
 
-    int index = (strncmp(source, "\xEF\xBB\xBF", 3) == 0) ? 3 : 0;
-    int len = source_size - index;
-    for(int i = 0; i < source_size; ++i)
-        len -= (source[i] == '\r');
-
-    char *buf = (char*)malloc(len + 1), *p = buf;
-    buf[len] = '\0';
-    for(; index < source_size; ++index) {
-        if(source[index] != '\r') *(p++) = source[index];
+    int index = 0;
+    // Skip utf8 BOM if there is any.
+    if (source.size >= 3 && strncmp(source.data, "\xEF\xBB\xBF", 3) == 0) index += 3;
+    // Drop all '\r'
+    pkpy_SStream ss;
+    pkpy_SStream__ctor2(&ss, source.size + 1);
+    while(index < source.size){
+        char c = source.data[index];
+        if(c != '\r') pkpy_SStream__write_char(&ss, c);
+        index++;
     }
-    pkpy_Str__take_buf(&self->source, buf, len);
-
+    self->source = pkpy_SStream__submit(&ss);
     self->is_precompiled = (strncmp(pkpy_Str__data(&self->source), "pkpy:", 5) == 0);
     c11_vector__push(const char*, &self->line_starts, pkpy_Str__data(&self->source));
 }

+ 24 - 4
src/common/sstream.c

@@ -10,6 +10,11 @@ void pkpy_SStream__ctor(pkpy_SStream* self) {
     c11_vector__ctor(&self->data, sizeof(char));
 }
 
+void pkpy_SStream__ctor2(pkpy_SStream* self, int capacity) {
+    c11_vector__ctor(&self->data, sizeof(char));
+    c11_vector__reserve(&self->data, capacity);
+}
+
 void pkpy_SStream__dtor(pkpy_SStream* self) {
     c11_vector__dtor(&self->data);
 }
@@ -24,10 +29,25 @@ void pkpy_SStream__write_int(pkpy_SStream* self, int i) {
     pkpy_SStream__write_cstr(self, buf);
 }
 
-void pkpy_SStream__write_i64(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__write_i64(pkpy_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){
+        pkpy_SStream__write_char(self, '0');
+        return;
+    }
+    if(val < 0){
+        pkpy_SStream__write_char(self, '-');
+        val = -val;
+    }
+    int start = self->data.count;
+    while(val){
+        c11_vector__push(char, &self->data, '0' + val % 10);
+        val /= 10;
+    }
+    int end = self->data.count - 1;
+    c11_vector__reverse(char, &self->data, start, end);
 }
 
 void pkpy_SStream__write_float(pkpy_SStream* self, float val, int precision){

Разница между файлами не показана из-за своего большого размера
+ 12 - 41
src/common/str.c


Разница между файлами не показана из-за своего большого размера
+ 0 - 1
src/compiler/lexer.cpp


+ 1 - 1
src/interpreter/iter.cpp

@@ -49,7 +49,7 @@ void StringIter::_register(VM* vm, PyObject* mod, PyObject* type) {
         Str& s = PK_OBJ_GET(Str, self.ref);
         if(self.i == s.size) return 0;
         int start = self.i;
-        int len = pkpy_utils__u8_header(s[self.i], false);
+        int len = c11__u8_header(s[self.i], false);
         self.i += len;
         vm->s_data.push(VAR(s.slice(start, self.i)));
         return 1;

+ 1 - 1
src/modules/random.cpp

@@ -199,7 +199,7 @@ struct Random {
             List result(k);
             for(int i = 0; i < k; i++) {
                 f64 r = self.gen.uniform(0.0, cum_weights[size - 1]);
-                int idx = lower_bound(cum_weights.begin(), cum_weights.end(), r) - cum_weights.begin();
+                int idx = c11__lower_bound_double(r, cum_weights.begin(), cum_weights.size()) - cum_weights.begin();
                 result[i] = data[idx];
             }
             return VAR(std::move(result));

Некоторые файлы не были показаны из-за большого количества измененных файлов