blueloveTH 3 лет назад
Родитель
Сommit
e84a996a1e
6 измененных файлов с 64 добавлено и 71 удалено
  1. 0 1
      src/__stl__.h
  2. 5 5
      src/codeobject.h
  3. 9 9
      src/iter.h
  4. 21 25
      src/obj.h
  5. 5 5
      src/pocketpy.h
  6. 24 26
      src/vm.h

+ 0 - 1
src/__stl__.h

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

+ 5 - 5
src/codeobject.h

@@ -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());
     }
 };

+ 9 - 9
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<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(){

+ 21 - 25
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<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__]; }
+};
+
+template <typename T>
+struct Py_ : PyObject {
+    T _value;
 
-    _Str getTypeName(){
-        return _type->getName();
+    Py_(const T& val, const PyVar& type) {
+        _value = val;
+        _type = type;
     }
+    Py_(T&& val, const PyVar& type) {
+        _value = std::move(val);
+        _type = type;
+    }
+};
 
-    PyObject(const _Value& val): _native(val) {}
-    PyObject(_Value&& val): _native(std::move(val)) {}
-};
+#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
+#define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName())

+ 5 - 5
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<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])
         );
     });
 

+ 24 - 26
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<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++) {