mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
4732d4149d
commit
371411d53a
@ -2,7 +2,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f:
|
|||||||
OPCODES_TEXT = f.read()
|
OPCODES_TEXT = f.read()
|
||||||
|
|
||||||
pipeline = [
|
pipeline = [
|
||||||
["common.h", "hash_table5.hpp", "memory.h", "str.h", "safestl.h", "builtins.h", "error.h"],
|
["common.h", "memory.h", "str.h", "tuplelist.h", "namedict.h", "builtins.h", "error.h"],
|
||||||
["obj.h", "parser.h", "ref.h", "codeobject.h", "frame.h"],
|
["obj.h", "parser.h", "ref.h", "codeobject.h", "frame.h"],
|
||||||
["vm.h", "ceval.h", "compiler.h", "repl.h"],
|
["vm.h", "ceval.h", "compiler.h", "repl.h"],
|
||||||
["iter.h", "pocketpy.h"]
|
["iter.h", "pocketpy.h"]
|
||||||
|
@ -28,16 +28,13 @@
|
|||||||
// #include <filesystem>
|
// #include <filesystem>
|
||||||
// namespace fs = std::filesystem;
|
// namespace fs = std::filesystem;
|
||||||
|
|
||||||
#define EMH_EXT 1
|
|
||||||
#define EMH_FIND_HIT 1
|
|
||||||
|
|
||||||
#ifdef POCKETPY_H
|
#ifdef POCKETPY_H
|
||||||
#define UNREACHABLE() throw std::runtime_error( "L" + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( "L" + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#else
|
#else
|
||||||
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PK_VERSION "0.8.9"
|
#define PK_VERSION "0.9.0"
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
|
||||||
typedef int32_t i64;
|
typedef int32_t i64;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "safestl.h"
|
#include "namedict.h"
|
||||||
|
#include "tuplelist.h"
|
||||||
|
|
||||||
struct NeedMoreLines {
|
struct NeedMoreLines {
|
||||||
NeedMoreLines(bool is_compiling_class) : is_compiling_class(is_compiling_class) {}
|
NeedMoreLines(bool is_compiling_class) : is_compiling_class(is_compiling_class) {}
|
||||||
|
2034
src/hash_table5.hpp
2034
src/hash_table5.hpp
File diff suppressed because it is too large
Load Diff
1788
src/hash_table8.hpp
1788
src/hash_table8.hpp
File diff suppressed because it is too large
Load Diff
@ -147,3 +147,8 @@ struct SmallArrayPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef pkpy::shared_ptr<PyObject> PyVar;
|
||||||
|
typedef PyVar PyVarOrNull;
|
||||||
|
typedef PyVar PyVarRef;
|
299
src/namedict.h
299
src/namedict.h
@ -1,160 +1,167 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "safestl.h"
|
#include "common.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
struct NameDictNode{
|
namespace pkpy{
|
||||||
StrName first;
|
|
||||||
PyVar second;
|
|
||||||
inline bool empty() const { return first.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NameDict {
|
struct NameDictNode{
|
||||||
int _capacity;
|
StrName first;
|
||||||
int _size;
|
PyVar second;
|
||||||
float _load_factor;
|
inline bool empty() const { return first.empty(); }
|
||||||
NameDictNode* _a;
|
|
||||||
|
|
||||||
NameDict(int capacity=4, float load_factor=0.67):
|
|
||||||
_capacity(capacity), _size(0), _load_factor(load_factor) {
|
|
||||||
_a = new NameDictNode[_capacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
NameDict(const NameDict& other) {
|
|
||||||
this->_capacity = other._capacity;
|
|
||||||
this->_size = other._size;
|
|
||||||
this->_a = new NameDictNode[_capacity];
|
|
||||||
for(int i=0; i<_capacity; i++) _a[i] = other._a[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
NameDict& operator=(const NameDict& other){
|
|
||||||
delete[] _a;
|
|
||||||
this->_capacity = other._capacity;
|
|
||||||
this->_size = other._size;
|
|
||||||
this->_a = new NameDictNode[_capacity];
|
|
||||||
for(int i=0; i<_capacity; i++) _a[i] = other._a[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameDict(NameDict&&) = delete;
|
|
||||||
NameDict& operator=(NameDict&&) = delete;
|
|
||||||
|
|
||||||
int size() const { return _size; }
|
|
||||||
|
|
||||||
//https://github.com/python/cpython/blob/main/Objects/dictobject.c#L175
|
|
||||||
#define HASH_PROBE(key, ok, i) \
|
|
||||||
int i = (key).index % _capacity; \
|
|
||||||
bool ok = false; \
|
|
||||||
while(!_a[i].empty()) { \
|
|
||||||
if(_a[i].first == (key)) { ok = true; break; } \
|
|
||||||
i = (5*i + 1) % _capacity; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define HASH_PROBE_OVERRIDE(key, ok, i) \
|
|
||||||
i = (key).index % _capacity; \
|
|
||||||
ok = false; \
|
|
||||||
while(!_a[i].empty()) { \
|
|
||||||
if(_a[i].first == (key)) { ok = true; break; } \
|
|
||||||
i = (5*i + 1) % _capacity; \
|
|
||||||
}
|
|
||||||
|
|
||||||
const PyVar& operator[](StrName key) const {
|
|
||||||
HASH_PROBE(key, ok, i);
|
|
||||||
if(!ok) throw std::out_of_range("NameDict key not found");
|
|
||||||
return _a[i].second;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] PyVar& operator[](StrName key){
|
|
||||||
HASH_PROBE(key, ok, i);
|
|
||||||
if(!ok) {
|
|
||||||
_a[i].first = key;
|
|
||||||
_size++;
|
|
||||||
if(_size > _capacity * _load_factor){
|
|
||||||
_rehash_2x();
|
|
||||||
HASH_PROBE_OVERRIDE(key, ok, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _a[i].second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _rehash_2x(){
|
|
||||||
NameDictNode* old_a = _a;
|
|
||||||
int old_capacity = _capacity;
|
|
||||||
_capacity *= 2;
|
|
||||||
_size = 0;
|
|
||||||
_a = new NameDictNode[_capacity];
|
|
||||||
for(int i=0; i<old_capacity; i++){
|
|
||||||
if(old_a[i].empty()) continue;
|
|
||||||
HASH_PROBE(old_a[i].first, ok, j);
|
|
||||||
_a[j].first = old_a[i].first;
|
|
||||||
_a[j].second = std::move(old_a[i].second);
|
|
||||||
_size++;
|
|
||||||
}
|
|
||||||
delete[] old_a;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline PyVar* try_get(StrName key){
|
|
||||||
HASH_PROBE(key, ok, i);
|
|
||||||
if(!ok) return nullptr;
|
|
||||||
return &_a[i].second;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool contains(StrName key) const {
|
|
||||||
HASH_PROBE(key, ok, i);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
~NameDict(){ delete[] _a;}
|
|
||||||
|
|
||||||
struct iterator {
|
|
||||||
const NameDict* _dict;
|
|
||||||
int i;
|
|
||||||
iterator() = default;
|
|
||||||
iterator(const NameDict* dict, int i): _dict(dict), i(i) { _skip_empty(); }
|
|
||||||
inline void _skip_empty(){ while(i < _dict->_capacity && _dict->_a[i].empty()) i++;}
|
|
||||||
inline iterator& operator++(){ i++; _skip_empty(); return *this;}
|
|
||||||
|
|
||||||
inline bool operator!=(const iterator& other) const { return i != other.i; }
|
|
||||||
inline bool operator==(const iterator& other) const { return i == other.i; }
|
|
||||||
|
|
||||||
inline NameDictNode* operator->() const { return &_dict->_a[i]; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
struct NameDict {
|
||||||
void emplace(StrName key, T&& value){
|
int _capacity;
|
||||||
HASH_PROBE(key, ok, i);
|
int _size;
|
||||||
if(!ok) {
|
float _load_factor;
|
||||||
_a[i].first = key;
|
NameDictNode* _a;
|
||||||
_size++;
|
|
||||||
if(_size > _capacity * _load_factor){
|
NameDict(int capacity=4, float load_factor=0.67):
|
||||||
_rehash_2x();
|
_capacity(capacity), _size(0), _load_factor(load_factor) {
|
||||||
HASH_PROBE_OVERRIDE(key, ok, i);
|
_a = new NameDictNode[_capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
NameDict(const NameDict& other) {
|
||||||
|
this->_capacity = other._capacity;
|
||||||
|
this->_size = other._size;
|
||||||
|
this->_a = new NameDictNode[_capacity];
|
||||||
|
for(int i=0; i<_capacity; i++) _a[i] = other._a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
NameDict& operator=(const NameDict& other){
|
||||||
|
delete[] _a;
|
||||||
|
this->_capacity = other._capacity;
|
||||||
|
this->_size = other._size;
|
||||||
|
this->_a = new NameDictNode[_capacity];
|
||||||
|
for(int i=0; i<_capacity; i++) _a[i] = other._a[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NameDict(NameDict&&) = delete;
|
||||||
|
NameDict& operator=(NameDict&&) = delete;
|
||||||
|
|
||||||
|
int size() const { return _size; }
|
||||||
|
|
||||||
|
//https://github.com/python/cpython/blob/main/Objects/dictobject.c#L175
|
||||||
|
#define HASH_PROBE(key, ok, i) \
|
||||||
|
int i = (key).index % _capacity; \
|
||||||
|
bool ok = false; \
|
||||||
|
while(!_a[i].empty()) { \
|
||||||
|
if(_a[i].first == (key)) { ok = true; break; } \
|
||||||
|
i = (5*i + 1) % _capacity; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HASH_PROBE_OVERRIDE(key, ok, i) \
|
||||||
|
i = (key).index % _capacity; \
|
||||||
|
ok = false; \
|
||||||
|
while(!_a[i].empty()) { \
|
||||||
|
if(_a[i].first == (key)) { ok = true; break; } \
|
||||||
|
i = (5*i + 1) % _capacity; \
|
||||||
|
}
|
||||||
|
|
||||||
|
const PyVar& operator[](StrName key) const {
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
if(!ok) throw std::out_of_range("NameDict key not found");
|
||||||
|
return _a[i].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] PyVar& operator[](StrName key){
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
if(!ok) {
|
||||||
|
_a[i].first = key;
|
||||||
|
_size++;
|
||||||
|
if(_size > _capacity * _load_factor){
|
||||||
|
_rehash_2x();
|
||||||
|
HASH_PROBE_OVERRIDE(key, ok, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _a[i].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rehash_2x(){
|
||||||
|
NameDictNode* old_a = _a;
|
||||||
|
int old_capacity = _capacity;
|
||||||
|
_capacity *= 2;
|
||||||
|
_size = 0;
|
||||||
|
_a = new NameDictNode[_capacity];
|
||||||
|
for(int i=0; i<old_capacity; i++){
|
||||||
|
if(old_a[i].empty()) continue;
|
||||||
|
HASH_PROBE(old_a[i].first, ok, j);
|
||||||
|
if(ok) UNREACHABLE();
|
||||||
|
_a[j].first = old_a[i].first;
|
||||||
|
_a[j].second = std::move(old_a[i].second);
|
||||||
|
_size++;
|
||||||
|
}
|
||||||
|
delete[] old_a;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PyVar* try_get(StrName key){
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
if(!ok) return nullptr;
|
||||||
|
return &_a[i].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool contains(StrName key) const {
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
~NameDict(){ delete[] _a;}
|
||||||
|
|
||||||
|
struct iterator {
|
||||||
|
const NameDict* _dict;
|
||||||
|
int i;
|
||||||
|
iterator() = default;
|
||||||
|
iterator(const NameDict* dict, int i): _dict(dict), i(i) { _skip_empty(); }
|
||||||
|
inline void _skip_empty(){ while(i < _dict->_capacity && _dict->_a[i].empty()) i++;}
|
||||||
|
inline iterator& operator++(){ i++; _skip_empty(); return *this;}
|
||||||
|
|
||||||
|
inline bool operator!=(const iterator& other) const { return i != other.i; }
|
||||||
|
inline bool operator==(const iterator& other) const { return i == other.i; }
|
||||||
|
|
||||||
|
inline NameDictNode* operator->() const { return &_dict->_a[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void emplace(StrName key, T&& value){
|
||||||
|
HASH_PROBE(key, ok, i);
|
||||||
|
if(!ok) {
|
||||||
|
_a[i].first = key;
|
||||||
|
_size++;
|
||||||
|
if(_size > _capacity * _load_factor){
|
||||||
|
_rehash_2x();
|
||||||
|
HASH_PROBE_OVERRIDE(key, ok, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_a[i].second = std::forward<T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(iterator begin, iterator end){
|
||||||
|
for(auto it = begin; it != end; ++it){
|
||||||
|
emplace(it->first, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_a[i].second = std::forward<T>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert(iterator begin, iterator end){
|
iterator find(StrName key) const{
|
||||||
for(auto it = begin; it != end; ++it){
|
HASH_PROBE(key, ok, i);
|
||||||
emplace(it->first, it->second);
|
if(!ok) return end();
|
||||||
|
return iterator(this, i);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
iterator find(StrName key) const{
|
void erase(StrName key){
|
||||||
HASH_PROBE(key, ok, i);
|
HASH_PROBE(key, ok, i);
|
||||||
if(!ok) return end();
|
if(!ok) throw std::out_of_range("NameDict key not found");
|
||||||
return iterator(this, i);
|
_a[i] = NameDictNode();
|
||||||
}
|
_size--;
|
||||||
|
}
|
||||||
|
|
||||||
void erase(StrName key){
|
inline iterator begin() const { return iterator(this, 0); }
|
||||||
HASH_PROBE(key, ok, i);
|
inline iterator end() const { return iterator(this, _capacity); }
|
||||||
if(!ok) throw std::out_of_range("NameDict key not found");
|
|
||||||
_a[i] = NameDictNode();
|
|
||||||
_size--;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline iterator begin() const { return iterator(this, 0); }
|
#undef HASH_PROBE
|
||||||
inline iterator end() const { return iterator(this, _capacity); }
|
#undef HASH_PROBE_OVERRIDE
|
||||||
|
};
|
||||||
|
|
||||||
#undef HASH_PROBE
|
} // namespace pkpy
|
||||||
#undef HASH_PROBE_OVERRIDE
|
|
||||||
};
|
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "safestl.h"
|
#include "namedict.h"
|
||||||
|
#include "tuplelist.h"
|
||||||
|
|
||||||
struct CodeObject;
|
struct CodeObject;
|
||||||
struct Frame;
|
struct Frame;
|
||||||
|
@ -4,18 +4,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
|
||||||
struct PyObject;
|
|
||||||
typedef pkpy::shared_ptr<PyObject> PyVar;
|
|
||||||
typedef PyVar PyVarOrNull;
|
|
||||||
typedef PyVar PyVarRef;
|
|
||||||
|
|
||||||
#include "hash_table5.hpp"
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
#include "namedict.h"
|
|
||||||
// template<typename... Args>
|
|
||||||
// using HashMap = emhash5::HashMap<Args...>;
|
|
||||||
// typedef HashMap<StrName, PyVar> NameDict;
|
|
||||||
|
|
||||||
class List: public std::vector<PyVar> {
|
class List: public std::vector<PyVar> {
|
||||||
PyVar& at(size_t) = delete;
|
PyVar& at(size_t) = delete;
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user