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

+ 6 - 3
include/pocketpy/common/smallmap.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "pocketpy/common/vector.h"
+#include "pocketpy/common/str.h"
 #include <stdint.h>
 
 #ifdef __cplusplus
@@ -16,9 +17,11 @@ extern "C" {
 
 
 #define SMALLMAP_T__HEADER
-#define K const char*
-#define V uint16_t
-#define TAG s2n
+#define K c11_string
+#define V int
+#define TAG s2i
+#define less(a, b)  (c11_string__cmp((a.key), (b)) < 0)
+#define equal(a, b)  (c11_string__cmp((a), (b)) == 0)
 #include "pocketpy/xmacros/smallmap.h"
 #undef SMALLMAP_T__HEADER
 

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

@@ -14,6 +14,10 @@ typedef struct c11_string{
     int size;
 } c11_string;
 
+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__cmp3(c11_string self, const char* other);
+
 typedef struct pkpy_Str{
     int size;
     bool is_ascii;
@@ -48,6 +52,7 @@ pkpy_Str pkpy_Str__u8_slice(const pkpy_Str* self, int start, int stop, int step)
 int pkpy_Str__u8_length(const pkpy_Str* self);
 int pkpy_Str__cmp(const pkpy_Str* self, const pkpy_Str* other);
 int pkpy_Str__cmp2(const pkpy_Str* self, const char* other, int size);
+int pkpy_Str__cmp3(const pkpy_Str* self, const char* other);
 int pkpy_Str__unicode_index_to_byte(const pkpy_Str* self, int i);
 int pkpy_Str__byte_index_to_unicode(const pkpy_Str* self, int n);
 int pkpy_Str__index(const pkpy_Str* self, const pkpy_Str* sub, int start);

+ 5 - 0
include/pocketpy/common/str.hpp

@@ -347,6 +347,11 @@ struct SStream: pkpy_SStream {
         return *this;
     }
 
+    SStream& operator<< (c11_string val){
+        pkpy_SStream__write_cstrn(this, val.data, val.size);
+        return *this;
+    }
+
     SStream& operator<< (char val){
         pkpy_SStream__write_char(this, val);
         return *this;

+ 8 - 5
include/pocketpy/xmacros/smallmap.h

@@ -1,5 +1,3 @@
-#pragma once
-
 #if !defined(SMALLMAP_T__HEADER) && !defined(SMALLMAP_T__SOURCE)
     #include "pocketpy/common/vector.h"
 
@@ -14,6 +12,10 @@
     #define less(a, b) ((a.key) < (b))
 #endif
 
+#ifndef equal
+    #define equal(a, b) ((a) == (b))
+#endif
+
 /* Temprary macros */
 #define CONCAT(A, B) CONCAT_(A, B)
 #define CONCAT_(A, B) A##B
@@ -53,7 +55,7 @@ void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value) {
     int index;
     c11__lower_bound(KV, self->data, self->count, key, less, &index);
     KV* it = c11__at(KV, self, index);
-    if(index != self->count && it->key == key) {
+    if(index != self->count && equal(it->key, key)) {
         it->value = value;
     } else {
         KV kv = {key, value};
@@ -65,7 +67,7 @@ V* SMALLMAP_METHOD(try_get)(const SMALLMAP* self, K key) {
     int index;
     c11__lower_bound(KV, self->data, self->count, key, less, &index);
     KV* it = c11__at(KV, self, index);
-    if(index != self->count && it->key == key) {
+    if(index != self->count && equal(it->key, key)) {
         return &it->value;
     } else {
         return NULL;
@@ -85,7 +87,7 @@ bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key) {
     int index;
     c11__lower_bound(KV, self->data, self->count, key, less, &index);
     KV* it = c11__at(KV, self, index);
-    if(index != self->count && it->key == key) {
+    if(index != self->count && equal(it->key, key)) {
         c11_vector__erase(KV, self, index);
         return true;
     }
@@ -108,3 +110,4 @@ void SMALLMAP_METHOD(clear)(SMALLMAP* self) {
 #undef V
 #undef TAG
 #undef less
+#undef equal

+ 6 - 3
src/common/smallmap.c

@@ -1,4 +1,5 @@
 #include "pocketpy/common/vector.h"
+#include "pocketpy/common/str.h"
 #include <stdint.h>
 
 #define SMALLMAP_T__SOURCE
@@ -10,8 +11,10 @@
 
 
 #define SMALLMAP_T__SOURCE
-#define K const char*
-#define V uint16_t
-#define TAG s2n
+#define K c11_string
+#define V int
+#define TAG s2i
+#define less(a, b)  (c11_string__cmp((a.key), (b)) < 0)
+#define equal(a, b)  (c11_string__cmp((a), (b)) == 0)
 #include "pocketpy/xmacros/smallmap.h"
 #undef SMALLMAP_T__SOURCE

+ 18 - 0
src/common/str.c

@@ -238,6 +238,20 @@ pkpy_Str pkpy_Str__replace2(const pkpy_Str *self, const pkpy_Str *old, const pkp
     return retval;
 }
 
+int c11_string__cmp(c11_string self, c11_string other){
+    return c11_string__cmp2(self, other.data, other.size);
+}
+
+int c11_string__cmp2(c11_string self, const char *other, int size){
+    int res = strncmp(self.data, other, PK_MIN(self.size, size));
+    if(res != 0) return res;
+    return self.size - size;
+}
+
+int c11_string__cmp3(c11_string self, const char *other){
+    return c11_string__cmp2(self, other, strlen(other));
+}
+
 int pkpy_Str__cmp(const pkpy_Str *self, const pkpy_Str *other){
     return pkpy_Str__cmp2(self, pkpy_Str__data(other), other->size);
 }
@@ -248,6 +262,10 @@ int pkpy_Str__cmp2(const pkpy_Str *self, const char *other, int size){
     return self->size - size;
 }
 
+int pkpy_Str__cmp3(const pkpy_Str *self, const char *other){
+    return strcmp(pkpy_Str__data(self), other);
+}
+
 pkpy_Str pkpy_Str__u8_getitem(const pkpy_Str *self, int i){
     i = pkpy_Str__unicode_index_to_byte(self, i);
     int size = c11__u8_header(pkpy_Str__data(self)[i], false);

+ 18 - 8
src/compiler/lexer.cpp

@@ -1,6 +1,7 @@
 #include "pocketpy/compiler/lexer.hpp"
 #include "pocketpy/common/config.h"
 #include "pocketpy/common/str.h"
+#include "pocketpy/common/smallmap.h"
 
 #include <cstdarg>
 
@@ -603,29 +604,37 @@ Error* Lexer::precompile(Str* out) noexcept{
     ss << "pkpy:" PK_VERSION << '\n';       // L1: version string
     ss << (int)src->mode << '\n';           // L2: mode
 
-    small_map<std::string_view, int> token_indices;
+    c11_smallmap_s2i token_indices;
+    c11_smallmap_s2i__ctor(&token_indices);
+
     for(auto token: nexts) {
         if(is_raw_string_used(token.type)) {
-            if(!token_indices.contains(token.sv())) {
-                token_indices.insert(token.sv(), 0);
+            c11_string token_sv = {token.start, token.length};
+            if(!c11_smallmap_s2i__contains(&token_indices, token_sv)) {
+                c11_smallmap_s2i__set(&token_indices, token_sv, 0);
                 // assert no '\n' in token.sv()
                 for(char c: token.sv())
                     assert(c != '\n');
             }
         }
     }
-    ss << "=" << (int)token_indices.size() << '\n';  // L3: raw string count
+    ss << "=" << (int)token_indices.count << '\n';  // L3: raw string count
     int index = 0;
-    for(auto& kv: token_indices) {
-        ss << kv.first << '\n';  // L4: raw strings
-        kv.second = index++;
+    for(int i=0; i<token_indices.count; i++){
+        c11_smallmap_entry_s2i* kv = c11__at(c11_smallmap_entry_s2i, &token_indices, i);
+        ss << kv->key << '\n';  // L4: raw strings
+        kv->value = index++;
     }
 
     ss << "=" << (int)nexts.size() << '\n';  // L5: token count
     for(int i = 0; i < nexts.size(); i++) {
         const Token& token = nexts[i];
         ss << (int)token.type << ',';
-        if(is_raw_string_used(token.type)) { ss << token_indices[token.sv()] << ','; }
+        if(is_raw_string_used(token.type)) {
+            int index = c11_smallmap_s2i__get(&token_indices, {token.start, token.length}, -1);
+            assert(index >= 0);
+            ss << index << ',';
+        }
         if(i > 0 && nexts[i - 1].line == token.line)
             ss << ',';
         else
@@ -652,6 +661,7 @@ Error* Lexer::precompile(Str* out) noexcept{
             token.value);
     }
     *out = ss.str();
+    c11_smallmap_s2i__dtor(&token_indices);
     return NULL;
 }