From e84a996a1ea1cd82086bc96a7da84917c1b3ebe9 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 7 Dec 2022 17:32:09 +0800 Subject: [PATCH] remove variant --- src/__stl__.h | 1 - src/codeobject.h | 10 +++++----- src/iter.h | 18 ++++++++--------- src/obj.h | 48 +++++++++++++++++++++------------------------- src/pocketpy.h | 10 +++++----- src/vm.h | 50 +++++++++++++++++++++++------------------------- 6 files changed, 65 insertions(+), 72 deletions(-) diff --git a/src/__stl__.h b/src/__stl__.h index 99fd3e8e..ed44e8fd 100644 --- a/src/__stl__.h +++ b/src/__stl__.h @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/src/codeobject.h b/src/codeobject.h index 9c70a0cd..2bb2668b 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -102,7 +102,7 @@ struct CodeObject { _StrStream consts; consts << "co_consts: "; for(int i=0; igetTypeName(); + consts << UNION_TP_NAME(co_consts[i]); if(i != co_consts.size() - 1) consts << ", "; } @@ -113,10 +113,10 @@ struct CodeObject { if(i != co_names.size() - 1) names << ", "; } ss << '\n' << consts.str() << '\n' << names.str() << '\n'; - for(int i=0; i(&co_consts[i]->_native); - if(fn) ss << '\n' << (*fn)->code->name << ":\n" << (*fn)->code->toString(); - } + // for(int i=0; i(&co_consts[i]->_native); + // if(fn) ss << '\n' << (*fn)->code->name << ":\n" << (*fn)->code->toString(); + // } return _Str(ss.str()); } }; diff --git a/src/iter.h b/src/iter.h index daeb44df..07d189cf 100644 --- a/src/iter.h +++ b/src/iter.h @@ -2,13 +2,13 @@ #include "obj.h" -class RangeIterator : public _Iterator { +class RangeIterator : public BaseIterator { private: _Int current; _Range r; public: - RangeIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) { - this->r = std::get<_Range>(_ref->_native); + RangeIterator(VM* vm, PyVar _ref) : BaseIterator(vm, _ref) { + this->r = UNION_GET(_Range, _ref); this->current = r.start; } @@ -23,13 +23,13 @@ public: PyVar next() override; }; -class VectorIterator : public _Iterator { +class VectorIterator : public BaseIterator { private: size_t index = 0; const PyVarList* vec; public: - VectorIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) { - vec = &std::get(_ref->_native); + VectorIterator(VM* vm, PyVar _ref) : BaseIterator(vm, _ref) { + vec = &UNION_GET(PyVarList, _ref); } bool hasNext(){ @@ -41,13 +41,13 @@ public: } }; -class StringIterator : public _Iterator { +class StringIterator : public BaseIterator { private: int index = 0; _Str str; public: - StringIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) { - str = std::get<_Str>(_ref->_native); + StringIterator(VM* vm, PyVar _ref) : BaseIterator(vm, _ref) { + str = UNION_GET(_Str, _ref); } bool hasNext(){ diff --git a/src/obj.h b/src/obj.h index 8ddd58e2..de91a588 100644 --- a/src/obj.h +++ b/src/obj.h @@ -53,7 +53,7 @@ struct _Slice { } }; -class _Iterator { +class BaseIterator { protected: VM* vm; PyVar _ref; // keep a reference to the object so it will not be deleted while iterating @@ -61,40 +61,36 @@ public: virtual PyVar next() = 0; virtual bool hasNext() = 0; _Pointer var; - _Iterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} - virtual ~_Iterator() = default; + BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} + virtual ~BaseIterator() = default; }; typedef pkpy::shared_ptr _Func; -typedef std::variant,_BoundedMethod,_Range,_Slice,_Pointer> _Value; - -const int VALUE_SIZE = sizeof(_Value); - +typedef pkpy::shared_ptr _Iterator; struct PyObject { PyVarDict attribs; - _Value _native; PyVar _type; - inline bool isType(const PyVar& type){ - return this->_type == type; - } - - inline void setType(const PyVar& type){ - this->_type = type; - // this->attribs[__class__] = type; - } + inline bool isType(const PyVar& type){ return this->_type == type; } // currently __name__ is only used for 'type' - _Str getName(){ - _Value val = attribs[__name__]->_native; - return std::get<_Str>(val); - } + PyVar _typeName(){ return _type->attribs[__name__]; } +}; - _Str getTypeName(){ - return _type->getName(); - } +template +struct Py_ : PyObject { + T _value; - PyObject(const _Value& val): _native(val) {} - PyObject(_Value&& val): _native(std::move(val)) {} -}; \ No newline at end of file + Py_(const T& val, const PyVar& type) { + _value = val; + _type = type; + } + Py_(T&& val, const PyVar& type) { + _value = std::move(val); + _type = type; + } +}; + +#define UNION_GET(T, obj) (((Py_*)((obj).get()))->_value) +#define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName()) \ No newline at end of file diff --git a/src/pocketpy.h b/src/pocketpy.h index 1b5144ee..02b1a878 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -126,7 +126,7 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("object", "__repr__", [](VM* vm, const pkpy::ArgList& args) { PyVar _self = args[0]; - _Str s = "<" + _self->getTypeName() + " object at " + std::to_string((uintptr_t)_self.get()) + ">"; + _Str s = "<" + UNION_TP_NAME(_self) + " object at " + std::to_string((uintptr_t)_self.get()) + ">"; return vm->PyStr(s); }); @@ -149,7 +149,7 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("range", "__iter__", [](VM* vm, const pkpy::ArgList& args) { vm->__checkType(args[0], vm->_tp_range); return vm->PyIter( - pkpy::make_shared<_Iterator, RangeIterator>(vm, args[0]) + pkpy::make_shared(vm, args[0]) ); }); @@ -315,7 +315,7 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("str", "__iter__", [](VM* vm, const pkpy::ArgList& args) { return vm->PyIter( - pkpy::make_shared<_Iterator, StringIterator>(vm, args[0]) + pkpy::make_shared(vm, args[0]) ); }); @@ -429,7 +429,7 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("list", "__iter__", [](VM* vm, const pkpy::ArgList& args) { vm->__checkType(args[0], vm->_tp_list); return vm->PyIter( - pkpy::make_shared<_Iterator, VectorIterator>(vm, args[0]) + pkpy::make_shared(vm, args[0]) ); }); @@ -527,7 +527,7 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("tuple", "__iter__", [](VM* vm, const pkpy::ArgList& args) { vm->__checkType(args[0], vm->_tp_tuple); return vm->PyIter( - pkpy::make_shared<_Iterator, VectorIterator>(vm, args[0]) + pkpy::make_shared(vm, args[0]) ); }); diff --git a/src/vm.h b/src/vm.h index feefd072..1cfcff1a 100644 --- a/src/vm.h +++ b/src/vm.h @@ -7,7 +7,7 @@ #define __DEF_PY_AS_C(type, ctype, ptype) \ inline ctype& Py##type##_AS_C(const PyVar& obj) { \ __checkType(obj, ptype); \ - return std::get(obj->_native); \ + return UNION_GET(ctype, obj); \ } #define __DEF_PY(type, ctype, ptype) \ @@ -74,7 +74,7 @@ protected: const auto& attr = frame->code->co_names[byte.arg]; PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - const _Pointer& p = std::get<_Pointer>(obj->_native); + const _Pointer& p = UNION_GET(_Pointer, obj); frame->push(PyPointer( pkpy::make_shared(p->get(this, frame), &attr) )); @@ -223,7 +223,7 @@ protected: // pointer to _pointer PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - frame->push(PyPointer(std::get<_Pointer>(obj->_native))); + frame->push(PyPointer(UNION_GET(_Pointer, obj))); } break; case OP_POP_JUMP_IF_FALSE: if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg); @@ -286,7 +286,7 @@ protected: PyIter_AS_C(tmp)->var = std::move(PyPointer_AS_C(frame->__pop())); frame->push(std::move(tmp)); }else{ - typeError("'" + obj->getTypeName() + "' object is not iterable"); + typeError("'" + UNION_TP_NAME(obj) + "' object is not iterable"); } } break; case OP_FOR_ITER: @@ -431,7 +431,7 @@ public: } PyVar asRepr(const PyVar& obj){ - if(obj->isType(_tp_type)) return PyStr("getName() + "'>"); + if(obj->isType(_tp_type)) return PyStr("attribs[__name__]) + "'>"); return call(obj, __repr__, {}); } @@ -492,7 +492,7 @@ public: } if((*callable)->isType(_tp_native_function)){ - const auto& f = std::get<_CppFunc>((*callable)->_native); + const auto& f = UNION_GET(_CppFunc, *callable); return f(this, args); } else if((*callable)->isType(_tp_function)){ const _Func& fn = PyFunction_AS_C((*callable)); @@ -530,7 +530,7 @@ public: } return _exec(fn->code, _module, locals); } - typeError("'" + (*callable)->getTypeName() + "' object is not callable"); + typeError("'" + UNION_TP_NAME(*callable) + "' object is not callable"); return None; } @@ -604,18 +604,16 @@ public: PyVar newClassType(_Str name, PyVar base=nullptr) { if(base == nullptr) base = _tp_object; - PyVar obj = pkpy::make_shared((_Int)0); - obj->setType(_tp_type); + PyVar obj = pkpy::make_shared>((_Int)0, _tp_type); setAttr(obj, __base__, base); _types[name] = obj; return obj; } - PyVar newObject(PyVar type, const _Value& _native) { + template + inline PyVar newObject(PyVar type, T _value) { __checkType(type, _tp_type); - PyVar obj = pkpy::make_shared(_native); - obj->setType(type); - return obj; + return pkpy::make_shared>(_value, type); } PyVar newModule(_Str name) { @@ -637,7 +635,7 @@ public: const PyVar* root = &obj; int depth = 1; while(true){ - root = &std::get((*root)->_native); + root = &UNION_GET(PyVar, *root); if(!(*root)->isType(_tp_super)) break; depth++; } @@ -672,7 +670,7 @@ public: if(obj->isType(_tp_super)){ const PyVar* root = &obj; while(true){ - root = &std::get((*root)->_native); + root = &UNION_GET(PyVar, *root); if(!(*root)->isType(_tp_super)) break; } (*root)->attribs[name] = value; @@ -685,7 +683,7 @@ public: if(obj->isType(_tp_super)){ const PyVar* root = &obj; while(true){ - root = &std::get((*root)->_native); + root = &UNION_GET(PyVar, *root); if(!(*root)->isType(_tp_super)) break; } (*root)->attribs[name] = std::move(value); @@ -774,7 +772,7 @@ public: inline _Pointer& PyPointer_AS_C(const PyVar& obj) { if(!obj->isType(_tp_pointer)) typeError("expected an l-value"); - return std::get<_Pointer>(obj->_native); + return UNION_GET(_Pointer, obj); } __DEF_PY_AS_C(Int, _Int, _tp_int) @@ -789,7 +787,7 @@ public: DEF_NATIVE(Tuple, PyVarList, _tp_tuple) DEF_NATIVE(Function, _Func, _tp_function) DEF_NATIVE(NativeFunction, _CppFunc, _tp_native_function) - DEF_NATIVE(Iter, pkpy::shared_ptr<_Iterator>, _tp_native_iterator) + DEF_NATIVE(Iter, _Iterator, _tp_native_iterator) DEF_NATIVE(BoundedMethod, _BoundedMethod, _tp_bounded_method) DEF_NATIVE(Range, _Range, _tp_range) DEF_NATIVE(Slice, _Slice, _tp_slice) @@ -799,8 +797,8 @@ public: inline const PyVar& PyBool(bool value){return value ? True : False;} void initializeBuiltinClasses(){ - _tp_object = pkpy::make_shared((_Int)0); - _tp_type = pkpy::make_shared((_Int)0); + _tp_object = pkpy::make_shared>((_Int)0, nullptr); + _tp_type = pkpy::make_shared>((_Int)0, nullptr); _types["object"] = _tp_object; _types["type"] = _tp_type; @@ -834,9 +832,9 @@ public: this->_main = newModule("__main__"_c); setAttr(_tp_type, __base__, _tp_object); - _tp_type->setType(_tp_type); + _tp_type->_type = _tp_type; setAttr(_tp_object, __base__, None); - _tp_object->setType(_tp_type); + _tp_object->_type = _tp_type; for (auto& [name, type] : _types) { setAttr(type, __name__, PyStr(name)); @@ -869,7 +867,7 @@ public: } return x; } - typeError("unhashable type: " + obj->getTypeName()); + typeError("unhashable type: " + UNION_TP_NAME(obj)); return 0; } @@ -920,11 +918,11 @@ public: } void attributeError(PyVar obj, const _Str& name){ - _error("AttributeError", "type '" + obj->getTypeName() + "' has no attribute '" + name + "'"); + _error("AttributeError", "type '" + UNION_TP_NAME(obj) + "' has no attribute '" + name + "'"); } inline void __checkType(const PyVar& obj, const PyVar& type){ - if(!obj->isType(type)) typeError("expected '" + type->getName() + "', but got '" + obj->getTypeName() + "'"); + if(!obj->isType(type)) typeError("expected '" + UNION_TP_NAME(type) + "', but got '" + UNION_TP_NAME(obj) + "'"); } inline void __checkArgSize(const pkpy::ArgList& args, int size, bool method=false){ @@ -1034,7 +1032,7 @@ void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{ if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){ vm->typeError("only tuple or list can be unpacked"); } - const PyVarList& args = std::get(val->_native); + const PyVarList& args = UNION_GET(PyVarList, val); if(args.size() > pointers.size()) vm->valueError("too many values to unpack"); if(args.size() < pointers.size()) vm->valueError("not enough values to unpack"); for (int i = 0; i < pointers.size(); i++) {