some move

This commit is contained in:
blueloveTH 2024-06-16 17:34:11 +08:00
parent 6791c0c81e
commit 26815fae74
34 changed files with 323 additions and 234 deletions

View File

@ -1,5 +1,8 @@
-Wall -Wall
-W* -W*
-xc++
-std=c++17
-Iinclude/ -Iinclude/
-I3rd/cjson/include/ -I3rd/cjson/include/

View File

@ -11,7 +11,7 @@ extern "C" {
#define SMALLMAP_T__HEADER #define SMALLMAP_T__HEADER
#define K uint16_t #define K uint16_t
#define V int #define V int
#define TAG n2i #define NAME c11_smallmap_n2i
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__HEADER #undef SMALLMAP_T__HEADER
@ -19,7 +19,7 @@ extern "C" {
#define SMALLMAP_T__HEADER #define SMALLMAP_T__HEADER
#define K c11_string #define K c11_string
#define V uint16_t #define V uint16_t
#define TAG s2n #define NAME c11_smallmap_s2n
#define less(a, b) (c11_string__cmp((a), (b)) < 0) #define less(a, b) (c11_string__cmp((a), (b)) < 0)
#define equal(a, b) (c11_string__cmp((a), (b)) == 0) #define equal(a, b) (c11_string__cmp((a), (b)) == 0)
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"

View File

@ -39,7 +39,7 @@ struct VoidP {
#define POINTER_VAR(Tp, NAME) \ #define POINTER_VAR(Tp, NAME) \
inline PyVar py_var(VM* vm, Tp val) { \ inline PyVar py_var(VM* vm, Tp val) { \
const static pair<StrName, StrName> P("c", NAME); \ const static pair<StrName, StrName> P("c", NAME); \
PyVar type = vm->_modules[P.first]->attr(P.second); \ PyVar type = vm->_modules[P.first]->attr()[P.second]; \
return vm->new_object<VoidP>(type->as<Type>(), val); \ return vm->new_object<VoidP>(type->as<Type>(), val); \
} }

View File

@ -218,11 +218,11 @@ public:
constexpr static Type tp_none_type = Type(kTpNoneTypeIndex), tp_not_implemented_type = Type(kTpNotImplementedTypeIndex); constexpr static Type tp_none_type = Type(kTpNoneTypeIndex), tp_not_implemented_type = Type(kTpNotImplementedTypeIndex);
constexpr static Type tp_ellipsis = Type(26); constexpr static Type tp_ellipsis = Type(26);
constexpr static PyVar True{const_sso_var(), tp_bool, 1}; inline static PyVar True = pkpy_True;
constexpr static PyVar False{const_sso_var(), tp_bool, 0}; inline static PyVar False = pkpy_False;
constexpr static PyVar None{const_sso_var(), tp_none_type, 0}; inline static PyVar None = pkpy_None;
constexpr static PyVar NotImplemented{const_sso_var(), tp_not_implemented_type, 0}; inline static PyVar NotImplemented = pkpy_NotImplemented;
constexpr static PyVar Ellipsis{const_sso_var(), tp_ellipsis, 0}; inline static PyVar Ellipsis = pkpy_Ellipsis;
const bool enable_os; const bool enable_os;
VM(bool enable_os = true); VM(bool enable_os = true);
@ -242,7 +242,7 @@ public:
List py_list(PyVar); // x -> list(x) List py_list(PyVar); // x -> list(x)
bool py_callable(PyVar obj); // x -> callable(x) bool py_callable(PyVar obj); // x -> callable(x)
bool py_bool(PyVar obj){ // x -> bool(x) bool py_bool(PyVar obj){ // x -> bool(x)
if(obj.type == tp_bool) return obj._0; if(obj.type == tp_bool) return obj._bool;
return __py_bool_non_trivial(obj); return __py_bool_non_trivial(obj);
} }
i64 py_hash(PyVar obj); // x -> hash(x) i64 py_hash(PyVar obj); // x -> hash(x)

View File

@ -0,0 +1,77 @@
#pragma once
#include "stdint.h"
#include "stdbool.h"
#include "stdlib.h"
#include "assert.h"
#include "string.h"
#include "pocketpy/common/utils.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int16_t pkpy_Type;
typedef struct PyObject PyObject;
typedef struct PyVar{
pkpy_Type type;
bool is_ptr;
uint8_t flags;
int flags_ex;
union {
int64_t _i64;
double _f64;
bool _bool;
PyObject* _obj;
void* _ptr;
// Vec2
};
} PyVar;
static_assert(sizeof(PyVar) == 16, "sizeof(PyVar) != 16");
PK_INLINE bool PyVar__is_null(const PyVar* self) { return self->type == 0; }
PK_INLINE PyObject* PyVar__get(const PyVar* self) { return self->_obj; }
PK_INLINE int64_t PyVar__hash(const PyVar* self) { return self->flags_ex + self->_i64; }
PK_INLINE bool PyVar__less(const PyVar* self, const PyVar* other){
return memcmp(self, other, sizeof(PyVar)) < 0;
}
PK_INLINE bool PyVar__equal(const PyVar* self, const PyVar* other){
return memcmp(self, other, sizeof(PyVar)) == 0;
}
PK_INLINE void PyVar__ctor(PyVar* self, pkpy_Type type, PyObject* obj){
self->type = type;
self->is_ptr = true;
self->flags = 0;
self->flags_ex = 0;
self->_obj = obj;
}
#define pkpy_Var__is_null(self) ((self)->type == 0)
#define pkpy_Var__set_null(self) do { (self)->type = 0; } while(0)
bool pkpy_Var__eq__(void *vm, PyVar a, PyVar b);
int64_t pkpy_Var__hash__(void *vm, PyVar a);
extern const pkpy_Type tp_object, tp_type;
extern const pkpy_Type tp_int, tp_float, tp_bool, tp_str;
extern const pkpy_Type tp_list, tp_tuple;
extern const pkpy_Type tp_slice, tp_range, tp_module;
extern const pkpy_Type tp_function, tp_native_func, tp_bound_method;
extern const pkpy_Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
extern const pkpy_Type tp_dict, tp_property, tp_star_wrapper;
extern const pkpy_Type tp_staticmethod, tp_classmethod;
extern const pkpy_Type tp_none_type, tp_not_implemented_type;
extern const pkpy_Type tp_ellipsis;
extern const PyVar pkpy_True, pkpy_False, pkpy_None;
extern const PyVar pkpy_NotImplemented, pkpy_Ellipsis;
extern const PyVar pkpy_NULL;
#ifdef __cplusplus
}
#endif

View File

@ -2,6 +2,7 @@
#include "pocketpy/common/types.hpp" #include "pocketpy/common/types.hpp"
#include "pocketpy/common/traits.hpp" #include "pocketpy/common/traits.hpp"
#include "pocketpy/objects/base.h"
#include <cstdint> #include <cstdint>
#include <cassert> #include <cassert>
@ -11,29 +12,15 @@
namespace pkpy { namespace pkpy {
struct Type { struct Type {
int16_t index; pkpy_Type index;
constexpr Type() : index(0) {} constexpr Type() : index(0) {}
constexpr Type(pkpy_Type index) : index(index) {}
explicit constexpr Type(int index) : index(index) {}
bool operator== (Type other) const { return this->index == other.index; } bool operator== (Type other) const { return this->index == other.index; }
bool operator!= (Type other) const { return this->index != other.index; } bool operator!= (Type other) const { return this->index != other.index; }
constexpr operator pkpy_Type () const { return index; }
constexpr operator int () const { return index; }
}; };
struct const_sso_var {}; struct PyVar final: ::PyVar {
struct PyVar final {
Type type;
bool is_ptr;
uint8_t flags;
// 12 bytes SSO
int _0;
i64 _1;
// uninitialized // uninitialized
PyVar() = default; PyVar() = default;
@ -41,20 +28,29 @@ struct PyVar final {
PyVar(PyObject* p); PyVar(PyObject* p);
/* We must initialize all members to allow == operator to work correctly */ /* We must initialize all members to allow == operator to work correctly */
// constexpr initialized
constexpr PyVar(const const_sso_var&, Type type, int value) :
type(type), is_ptr(false), flags(0), _0(value), _1(0) {}
// zero initialized // zero initialized
constexpr PyVar(std::nullptr_t) : type(0), is_ptr(false), flags(0), _0(0), _1(0) {} PyVar(std::nullptr_t){
set_null();
}
// PyObject* initialized (is_sso = false) // PyObject* initialized (is_sso = false)
PyVar(Type type, PyObject* p) : type(type), is_ptr(true), flags(0), _0(0), _1(reinterpret_cast<i64>(p)) {} PyVar(Type type, PyObject* p){
this->type = type;
this->is_ptr = true;
this->flags = 0;
this->flags_ex = 0;
this->_obj = (::PyObject*)p;
}
// SSO initialized (is_sso = true) // SSO initialized (is_sso = true)
template <typename T> template <typename T>
PyVar(Type type, T value) : type(type), is_ptr(false), flags(0), _0(0), _1(0) { PyVar(Type type, T value){
static_assert(sizeof(T) <= 12, "SSO size exceeded"); static_assert(sizeof(T) <= 12, "SSO size exceeded");
this->type = type;
this->is_ptr = false;
this->flags = 0;
this->flags_ex = 0;
this->_i64 = 0;
as<T>() = value; as<T>() = value;
} }
@ -62,9 +58,9 @@ struct PyVar final {
T& as() { T& as() {
static_assert(!std::is_reference_v<T>); static_assert(!std::is_reference_v<T>);
if constexpr(sizeof(T) <= 8) { if constexpr(sizeof(T) <= 8) {
return reinterpret_cast<T&>(_1); return reinterpret_cast<T&>(_i64);
} else { } else {
return reinterpret_cast<T&>(_0); return reinterpret_cast<T&>(flags_ex);
} }
} }
@ -89,21 +85,26 @@ struct PyVar final {
PyObject* get() const { PyObject* get() const {
assert(is_ptr); assert(is_ptr);
return reinterpret_cast<PyObject*>(_1); return (PyObject*)_obj;
} }
PyObject* operator->() const { PyObject* operator->() const {
assert(is_ptr); assert(is_ptr);
return reinterpret_cast<PyObject*>(_1); return (PyObject*)_obj;
} }
i64 hash() const { return _0 + _1; } i64 hash() const { return PyVar__hash(this); }
template <typename T> template <typename T>
obj_get_t<T> obj_get(); obj_get_t<T> obj_get();
// std::less<> for map-like containers // std::less<> for map-like containers
bool operator< (const PyVar& other) const { return memcmp(this, &other, sizeof(PyVar)) < 0; } bool operator< (const PyVar& other) const { return memcmp(this, &other, sizeof(PyVar)) < 0; }
// implicit convert from ::PyVar
PyVar(const ::PyVar& var) {
memcpy(this, &var, sizeof(var));
}
}; };
static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>); static_assert(sizeof(PyVar) == 16 && is_pod_v<PyVar>);

View File

@ -82,13 +82,13 @@ const inline int16_t kTpNotImplementedTypeIndex = 25;
inline bool is_tagged(PyVar p) noexcept { return !p.is_ptr; } inline bool is_tagged(PyVar p) noexcept { return !p.is_ptr; }
inline bool is_float(PyVar p) noexcept { return p.type.index == kTpFloatIndex; } inline bool is_float(PyVar p) noexcept { return p.type == kTpFloatIndex; }
inline bool is_int(PyVar p) noexcept { return p.type.index == kTpIntIndex; } inline bool is_int(PyVar p) noexcept { return p.type == kTpIntIndex; }
inline bool is_none(PyVar p) noexcept { return p.type.index == kTpNoneTypeIndex; } inline bool is_none(PyVar p) noexcept { return p.type == kTpNoneTypeIndex; }
inline bool is_not_implemented(PyVar p) noexcept { return p.type.index == kTpNotImplementedTypeIndex; } inline bool is_not_implemented(PyVar p) noexcept { return p.type == kTpNotImplementedTypeIndex; }
inline bool is_type(PyVar obj, Type type) { inline bool is_type(PyVar obj, Type type) {
assert(obj != nullptr); assert(obj != nullptr);
@ -121,7 +121,7 @@ obj_get_t<T> PyVar::obj_get() {
return as<T>(); return as<T>();
} else { } else {
assert(is_ptr); assert(is_ptr);
void* v = ((PyObject*)_1)->_value_ptr(); void* v = PyObject__value_ptr(_obj);
return *reinterpret_cast<T*>(v); return *reinterpret_cast<T*>(v);
} }
} }
@ -139,9 +139,8 @@ obj_get_t<T> PyVar::obj_get() {
#define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value) #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
/*****************************************************************/ /*****************************************************************/
#define PY_NULL nullptr #define PY_NULL nullptr
extern PyVar const PY_OP_CALL; extern PyVar PY_OP_CALL;
extern const PyVar PY_OP_YIELD; extern PyVar PY_OP_YIELD;
} // namespace pkpy } // namespace pkpy

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include "pocketpy/objects/pyvar.h" #include "pocketpy/objects/base.h"
#include "pocketpy/common/vector.h" #include "pocketpy/common/vector.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -49,7 +49,7 @@ pkpy_Dict pkpy_Dict__copy(const pkpy_Dict* self);
* @param val value to set * @param val value to set
* @return `true` if the key is newly added, `false` if the key already exists * @return `true` if the key is newly added, `false` if the key already exists
*/ */
bool pkpy_Dict__set(pkpy_Dict* self, void* vm, pkpy_Var key, pkpy_Var val); bool pkpy_Dict__set(pkpy_Dict* self, void* vm, PyVar key, PyVar val);
/** /**
* @brief Check if a key exists in the `pkpy_Dict` * @brief Check if a key exists in the `pkpy_Dict`
@ -58,7 +58,7 @@ bool pkpy_Dict__set(pkpy_Dict* self, void* vm, pkpy_Var key, pkpy_Var val);
* @param key key to check * @param key key to check
* @return `true` if the key exists, `false` otherwise * @return `true` if the key exists, `false` otherwise
*/ */
bool pkpy_Dict__contains(const pkpy_Dict* self, void* vm, pkpy_Var key); bool pkpy_Dict__contains(const pkpy_Dict* self, void* vm, PyVar key);
/** /**
* @brief Remove a key from the `pkpy_Dict` * @brief Remove a key from the `pkpy_Dict`
@ -67,7 +67,7 @@ bool pkpy_Dict__contains(const pkpy_Dict* self, void* vm, pkpy_Var key);
* @param key key to remove * @param key key to remove
* @return `true` if the key was found and removed, `false` if the key doesn't exist * @return `true` if the key was found and removed, `false` if the key doesn't exist
*/ */
bool pkpy_Dict__del(pkpy_Dict* self, void* vm, pkpy_Var key); bool pkpy_Dict__del(pkpy_Dict* self, void* vm, PyVar key);
/** /**
* @brief Try to get a value from the `pkpy_Dict` * @brief Try to get a value from the `pkpy_Dict`
@ -76,7 +76,7 @@ bool pkpy_Dict__del(pkpy_Dict* self, void* vm, pkpy_Var key);
* @param key key to get * @param key key to get
* @return the value associated with the key, `NULL` if the key doesn't exist * @return the value associated with the key, `NULL` if the key doesn't exist
*/ */
const pkpy_Var* pkpy_Dict__try_get(const pkpy_Dict* self, void* vm, pkpy_Var key); const PyVar* pkpy_Dict__try_get(const pkpy_Dict* self, void* vm, PyVar key);
/** /**
* @brief Update the `pkpy_Dict` with another one * @brief Update the `pkpy_Dict` with another one
@ -106,7 +106,7 @@ pkpy_DictIter pkpy_Dict__iter(const pkpy_Dict* self);
* @param value value will be filled with the current value, can be `NULL` if not needed * @param value value will be filled with the current value, can be `NULL` if not needed
* @return `true` if the iteration is still valid, `false` otherwise * @return `true` if the iteration is still valid, `false` otherwise
*/ */
bool pkpy_DictIter__next(pkpy_DictIter* self, pkpy_Var* key, pkpy_Var* value); bool pkpy_DictIter__next(pkpy_DictIter* self, PyVar* key, PyVar* value);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -28,21 +28,21 @@ struct Dict : private pkpy_Dict {
int size() const { return count; } int size() const { return count; }
void set(VM* vm, PyVar key, PyVar val) { void set(VM* vm, PyVar key, PyVar val) {
pkpy_Dict__set(this, vm, *(pkpy_Var*)(&key), *(pkpy_Var*)(&val)); pkpy_Dict__set(this, vm, *(::PyVar*)(&key), *(::PyVar*)(&val));
} }
PyVar try_get(VM* vm, PyVar key) const { PyVar try_get(VM* vm, PyVar key) const {
auto res = pkpy_Dict__try_get(this, vm, *(pkpy_Var*)(&key)); auto res = pkpy_Dict__try_get(this, vm, *(::PyVar*)(&key));
if (!res) return nullptr; if (!res) return nullptr;
return *(const PyVar*)(res); return *(const PyVar*)(res);
} }
bool contains(VM* vm, PyVar key) const { bool contains(VM* vm, PyVar key) const {
return pkpy_Dict__contains(this, vm, *(pkpy_Var*)(&key)); return pkpy_Dict__contains(this, vm, *(::PyVar*)(&key));
} }
bool del(VM* vm, PyVar key) { bool del(VM* vm, PyVar key) {
return pkpy_Dict__del(this, vm, *(pkpy_Var*)(&key)); return pkpy_Dict__del(this, vm, *(::PyVar*)(&key));
} }
void update(VM* vm, const Dict& other) { void update(VM* vm, const Dict& other) {
@ -53,7 +53,7 @@ struct Dict : private pkpy_Dict {
void apply(__Func f) const { void apply(__Func f) const {
pkpy_DictIter it = iter(); pkpy_DictIter it = iter();
PyVar key, val; PyVar key, val;
while(pkpy_DictIter__next(&it, (pkpy_Var*)(&key), (pkpy_Var*)(&val))) { while(pkpy_DictIter__next(&it, (::PyVar*)(&key), (::PyVar*)(&val))) {
f(key, val); f(key, val);
} }
} }
@ -63,7 +63,7 @@ struct Dict : private pkpy_Dict {
pkpy_DictIter it = iter(); pkpy_DictIter it = iter();
PyVar key, val; PyVar key, val;
int i = 0; int i = 0;
while(pkpy_DictIter__next(&it, (pkpy_Var*)(&key), (pkpy_Var*)(&val))) { while(pkpy_DictIter__next(&it, (::PyVar*)(&key), (::PyVar*)(&val))) {
res[i++] = key; res[i++] = key;
} }
return res; return res;
@ -74,7 +74,7 @@ struct Dict : private pkpy_Dict {
pkpy_DictIter it = iter(); pkpy_DictIter it = iter();
PyVar key, val; PyVar key, val;
int i = 0; int i = 0;
while(pkpy_DictIter__next(&it, (pkpy_Var*)(&key), (pkpy_Var*)(&val))) { while(pkpy_DictIter__next(&it, (::PyVar*)(&key), (::PyVar*)(&val))) {
res[i++] = val; res[i++] = val;
} }
return res; return res;

View File

@ -2,23 +2,20 @@
#include "pocketpy/common/vector.h" #include "pocketpy/common/vector.h"
#include "pocketpy/common/str.h" #include "pocketpy/common/str.h"
#include "pocketpy/objects/base.h"
#include <stdint.h> #include <stdint.h>
#include "pocketpy/objects/pyvar.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define SMALLMAP_T__HEADER #define SMALLMAP_T__HEADER
#define K uint16_t #define K uint16_t
#define V pkpy_Var #define V PyVar
#define TAG n2v #define NAME pkpy_NameDict
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__HEADER #undef SMALLMAP_T__HEADER
typedef c11_smallmap_n2v pkpy_NameDict;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -6,6 +6,8 @@
#include "pocketpy/objects/object.hpp" #include "pocketpy/objects/object.hpp"
#include "pocketpy/objects/namedict.h" #include "pocketpy/objects/namedict.h"
#include <string_view>
namespace pkpy { namespace pkpy {
struct NameDict: pkpy_NameDict { struct NameDict: pkpy_NameDict {
@ -14,11 +16,11 @@ struct NameDict: pkpy_NameDict {
using Item = pair<StrName, PyVar>; using Item = pair<StrName, PyVar>;
NameDict() { NameDict() {
c11_smallmap_n2v__ctor(this); pkpy_NameDict__ctor(this);
} }
~NameDict() { ~NameDict() {
c11_smallmap_n2v__dtor(this); pkpy_NameDict__dtor(this);
} }
uint16_t size() const { uint16_t size() const {
@ -26,18 +28,19 @@ struct NameDict: pkpy_NameDict {
} }
void set(StrName key, PyVar val){ void set(StrName key, PyVar val){
pkpy_Var* p = (pkpy_Var*)&val; PyVar* p = (PyVar*)&val;
c11_smallmap_n2v__set(this, key.index, *p); pkpy_NameDict__set(this, key.index, *p);
} }
PyVar try_get(StrName key) const{ PyVar try_get(StrName key) const{
PyVar* p = try_get_2(key); PyVar* p = try_get_2(key);
return p ? *p : nullptr; if(p) return *p;
return nullptr;
} }
PyVar* try_get_2(StrName key) const{ PyVar* try_get_2(StrName key) const{
pkpy_Var* p = c11_smallmap_n2v__try_get(this, key.index); PyVar* p = (PyVar*)pkpy_NameDict__try_get(this, key.index);
return p ? (PyVar*)p : nullptr; return p;
} }
PyVar try_get_likely_found(StrName key) const{ PyVar try_get_likely_found(StrName key) const{
@ -49,11 +52,11 @@ struct NameDict: pkpy_NameDict {
} }
bool del(StrName key){ bool del(StrName key){
return c11_smallmap_n2v__del(this, key.index); return pkpy_NameDict__del(this, key.index);
} }
bool contains(StrName key) const{ bool contains(StrName key) const{
return c11_smallmap_n2v__contains(this, key.index); return pkpy_NameDict__contains(this, key.index);
} }
PyVar operator[] (StrName key) const{ PyVar operator[] (StrName key) const{
@ -65,13 +68,13 @@ struct NameDict: pkpy_NameDict {
} }
void clear(){ void clear(){
c11_smallmap_n2v__clear(this); pkpy_NameDict__clear(this);
} }
array<StrName> keys() const{ array<StrName> keys() const{
array<StrName> retval((int)size()); array<StrName> retval((int)size());
for(int i=0; i<size(); i++){ for(int i=0; i<size(); i++){
auto it = c11__at(c11_smallmap_entry_n2v, this, i); auto it = c11__at(pkpy_NameDict_KV, this, i);
retval[i] = StrName(it->key); retval[i] = StrName(it->key);
} }
return retval; return retval;
@ -80,7 +83,7 @@ struct NameDict: pkpy_NameDict {
array<Item> items() const{ array<Item> items() const{
array<Item> retval((int)size()); array<Item> retval((int)size());
for(int i=0; i<size(); i++){ for(int i=0; i<size(); i++){
auto it = c11__at(c11_smallmap_entry_n2v, this, i); auto it = c11__at(pkpy_NameDict_KV, this, i);
PyVar* p = (PyVar*)&it->value; PyVar* p = (PyVar*)&it->value;
retval[i] = Item(StrName(it->key), *p); retval[i] = Item(StrName(it->key), *p);
} }
@ -89,7 +92,7 @@ struct NameDict: pkpy_NameDict {
void apply(void (*f)(StrName, PyVar, void*), void* data){ void apply(void (*f)(StrName, PyVar, void*), void* data){
for(int i=0; i<size(); i++){ for(int i=0; i<size(); i++){
auto it = c11__at(c11_smallmap_entry_n2v, this, i); auto it = c11__at(pkpy_NameDict_KV, this, i);
PyVar* p = (PyVar*)&it->value; PyVar* p = (PyVar*)&it->value;
f(StrName(it->key), *p, data); f(StrName(it->key), *p, data);
} }

View File

@ -0,0 +1,41 @@
#pragma once
#include "pocketpy/objects/namedict.h"
#include "pocketpy/objects/base.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct PyObject{
pkpy_Type type; // we have a duplicated type here for convenience
bool gc_is_large;
bool gc_marked;
pkpy_NameDict* _attr; // gc will delete this on destruction
} PyObject;
static_assert(sizeof(PyObject) <= 16, "!(sizeof(PyObject) <= 16)");
#define PyObject__value_ptr(self) ((char*)self + 16)
#define PyObject__as(T, self) (T*)(PyObject__value_ptr(self))
PK_INLINE void PyObject__ctor(PyObject* self, pkpy_Type type, bool gc_is_large){
self->type = type;
self->gc_is_large = gc_is_large;
self->gc_marked = false;
self->_attr = NULL;
}
PK_INLINE PyVar PyVar__fromobj(PyObject* self){
PyVar var;
var.type = self->type;
var.is_ptr = true;
var.flags = 0;
var.flags_ex = 0;
var._obj = self;
return var;
}
#ifdef __cplusplus
}
#endif

View File

@ -3,35 +3,35 @@
#include "pocketpy/common/str.hpp" #include "pocketpy/common/str.hpp"
#include "pocketpy/common/config.h" #include "pocketpy/common/config.h"
#include "pocketpy/objects/base.hpp" #include "pocketpy/objects/base.hpp"
#include "pocketpy/objects/object.h"
namespace pkpy { namespace pkpy {
struct NameDict; struct NameDict;
struct PyObject final { struct PyObject final: ::PyObject {
Type type; // we have a duplicated type here for convenience
bool gc_is_large;
bool gc_marked;
NameDict* _attr; // gc will delete this on destruction
bool is_attr_valid() const noexcept { return _attr != nullptr; } bool is_attr_valid() const noexcept { return _attr != nullptr; }
void* _value_ptr() noexcept { return (char*)this + 16; } void* _value_ptr() noexcept { return (char*)this + 16; }
NameDict& attr() const{
return *(NameDict*)_attr;
}
PyVar attr(StrName name) const;
template <typename T> template <typename T>
T& as() noexcept { T& as() noexcept {
static_assert(std::is_same_v<T, std::decay_t<T>>); static_assert(std::is_same_v<T, std::decay_t<T>>);
return *reinterpret_cast<T*>(_value_ptr()); return *reinterpret_cast<T*>(_value_ptr());
} }
NameDict& attr() { PyObject(Type type, bool gc_is_large){
assert(is_attr_valid()); this->type = type;
return *_attr; this->gc_is_large = gc_is_large;
this->gc_marked = false;
this->_attr = nullptr;
} }
PyObject(Type type, bool gc_is_large) : type(type), gc_is_large(gc_is_large), gc_marked(false), _attr(nullptr) {}
PyVar attr(StrName name) const;
}; };
static_assert(sizeof(PyObject) <= 16); static_assert(sizeof(PyObject) <= 16);

View File

@ -1,51 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief A python value in pocketpy.
*/
typedef struct {
int type;
int _0;
int64_t _1;
} pkpy_Var;
/**
* @brief Check if the pkpy_Var is null.
* @param self The variable to check.
* @return True if the variable is null, false otherwise.
*/
#define pkpy_Var__is_null(self) ((self)->type == 0)
/**
* @brief Set the variable to null.
* @param self The variable to set.
*/
#define pkpy_Var__set_null(self) do { (self)->type = 0; } while(0)
/**
* @brief Check if two pkpy_Vars are equal, respects to __eq__ method.
* @param vm The virtual machine.
* @param a The first pkpy_Var.
* @param b The second pkpy_Var.
* @return True if the pkpy_Vars are equal, false otherwise.
*/
bool pkpy_Var__eq__(void *vm, pkpy_Var a, pkpy_Var b);
/**
* @brief Get the hash of the pkpy_Var, respects to __hash__ method.
* @param vm The virtual machine.
* @param a The pkpy_Var to hash.
* @return The hash of the pkpy_Var.
*/
int64_t pkpy_Var__hash__(void *vm, pkpy_Var a);
#ifdef __cplusplus
}
#endif

View File

@ -1,15 +1,15 @@
#ifndef POCKETPY_C_H #ifndef POCKETPY_C_H
#define POCKETPY_C_H #define POCKETPY_C_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "pocketpy/common/export.h" #include "pocketpy/common/export.h"
#ifdef __cplusplus
extern "C" {
namespace pkpy{
#endif
typedef struct pkpy_vm_handle pkpy_vm; typedef struct pkpy_vm_handle pkpy_vm;
typedef int (*pkpy_CFunction)(pkpy_vm*); typedef int (*pkpy_CFunction)(pkpy_vm*);
typedef void (*pkpy_COutputHandler)(const char*, int); typedef void (*pkpy_COutputHandler)(const char*, int);
@ -101,6 +101,7 @@ extern "C" {
PK_EXPORT void pkpy_delete_repl(void* repl); PK_EXPORT void pkpy_delete_repl(void* repl);
#ifdef __cplusplus #ifdef __cplusplus
} }
}
#endif #endif
#endif #endif

View File

@ -6,7 +6,7 @@
/* Input */ /* Input */
#define K int #define K int
#define V float #define V float
#define TAG int_float #define NAME c11_smallmap_i2f
#endif #endif
/* Optional Input */ /* Optional Input */
@ -23,9 +23,8 @@
#define CONCAT(A, B) CONCAT_(A, B) #define CONCAT(A, B) CONCAT_(A, B)
#define CONCAT_(A, B) A##B #define CONCAT_(A, B) A##B
#define KV CONCAT(c11_smallmap_entry_, TAG) #define KV CONCAT(NAME, _KV)
#define SMALLMAP CONCAT(c11_smallmap_, TAG) #define METHOD(name) CONCAT(NAME, CONCAT(__, name))
#define SMALLMAP_METHOD(name) CONCAT(SMALLMAP, CONCAT(__, name))
#ifdef SMALLMAP_T__HEADER #ifdef SMALLMAP_T__HEADER
/* Declaration */ /* Declaration */
@ -34,32 +33,32 @@ typedef struct {
V value; V value;
} KV; } KV;
typedef c11_vector SMALLMAP; typedef c11_vector NAME;
void SMALLMAP_METHOD(ctor)(SMALLMAP* self); void METHOD(ctor)(NAME* self);
void SMALLMAP_METHOD(dtor)(SMALLMAP* self); void METHOD(dtor)(NAME* self);
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value); void METHOD(set)(NAME* self, K key, V value);
V* SMALLMAP_METHOD(try_get)(const SMALLMAP* self, K key); V* METHOD(try_get)(const NAME* self, K key);
V SMALLMAP_METHOD(get)(const SMALLMAP* self, K key, V default_value); V METHOD(get)(const NAME* self, K key, V default_value);
bool SMALLMAP_METHOD(contains)(const SMALLMAP* self, K key); bool METHOD(contains)(const NAME* self, K key);
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key); bool METHOD(del)(NAME* self, K key);
void SMALLMAP_METHOD(clear)(SMALLMAP* self); void METHOD(clear)(NAME* self);
#endif #endif
#ifdef SMALLMAP_T__SOURCE #ifdef SMALLMAP_T__SOURCE
/* Implementation */ /* Implementation */
void SMALLMAP_METHOD(ctor)(SMALLMAP* self) { void METHOD(ctor)(NAME* self) {
c11_vector__ctor(self, sizeof(KV)); c11_vector__ctor(self, sizeof(KV));
c11_vector__reserve(self, 4); c11_vector__reserve(self, 4);
} }
void SMALLMAP_METHOD(dtor)(SMALLMAP* self) { void METHOD(dtor)(NAME* self) {
c11_vector__dtor(self); c11_vector__dtor(self);
} }
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value) { void METHOD(set)(NAME* self, K key, V value) {
int index; int index;
c11__lower_bound(KV, self->data, self->count, key, partial_less, &index); c11__lower_bound(KV, self->data, self->count, key, partial_less, &index);
KV* it = c11__at(KV, self, index); KV* it = c11__at(KV, self, index);
@ -71,7 +70,7 @@ void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value) {
} }
} }
V* SMALLMAP_METHOD(try_get)(const SMALLMAP* self, K key) { V* METHOD(try_get)(const NAME* self, K key) {
// use `bsearch` which is faster than `lower_bound` // use `bsearch` which is faster than `lower_bound`
int low = 0; int low = 0;
int high = self->count - 1; int high = self->count - 1;
@ -89,16 +88,16 @@ V* SMALLMAP_METHOD(try_get)(const SMALLMAP* self, K key) {
return NULL; return NULL;
} }
V SMALLMAP_METHOD(get)(const SMALLMAP* self, K key, V default_value) { V METHOD(get)(const NAME* self, K key, V default_value) {
V* p = SMALLMAP_METHOD(try_get)(self, key); V* p = METHOD(try_get)(self, key);
return p ? *p : default_value; return p ? *p : default_value;
} }
bool SMALLMAP_METHOD(contains)(const SMALLMAP* self, K key) { bool METHOD(contains)(const NAME* self, K key) {
return SMALLMAP_METHOD(try_get)(self, key) != NULL; return METHOD(try_get)(self, key) != NULL;
} }
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key) { bool METHOD(del)(NAME* self, K key) {
int index; int index;
c11__lower_bound(KV, self->data, self->count, key, partial_less, &index); c11__lower_bound(KV, self->data, self->count, key, partial_less, &index);
KV* it = c11__at(KV, self, index); KV* it = c11__at(KV, self, index);
@ -109,7 +108,7 @@ bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key) {
return false; return false;
} }
void SMALLMAP_METHOD(clear)(SMALLMAP* self) { void METHOD(clear)(NAME* self) {
c11_vector__clear(self); c11_vector__clear(self);
} }
@ -117,14 +116,13 @@ void SMALLMAP_METHOD(clear)(SMALLMAP* self) {
/* Undefine all macros */ /* Undefine all macros */
#undef KV #undef KV
#undef SMALLMAP #undef METHOD
#undef SMALLMAP_METHOD
#undef CONCAT #undef CONCAT
#undef CONCAT_ #undef CONCAT_
#undef K #undef K
#undef V #undef V
#undef TAG #undef NAME
#undef less #undef less
#undef partial_less #undef partial_less
#undef equal #undef equal

View File

@ -3,7 +3,7 @@
#define SMALLMAP_T__SOURCE #define SMALLMAP_T__SOURCE
#define K uint16_t #define K uint16_t
#define V int #define V int
#define TAG n2i #define NAME c11_smallmap_n2i
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__SOURCE #undef SMALLMAP_T__SOURCE
@ -11,7 +11,7 @@
#define SMALLMAP_T__SOURCE #define SMALLMAP_T__SOURCE
#define K c11_string #define K c11_string
#define V uint16_t #define V uint16_t
#define TAG s2n #define NAME c11_smallmap_s2n
#define less(a, b) (c11_string__cmp((a), (b)) < 0) #define less(a, b) (c11_string__cmp((a), (b)) < 0)
#define equal(a, b) (c11_string__cmp((a), (b)) == 0) #define equal(a, b) (c11_string__cmp((a), (b)) == 0)
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"

View File

@ -637,7 +637,7 @@ Error* Lexer::precompile(Str* out) noexcept{
ss << "=" << (int)token_indices.count << '\n'; // L3: raw string count ss << "=" << (int)token_indices.count << '\n'; // L3: raw string count
uint16_t index = 0; uint16_t index = 0;
for(int i=0; i<token_indices.count; i++){ for(int i=0; i<token_indices.count; i++){
c11_smallmap_entry_s2n* kv = c11__at(c11_smallmap_entry_s2n, &token_indices, i); auto kv = c11__at(c11_smallmap_s2n_KV, &token_indices, i);
ss << kv->key << '\n'; // L4: raw strings ss << kv->key << '\n'; // L4: raw strings
kv->value = index++; kv->value = index++;
} }

View File

@ -475,7 +475,7 @@ PyVar VM::__run_top_frame() {
DISPATCH() DISPATCH()
case OP_BUILD_SET: { case OP_BUILD_SET: {
PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
_0 = call(builtins->attr(pk_id_set), _0); _0 = call(builtins->attr()[pk_id_set], _0);
STACK_SHRINK(byte.arg); STACK_SHRINK(byte.arg);
PUSH(_0); PUSH(_0);
} }
@ -526,7 +526,7 @@ PyVar VM::__run_top_frame() {
__unpack_as_list(STACK_VIEW(byte.arg), list); __unpack_as_list(STACK_VIEW(byte.arg), list);
STACK_SHRINK(byte.arg); STACK_SHRINK(byte.arg);
PyVar _0 = VAR(std::move(list)); PyVar _0 = VAR(std::move(list));
_0 = call(builtins->attr(pk_id_set), _0); _0 = call(builtins->attr()[pk_id_set], _0);
PUSH(_0); PUSH(_0);
} }
DISPATCH() DISPATCH()

View File

@ -267,7 +267,7 @@ void add_module_c(VM* vm) {
#undef BIND_PRIMITIVE #undef BIND_PRIMITIVE
PyObject* char_p_t = mod->attr("char_p").get(); PyObject* char_p_t = mod->attr()["char_p"].get();
vm->bind(char_p_t, "read_string(self) -> str", [](VM* vm, ArgsView args) { vm->bind(char_p_t, "read_string(self) -> str", [](VM* vm, ArgsView args) {
obj_get_t<VoidP> voidp = PK_OBJ_GET(VoidP, args[0]); obj_get_t<VoidP> voidp = PK_OBJ_GET(VoidP, args[0]);
const char* target = (const char*)voidp.ptr; const char* target = (const char*)voidp.ptr;

View File

@ -11,7 +11,7 @@ PyVar* FastLocals::try_get_name(StrName name) {
NameDict* FastLocals::to_namedict() { NameDict* FastLocals::to_namedict() {
NameDict* dict = new NameDict(); NameDict* dict = new NameDict();
for(int i=0; i<co->varnames_inv.count; i++){ for(int i=0; i<co->varnames_inv.count; i++){
auto entry = c11__getitem(c11_smallmap_entry_n2i, &co->varnames_inv, i); auto entry = c11__getitem(c11_smallmap_n2i_KV, &co->varnames_inv, i);
PyVar value = a[entry.value]; PyVar value = a[entry.value];
if(value) dict->set(StrName(entry.key), value); if(value) dict->set(StrName(entry.key), value);
} }

View File

@ -118,7 +118,7 @@ void DictItemsIter::_register(VM* vm, PyObject* mod, PyObject* type) {
vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned { vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
DictItemsIter& self = _CAST(DictItemsIter&, _0); DictItemsIter& self = _CAST(DictItemsIter&, _0);
PyVar key, val; PyVar key, val;
if (pkpy_DictIter__next(&self.it, (pkpy_Var*)(&key), (pkpy_Var*)(&val))) { if (pkpy_DictIter__next(&self.it, (PyVar*)(&key), (PyVar*)(&val))) {
vm->s_data.push(key); vm->s_data.push(key);
vm->s_data.push(val); vm->s_data.push(val);
return 2; return 2;

View File

@ -254,7 +254,7 @@ PyVar VM::py_op(std::string_view name) {
PyVar func; PyVar func;
auto it = __cached_op_funcs.try_get(name); auto it = __cached_op_funcs.try_get(name);
if(it == nullptr) { if(it == nullptr) {
func = py_import("operator")->attr(StrName::get(name)); func = py_import("operator")->attr()[StrName::get(name)];
__cached_op_funcs.insert(name, func); __cached_op_funcs.insert(name, func);
} else { } else {
func = *it; func = *it;
@ -283,11 +283,11 @@ PyVar VM::py_next(PyVar obj) {
bool VM::py_callable(PyVar obj) { bool VM::py_callable(PyVar obj) {
Type cls = vm->_tp(obj); Type cls = vm->_tp(obj);
switch(cls.index) { switch(cls) {
case VM::tp_function.index: return true; case VM::tp_function: return true;
case VM::tp_native_func.index: return true; case VM::tp_native_func: return true;
case VM::tp_bound_method.index: return true; case VM::tp_bound_method: return true;
case VM::tp_type.index: return true; case VM::tp_type: return true;
} }
return vm->find_name_in_mro(cls, __call__) != nullptr; return vm->find_name_in_mro(cls, __call__) != nullptr;
} }
@ -538,7 +538,7 @@ i64 VM::py_hash(PyVar obj) {
has_custom_eq = true; has_custom_eq = true;
else { else {
f = get_unbound_method(obj, __eq__, &self, false); f = get_unbound_method(obj, __eq__, &self, false);
has_custom_eq = f != _t(tp_object)->attr(__eq__); has_custom_eq = f != _t(tp_object)->attr()[__eq__];
} }
if(has_custom_eq) { if(has_custom_eq) {
TypeError(_S("unhashable type: ", ti->name.escape())); TypeError(_S("unhashable type: ", ti->name.escape()));
@ -1228,11 +1228,11 @@ PyVar VM::getattr(PyVar obj, StrName name, bool throw_err) {
if(cls_var != nullptr) { if(cls_var != nullptr) {
// bound method is non-data descriptor // bound method is non-data descriptor
if(!is_tagged(*cls_var)) { if(!is_tagged(*cls_var)) {
switch(cls_var->type.index) { switch(cls_var->type) {
case tp_function.index: return VAR(BoundMethod(obj, *cls_var)); case tp_function: return VAR(BoundMethod(obj, *cls_var));
case tp_native_func.index: return VAR(BoundMethod(obj, *cls_var)); case tp_native_func: return VAR(BoundMethod(obj, *cls_var));
case tp_staticmethod.index: return PK_OBJ_GET(StaticMethod, *cls_var).func; case tp_staticmethod: return PK_OBJ_GET(StaticMethod, *cls_var).func;
case tp_classmethod.index: return VAR(BoundMethod(_t(objtype), PK_OBJ_GET(ClassMethod, *cls_var).func)); case tp_classmethod: return VAR(BoundMethod(_t(objtype), PK_OBJ_GET(ClassMethod, *cls_var).func));
} }
} }
return *cls_var; return *cls_var;
@ -1291,11 +1291,11 @@ PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_er
if(cls_var != nullptr) { if(cls_var != nullptr) {
if(!is_tagged(*cls_var)) { if(!is_tagged(*cls_var)) {
switch(cls_var->type.index) { switch(cls_var->type) {
case tp_function.index: *self = obj; break; case tp_function: *self = obj; break;
case tp_native_func.index: *self = obj; break; case tp_native_func: *self = obj; break;
case tp_staticmethod.index: self->set_null(); return PK_OBJ_GET(StaticMethod, *cls_var).func; case tp_staticmethod: self->set_null(); return PK_OBJ_GET(StaticMethod, *cls_var).func;
case tp_classmethod.index: *self = _t(objtype); return PK_OBJ_GET(ClassMethod, *cls_var).func; case tp_classmethod: *self = _t(objtype); return PK_OBJ_GET(ClassMethod, *cls_var).func;
} }
} }
return *cls_var; return *cls_var;
@ -1395,9 +1395,9 @@ PyObject* VM::bind_property(PyObject* obj, const char* name, NativeFuncC fget, N
return prop; return prop;
} }
void VM::__builtin_error(StrName type) { _error(call(builtins->attr(type))); } void VM::__builtin_error(StrName type) { _error(call(builtins->attr()[type])); }
void VM::__builtin_error(StrName type, PyVar arg) { _error(call(builtins->attr(type), arg)); } void VM::__builtin_error(StrName type, PyVar arg) { _error(call(builtins->attr()[type], arg)); }
void VM::__builtin_error(StrName type, const Str& msg) { __builtin_error(type, VAR(msg)); } void VM::__builtin_error(StrName type, const Str& msg) { __builtin_error(type, VAR(msg)); }
@ -1796,11 +1796,8 @@ void VM::__breakpoint() {
#endif #endif
} }
/**************************************************************************/
PyVar PyObject::attr(StrName name) const{ PyVar PyObject::attr(StrName name) const{
assert(is_attr_valid()); return attr()[name];
return (*_attr)[name];
} }
/**************************************************************************/ /**************************************************************************/

View File

@ -149,11 +149,11 @@ struct Array2d {
HANDLE_SLICE(); HANDLE_SLICE();
bool is_basic_type = false; bool is_basic_type = false;
switch(vm->_tp(_2).index) { switch(vm->_tp(_2)) {
case VM::tp_int.index: is_basic_type = true; break; case VM::tp_int: is_basic_type = true; break;
case VM::tp_float.index: is_basic_type = true; break; case VM::tp_float: is_basic_type = true; break;
case VM::tp_str.index: is_basic_type = true; break; case VM::tp_str: is_basic_type = true; break;
case VM::tp_bool.index: is_basic_type = true; break; case VM::tp_bool: is_basic_type = true; break;
default: is_basic_type = is_none(_2); default: is_basic_type = is_none(_2);
} }

View File

@ -65,7 +65,7 @@ void add_module_csv(VM* vm) {
}); });
vm->bind(mod, "DictReader(csvfile: list[str]) -> list[dict]", [](VM* vm, ArgsView args) { vm->bind(mod, "DictReader(csvfile: list[str]) -> list[dict]", [](VM* vm, ArgsView args) {
PyVar csv_reader = vm->_modules["csv"]->attr("reader"); PyVar csv_reader = vm->_modules["csv"]->attr()["reader"];
PyVar ret_obj = vm->call(csv_reader, args[0]); PyVar ret_obj = vm->call(csv_reader, args[0]);
const List& ret = CAST(List&, ret_obj); const List& ret = CAST(List&, ret_obj);
if(ret.size() == 0) { vm->ValueError("empty csvfile"); } if(ret.size() == 0) { vm->ValueError("empty csvfile"); }

View File

@ -72,8 +72,8 @@ static void patch__eq__(VM* vm, Type cls) {
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)]; const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
const auto& fields = cls_info->annotated_fields; const auto& fields = cls_info->annotated_fields;
for(StrName field: fields) { for(StrName field: fields) {
PyVar lhs = _0->attr(field); PyVar lhs = _0->attr()[field];
PyVar rhs = _1->attr(field); PyVar rhs = _1->attr()[field];
if(vm->py_ne(lhs, rhs)) return vm->False; if(vm->py_ne(lhs, rhs)) return vm->False;
} }
return vm->True; return vm->True;

20
src/objects/base.c Normal file
View File

@ -0,0 +1,20 @@
#include "pocketpy/objects/base.h"
/* predefined vars */
const pkpy_Type tp_object = 1, tp_type = 2;
const pkpy_Type tp_int = 3, tp_float = 4, tp_bool = 5, tp_str = 6;
const pkpy_Type tp_list = 7, tp_tuple = 8;
const pkpy_Type tp_slice = 9, tp_range = 10, tp_module = 11;
const pkpy_Type tp_function = 12, tp_native_func = 13, tp_bound_method = 14;
const pkpy_Type tp_super = 15, tp_exception = 16, tp_bytes = 17, tp_mappingproxy = 18;
const pkpy_Type tp_dict = 19, tp_property = 20, tp_star_wrapper = 21;
const pkpy_Type tp_staticmethod = 22, tp_classmethod = 23;
const pkpy_Type tp_none_type = 24, tp_not_implemented_type = 25;
const pkpy_Type tp_ellipsis = 26;
const PyVar pkpy_True = {.type=tp_bool, .is_ptr=false, .flags=0, .flags_ex=0, ._bool=true};
const PyVar pkpy_False = {.type=tp_bool, .is_ptr=false, .flags=0, .flags_ex=0, ._bool=false};
const PyVar pkpy_None = {.type=tp_none_type, .is_ptr=false, .flags=0, .flags_ex=0, ._i64=0};
const PyVar pkpy_NotImplemented = {.type=tp_not_implemented_type, .is_ptr=false, .flags=0, .flags_ex=0, ._i64=0};
const PyVar pkpy_Ellipsis = {.type=tp_ellipsis, .is_ptr=false, .flags=0, .flags_ex=0, ._i64=0};
const PyVar pkpy_NULL = {.type=0, .is_ptr=false, .flags=0, .flags_ex=0, ._i64=0};

View File

@ -1,6 +1,6 @@
#include "pocketpy/objects/builtins.hpp" #include "pocketpy/objects/builtins.hpp"
namespace pkpy { namespace pkpy {
const PyVar PY_OP_CALL(Type(), new PyObject(Type(), true)); PyVar PY_OP_CALL(Type(), new PyObject(Type(), true));
const PyVar PY_OP_YIELD(Type(), new PyObject(Type(), true)); PyVar PY_OP_YIELD(Type(), new PyObject(Type(), true));
} // namespace pkpy } // namespace pkpy

View File

@ -10,8 +10,8 @@
#define PK_DICT_COMPACT_MODE 1 #define PK_DICT_COMPACT_MODE 1
struct pkpy_DictEntry { struct pkpy_DictEntry {
pkpy_Var key; PyVar key;
pkpy_Var val; PyVar val;
}; };
inline extern int pkpy_Dict__idx_size(const pkpy_Dict* self) { inline extern int pkpy_Dict__idx_size(const pkpy_Dict* self) {
@ -73,7 +73,7 @@ static void pkpy_Dict__htset(pkpy_Dict* self, int h, int v) {
#endif #endif
} }
static int pkpy_Dict__probe0(const pkpy_Dict* self, void* vm, pkpy_Var key, int hash) { static int pkpy_Dict__probe0(const pkpy_Dict* self, void* vm, PyVar key, int hash) {
const int null = pkpy_Dict__idx_null(self); const int null = pkpy_Dict__idx_null(self);
const int mask = self->_htcap - 1; const int mask = self->_htcap - 1;
for(int h = hash & mask;; h = DICT_HASH_NEXT(h) & mask) { for(int h = hash & mask;; h = DICT_HASH_NEXT(h) & mask) {
@ -86,7 +86,7 @@ static int pkpy_Dict__probe0(const pkpy_Dict* self, void* vm, pkpy_Var key, int
PK_UNREACHABLE(); PK_UNREACHABLE();
} }
static int pkpy_Dict__probe1(const pkpy_Dict* self, void* vm, pkpy_Var key, int hash) { static int pkpy_Dict__probe1(const pkpy_Dict* self, void* vm, PyVar key, int hash) {
const int null = pkpy_Dict__idx_null(self); const int null = pkpy_Dict__idx_null(self);
const int mask = self->_htcap - 1; const int mask = self->_htcap - 1;
for(int h = hash & mask;; h = DICT_HASH_NEXT(h) & mask) { for(int h = hash & mask;; h = DICT_HASH_NEXT(h) & mask) {
@ -116,7 +116,7 @@ static void pkpy_Dict__extendht(pkpy_Dict* self, void* vm) {
} }
} }
bool pkpy_Dict__set(pkpy_Dict* self, void* vm, pkpy_Var key, pkpy_Var val) { bool pkpy_Dict__set(pkpy_Dict* self, void* vm, PyVar key, PyVar val) {
int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key)); int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key));
int h = pkpy_Dict__probe1(self, vm, key, hash); int h = pkpy_Dict__probe1(self, vm, key, hash);
@ -151,7 +151,7 @@ bool pkpy_Dict__set(pkpy_Dict* self, void* vm, pkpy_Var key, pkpy_Var val) {
return false; return false;
} }
bool pkpy_Dict__contains(const pkpy_Dict* self, void* vm, pkpy_Var key) { bool pkpy_Dict__contains(const pkpy_Dict* self, void* vm, PyVar key) {
int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key)); int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key));
int h = pkpy_Dict__probe1(self, vm, key, hash); int h = pkpy_Dict__probe1(self, vm, key, hash);
@ -191,7 +191,7 @@ static bool pkpy_Dict__refactor(pkpy_Dict* self, void* vm) {
return true; return true;
} }
bool pkpy_Dict__del(pkpy_Dict* self, void* vm, pkpy_Var key) { bool pkpy_Dict__del(pkpy_Dict* self, void* vm, PyVar key) {
int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key)); int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key));
int h = pkpy_Dict__probe1(self, vm, key, hash); int h = pkpy_Dict__probe1(self, vm, key, hash);
int idx = pkpy_Dict__htget(self, h), null = pkpy_Dict__idx_null(self); int idx = pkpy_Dict__htget(self, h), null = pkpy_Dict__idx_null(self);
@ -204,7 +204,7 @@ bool pkpy_Dict__del(pkpy_Dict* self, void* vm, pkpy_Var key) {
return true; return true;
} }
const pkpy_Var *pkpy_Dict__try_get(const pkpy_Dict* self, void* vm, pkpy_Var key) { const PyVar *pkpy_Dict__try_get(const pkpy_Dict* self, void* vm, PyVar key) {
int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key)); int hash = DICT_HASH_TRANS(pkpy_Var__hash__(vm, key));
int h = pkpy_Dict__probe1(self, vm, key, hash); int h = pkpy_Dict__probe1(self, vm, key, hash);
@ -245,7 +245,7 @@ pkpy_DictIter pkpy_Dict__iter(const pkpy_Dict *self) {
}; };
} }
bool pkpy_DictIter__next(pkpy_DictIter *self, pkpy_Var *key, pkpy_Var *val) { bool pkpy_DictIter__next(pkpy_DictIter *self, PyVar *key, PyVar *val) {
if(self->_index >= self->_dict->_entries.count) return false; if(self->_index >= self->_dict->_entries.count) return false;
struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_dict->_entries, self->_index); struct pkpy_DictEntry* entry = &c11__getitem(struct pkpy_DictEntry, &self->_dict->_entries, self->_index);

View File

@ -2,7 +2,7 @@
#define SMALLMAP_T__SOURCE #define SMALLMAP_T__SOURCE
#define K uint16_t #define K uint16_t
#define V pkpy_Var #define V PyVar
#define TAG n2v #define NAME pkpy_NameDict
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__SOURCE #undef SMALLMAP_T__SOURCE

View File

@ -1,17 +1,16 @@
#include "pocketpy/objects/base.hpp" #include "pocketpy/objects/base.h"
#include "pocketpy/objects/pyvar.h"
#include "pocketpy/interpreter/vm.hpp" #include "pocketpy/interpreter/vm.hpp"
extern "C" { extern "C" {
bool pkpy_Var__eq__(void* vm_, pkpy_Var a, pkpy_Var b) { bool pkpy_Var__eq__(void* vm_, PyVar a, PyVar b) {
auto vm = (pkpy::VM*)(vm_); auto vm = (pkpy::VM*)(vm_);
return vm->py_eq(*(pkpy::PyVar*)(&a), *(pkpy::PyVar*)(&b)); return vm->py_eq(*(PyVar*)(&a), *(PyVar*)(&b));
} }
int64_t pkpy_Var__hash__(void* vm_, pkpy_Var a) { int64_t pkpy_Var__hash__(void* vm_, PyVar a) {
auto vm = (pkpy::VM*)(vm_); auto vm = (pkpy::VM*)(vm_);
return vm->py_hash(*(pkpy::PyVar*)(&a)); return vm->py_hash(*(PyVar*)(&a));
} }
} }

View File

@ -1495,7 +1495,7 @@ void __init_builtins(VM* _vm) {
if(self.size() != other.size()) return vm->False; if(self.size() != other.size()) return vm->False;
pkpy_DictIter it = self.iter(); pkpy_DictIter it = self.iter();
PyVar key, val; PyVar key, val;
while(pkpy_DictIter__next(&it, (pkpy_Var*)(&key), (pkpy_Var*)(&val))) { while(pkpy_DictIter__next(&it, (PyVar*)(&key), (PyVar*)(&val))) {
PyVar other_val = other.try_get(vm, key); PyVar other_val = other.try_get(vm, key);
if(other_val == nullptr) return vm->False; if(other_val == nullptr) return vm->False;
if(!vm->py_eq(val, other_val)) return vm->False; if(!vm->py_eq(val, other_val)) return vm->False;

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
using namespace pkpy; namespace pkpy{
#define PK_ASSERT_N_EXTRA_ELEMENTS(n) \ #define PK_ASSERT_N_EXTRA_ELEMENTS(n) \
int __ex_count = count_extra_elements(vm, n); \ int __ex_count = count_extra_elements(vm, n); \
@ -567,3 +567,5 @@ bool pkpy_repl_input(void* r, const char* line) { return ((REPL*)r)->input(line)
void pkpy_delete_repl(void* repl) { delete (REPL*)repl; } void pkpy_delete_repl(void* repl) { delete (REPL*)repl; }
#endif // PK_NO_EXPORT_C_API #endif // PK_NO_EXPORT_C_API
} // namespace pkpy

View File

@ -34,6 +34,8 @@ std::string pkpy_platform_getline(bool* eof) {
#else #else
using namespace pkpy;
std::string pkpy_platform_getline(bool* eof) { std::string pkpy_platform_getline(bool* eof) {
std::string output; std::string output;
if(!std::getline(std::cin, output)) { if(!std::getline(std::cin, output)) {