remove variant

This commit is contained in:
blueloveTH 2022-12-07 17:32:09 +08:00
parent af776bb4aa
commit e84a996a1e
6 changed files with 65 additions and 72 deletions

View File

@ -8,7 +8,6 @@
#include <sstream>
#include <regex>
#include <variant>
#include <stack>
#include <cmath>
#include <stdexcept>

View File

@ -102,7 +102,7 @@ struct CodeObject {
_StrStream consts;
consts << "co_consts: ";
for(int i=0; i<co_consts.size(); i++){
consts << co_consts[i]->getTypeName();
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.size(); i++){
auto fn = std::get_if<_Func>(&co_consts[i]->_native);
if(fn) ss << '\n' << (*fn)->code->name << ":\n" << (*fn)->code->toString();
}
// for(int i=0; i<co_consts.size(); i++){
// auto fn = std::get_if<_Func>(&co_consts[i]->_native);
// if(fn) ss << '\n' << (*fn)->code->name << ":\n" << (*fn)->code->toString();
// }
return _Str(ss.str());
}
};

View File

@ -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<PyVarList>(_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(){

View File

@ -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<Function> _Func;
typedef std::variant<PyVar,_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,pkpy::shared_ptr<_Iterator>,_BoundedMethod,_Range,_Slice,_Pointer> _Value;
const int VALUE_SIZE = sizeof(_Value);
typedef pkpy::shared_ptr<BaseIterator> _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 <typename T>
struct Py_ : PyObject {
T _value;
PyObject(const _Value& val): _native(val) {}
PyObject(_Value&& val): _native(std::move(val)) {}
};
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_<T>*)((obj).get()))->_value)
#define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName())

View File

@ -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<BaseIterator, RangeIterator>(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<BaseIterator, StringIterator>(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<BaseIterator, VectorIterator>(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<BaseIterator, VectorIterator>(vm, args[0])
);
});

View File

@ -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<ctype>(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<const BasePointer, AttrPointer>(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("<class '" + obj->getName() + "'>");
if(obj->isType(_tp_type)) return PyStr("<class '" + UNION_GET(_Str, obj->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<PyObject>((_Int)0);
obj->setType(_tp_type);
PyVar obj = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)0, _tp_type);
setAttr(obj, __base__, base);
_types[name] = obj;
return obj;
}
PyVar newObject(PyVar type, const _Value& _native) {
template<typename T>
inline PyVar newObject(PyVar type, T _value) {
__checkType(type, _tp_type);
PyVar obj = pkpy::make_shared<PyObject>(_native);
obj->setType(type);
return obj;
return pkpy::make_shared<PyObject, Py_<T>>(_value, type);
}
PyVar newModule(_Str name) {
@ -637,7 +635,7 @@ public:
const PyVar* root = &obj;
int depth = 1;
while(true){
root = &std::get<PyVar>((*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<PyVar>((*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<PyVar>((*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<PyObject>((_Int)0);
_tp_type = pkpy::make_shared<PyObject>((_Int)0);
_tp_object = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)0, nullptr);
_tp_type = pkpy::make_shared<PyObject, Py_<_Int>>((_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<PyVarList>(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++) {