mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-22 04:20:17 +00:00
177 lines
5.1 KiB
C
177 lines
5.1 KiB
C
#include "pocketpy/common/strname.h"
|
|
#include "pocketpy/common/smallmap.h"
|
|
#include "pocketpy/common/utils.h"
|
|
#include "pocketpy/common/vector.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
// TODO: use a more efficient data structure
|
|
static c11_smallmap_s2n _interned;
|
|
static c11_vector/*T=char* */ _r_interned;
|
|
static bool _initialized = false;
|
|
|
|
void pk_StrName__initialize(){
|
|
if(_initialized) return;
|
|
c11_smallmap_s2n__ctor(&_interned);
|
|
for(int i=0; i<_r_interned.count; i++){
|
|
free(c11__at(char*, &_r_interned, i));
|
|
}
|
|
c11_vector__ctor(&_r_interned, sizeof(c11_string));
|
|
_initialized = true;
|
|
|
|
// unary operators
|
|
__repr__ = pk_StrName__map("__repr__");
|
|
__str__ = pk_StrName__map("__str__");
|
|
__hash__ = pk_StrName__map("__hash__");
|
|
__len__ = pk_StrName__map("__len__");
|
|
__iter__ = pk_StrName__map("__iter__");
|
|
__next__ = pk_StrName__map("__next__");
|
|
__neg__ = pk_StrName__map("__neg__");
|
|
// logical operators
|
|
__eq__ = pk_StrName__map("__eq__");
|
|
__lt__ = pk_StrName__map("__lt__");
|
|
__le__ = pk_StrName__map("__le__");
|
|
__gt__ = pk_StrName__map("__gt__");
|
|
__ge__ = pk_StrName__map("__ge__");
|
|
__contains__ = pk_StrName__map("__contains__");
|
|
// binary operators
|
|
__add__ = pk_StrName__map("__add__");
|
|
__radd__ = pk_StrName__map("__radd__");
|
|
__sub__ = pk_StrName__map("__sub__");
|
|
__rsub__ = pk_StrName__map("__rsub__");
|
|
__mul__ = pk_StrName__map("__mul__");
|
|
__rmul__ = pk_StrName__map("__rmul__");
|
|
__truediv__ = pk_StrName__map("__truediv__");
|
|
__floordiv__ = pk_StrName__map("__floordiv__");
|
|
__mod__ = pk_StrName__map("__mod__");
|
|
__pow__ = pk_StrName__map("__pow__");
|
|
__matmul__ = pk_StrName__map("__matmul__");
|
|
__lshift__ = pk_StrName__map("__lshift__");
|
|
__rshift__ = pk_StrName__map("__rshift__");
|
|
__and__ = pk_StrName__map("__and__");
|
|
__or__ = pk_StrName__map("__or__");
|
|
__xor__ = pk_StrName__map("__xor__");
|
|
__invert__ = pk_StrName__map("__invert__");
|
|
// indexer
|
|
__getitem__ = pk_StrName__map("__getitem__");
|
|
__setitem__ = pk_StrName__map("__setitem__");
|
|
__delitem__ = pk_StrName__map("__delitem__");
|
|
|
|
// specials
|
|
__new__ = pk_StrName__map("__new__");
|
|
__init__ = pk_StrName__map("__init__");
|
|
__call__ = pk_StrName__map("__call__");
|
|
__divmod__ = pk_StrName__map("__divmod__");
|
|
__enter__ = pk_StrName__map("__enter__");
|
|
__exit__ = pk_StrName__map("__exit__");
|
|
__name__ = pk_StrName__map("__name__");
|
|
__all__ = pk_StrName__map("__all__");
|
|
__package__ = pk_StrName__map("__package__");
|
|
__path__ = pk_StrName__map("__path__");
|
|
__class__ = pk_StrName__map("__class__");
|
|
__missing__ = pk_StrName__map("__missing__");
|
|
|
|
pk_id_add = pk_StrName__map("add");
|
|
pk_id_set = pk_StrName__map("set");
|
|
pk_id_long = pk_StrName__map("long");
|
|
pk_id_complex = pk_StrName__map("complex");
|
|
}
|
|
|
|
void pk_StrName__finalize(){
|
|
if(!_initialized) return;
|
|
c11_smallmap_s2n__dtor(&_interned);
|
|
c11_vector__dtor(&_r_interned);
|
|
}
|
|
|
|
uint16_t pk_StrName__map(const char* name){
|
|
return pk_StrName__map2((c11_string){name, strlen(name)});
|
|
}
|
|
|
|
uint16_t pk_StrName__map2(c11_string name){
|
|
// TODO: PK_GLOBAL_SCOPE_LOCK()
|
|
if(!_initialized){
|
|
pk_StrName__initialize(); // lazy init
|
|
}
|
|
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
|
|
if(index != 0) return index;
|
|
// generate new index
|
|
if(_interned.count > 65530){
|
|
PK_FATAL_ERROR("StrName index overflow\n");
|
|
}
|
|
// NOTE: we must allocate the string in the heap so iterators are not invalidated
|
|
char* p = malloc(name.size + 1);
|
|
memcpy(p, name.data, name.size);
|
|
p[name.size] = '\0';
|
|
c11_vector__push(char*, &_r_interned, p);
|
|
index = _r_interned.count; // 1-based
|
|
// save to _interned
|
|
c11_smallmap_s2n__set(&_interned, (c11_string){p, name.size}, index);
|
|
assert(_interned.count == _r_interned.count);
|
|
return index;
|
|
}
|
|
|
|
const char* pk_StrName__rmap(uint16_t index){
|
|
assert(_initialized);
|
|
assert(index > 0 && index <= _interned.count);
|
|
return c11__getitem(char*, &_r_interned, index - 1);
|
|
}
|
|
|
|
|
|
|
|
// unary operators
|
|
uint16_t __repr__;
|
|
uint16_t __str__;
|
|
uint16_t __hash__;
|
|
uint16_t __len__;
|
|
uint16_t __iter__;
|
|
uint16_t __next__;
|
|
uint16_t __neg__;
|
|
// logical operators
|
|
uint16_t __eq__;
|
|
uint16_t __lt__;
|
|
uint16_t __le__;
|
|
uint16_t __gt__;
|
|
uint16_t __ge__;
|
|
uint16_t __contains__;
|
|
// binary operators
|
|
uint16_t __add__;
|
|
uint16_t __radd__;
|
|
uint16_t __sub__;
|
|
uint16_t __rsub__;
|
|
uint16_t __mul__;
|
|
uint16_t __rmul__;
|
|
uint16_t __truediv__;
|
|
uint16_t __floordiv__;
|
|
uint16_t __mod__;
|
|
uint16_t __pow__;
|
|
uint16_t __matmul__;
|
|
uint16_t __lshift__;
|
|
uint16_t __rshift__;
|
|
uint16_t __and__;
|
|
uint16_t __or__;
|
|
uint16_t __xor__;
|
|
uint16_t __invert__;
|
|
// indexer
|
|
uint16_t __getitem__;
|
|
uint16_t __setitem__;
|
|
uint16_t __delitem__;
|
|
|
|
// specials
|
|
uint16_t __new__;
|
|
uint16_t __init__;
|
|
uint16_t __call__;
|
|
uint16_t __divmod__;
|
|
uint16_t __enter__;
|
|
uint16_t __exit__;
|
|
uint16_t __name__;
|
|
uint16_t __all__;
|
|
uint16_t __package__;
|
|
uint16_t __path__;
|
|
uint16_t __class__;
|
|
uint16_t __missing__;
|
|
|
|
uint16_t pk_id_add;
|
|
uint16_t pk_id_set;
|
|
uint16_t pk_id_long;
|
|
uint16_t pk_id_complex;
|