diff --git a/include/pocketpy/common/smallmap.h b/include/pocketpy/common/smallmap.h index 43002cc5..3b2e04f7 100644 --- a/include/pocketpy/common/smallmap.h +++ b/include/pocketpy/common/smallmap.h @@ -1,6 +1,7 @@ #pragma once #include "pocketpy/common/vector.h" +#include "pocketpy/common/str.h" #include #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 diff --git a/include/pocketpy/common/str.h b/include/pocketpy/common/str.h index 28efd200..bf68929f 100644 --- a/include/pocketpy/common/str.h +++ b/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); diff --git a/include/pocketpy/common/str.hpp b/include/pocketpy/common/str.hpp index 2ef12dd1..b8ba24bc 100644 --- a/include/pocketpy/common/str.hpp +++ b/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; diff --git a/include/pocketpy/xmacros/smallmap.h b/include/pocketpy/xmacros/smallmap.h index e0819549..8422d09b 100644 --- a/include/pocketpy/xmacros/smallmap.h +++ b/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 diff --git a/src/common/smallmap.c b/src/common/smallmap.c index d8a01b84..0f82764b 100644 --- a/src/common/smallmap.c +++ b/src/common/smallmap.c @@ -1,4 +1,5 @@ #include "pocketpy/common/vector.h" +#include "pocketpy/common/str.h" #include #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 diff --git a/src/common/str.c b/src/common/str.c index 3a21f342..7b7705d4 100644 --- a/src/common/str.c +++ b/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); diff --git a/src/compiler/lexer.cpp b/src/compiler/lexer.cpp index e53670bc..e5573512 100644 --- a/src/compiler/lexer.cpp +++ b/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 @@ -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 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; ikey << '\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; }