add __iter__ and __new__ for some types

This commit is contained in:
blueloveTH 2022-11-10 16:42:12 +08:00
parent b52aa85f13
commit aa0c415f1d
7 changed files with 116 additions and 28 deletions

View File

@ -60,6 +60,8 @@ list.__contains__ = __iterable4__contains__
tuple.__contains__ = __iterable4__contains__ tuple.__contains__ = __iterable4__contains__
del __iterable4__contains__ del __iterable4__contains__
list.__new__ = lambda obj: [i for i in obj]
# https://github.com/python/cpython/blob/main/Objects/dictobject.c # https://github.com/python/cpython/blob/main/Objects/dictobject.c
class dict: class dict:
def __init__(self): def __init__(self):

View File

@ -62,7 +62,7 @@ public:
} }
const char* what() const noexcept override { const char* what() const noexcept override {
return _what; return _what.c_str();
} }
}; };

View File

@ -2,25 +2,16 @@
#include "obj.h" #include "obj.h"
typedef std::function<PyVar (_Int)> _PyIntFn;
class RangeIterator : public _Iterator { class RangeIterator : public _Iterator {
private: private:
_Int current; _Int current;
_Range r; _Range r;
_PyIntFn fn;
public: public:
RangeIterator(PyVar _ref, _PyIntFn fn) : _Iterator(_ref), fn(fn) { RangeIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) {
this->r = std::get<_Range>(_ref->_native); this->r = std::get<_Range>(_ref->_native);
this->current = r.start; this->current = r.start;
} }
PyVar next() override {
PyVar val = fn(current);
current += r.step;
return val;
}
bool hasNext() override { bool hasNext() override {
if(r.step > 0){ if(r.step > 0){
return current < r.stop; return current < r.stop;
@ -28,6 +19,8 @@ public:
return current > r.stop; return current > r.stop;
} }
} }
PyVar next();
}; };
class VectorIterator : public _Iterator { class VectorIterator : public _Iterator {
@ -35,7 +28,7 @@ private:
size_t index = 0; size_t index = 0;
const PyVarList* vec; const PyVarList* vec;
public: public:
VectorIterator(PyVar _ref) : _Iterator(_ref) { VectorIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) {
vec = &std::get<PyVarList>(_ref->_native); vec = &std::get<PyVarList>(_ref->_native);
} }
@ -47,3 +40,19 @@ public:
return vec->operator[](index++); return vec->operator[](index++);
} }
}; };
class StringIterator : public _Iterator {
private:
size_t index = 0;
const _Str* str;
public:
StringIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) {
str = &std::get<_Str>(_ref->_native);
}
bool hasNext(){
return index < str->u8_length();
}
PyVar next();
};

View File

@ -13,6 +13,11 @@
typedef int64_t _Int; typedef int64_t _Int;
typedef double _Float; typedef double _Float;
#define _Int_MAX_POS 9223372036854775807
#define _Int_MAX_NEG -9223372036854775808
#define _FLOAT_INF_POS 1.0/0.0
#define _FLOAT_INF_NEG -1.0/0.0
class PyObject; class PyObject;
class CodeObject; class CodeObject;
class BasePointer; class BasePointer;
@ -90,15 +95,14 @@ struct _Slice {
}; };
class _Iterator { class _Iterator {
private: protected:
PyVar _ref; // keep a reference to the object so it will not be deleted while iterating PyVar _ref; // keep a reference to the object so it will not be deleted while iterating
VM* vm;
public: public:
virtual PyVar next() = 0; virtual PyVar next() = 0;
virtual bool hasNext() = 0; virtual bool hasNext() = 0;
_Pointer var; _Pointer var;
_Iterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
_Iterator(PyVar _ref) : _ref(_ref) {}
}; };
typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,BoundedMethod,_Range,_Slice,_Pointer> _Value; typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,BoundedMethod,_Range,_Slice,_Pointer> _Value;

View File

@ -42,7 +42,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
#undef BIND_NUM_LOGICAL_OPT #undef BIND_NUM_LOGICAL_OPT
_vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) { _vm->bindBuiltinFunc("print", [](VM* vm, PyVarList args) {
for (auto& arg : args) vm->_stdout(vm->PyStr_AS_C(vm->asStr(arg)) + " "); for (auto& arg : args){
_Str s = vm->PyStr_AS_C(vm->asStr(arg)) + " ";
vm->_stdout(s.c_str());
}
vm->_stdout("\n"); vm->_stdout("\n");
return vm->None; return vm->None;
}); });
@ -50,7 +53,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindBuiltinFunc("eval", [](VM* vm, PyVarList args) { _vm->bindBuiltinFunc("eval", [](VM* vm, PyVarList args) {
vm->__checkArgSize(args, 1); vm->__checkArgSize(args, 1);
const _Str& expr = vm->PyStr_AS_C(args[0]); const _Str& expr = vm->PyStr_AS_C(args[0]);
_Code code = compile(vm, expr, "<eval>", EVAL_MODE); _Code code = compile(vm, expr.c_str(), "<eval>", EVAL_MODE);
if(code == nullptr) return vm->None; if(code == nullptr) return vm->None;
return vm->_exec(code); // not working in function return vm->_exec(code); // not working in function
}); });
@ -115,7 +118,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("range", "__iter__", [](VM* vm, PyVarList args) { _vm->bindMethod("range", "__iter__", [](VM* vm, PyVarList args) {
vm->__checkType(args[0], vm->_tp_range); vm->__checkType(args[0], vm->_tp_range);
auto iter = std::make_shared<RangeIterator>(args[0], [=](_Int val){return vm->PyInt(val);}); auto iter = std::make_shared<RangeIterator>(vm, args[0]);
return vm->PyIter(iter); return vm->PyIter(iter);
}); });
@ -142,6 +145,25 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
/************ PyInt ************/ /************ PyInt ************/
_vm->bindMethod("int", "__new__", [](VM* vm, PyVarList args) {
if(args.size() == 0) return vm->PyInt(0);
vm->__checkArgSize(args, 1);
if (args[0]->isType(vm->_tp_int)) return args[0];
if (args[0]->isType(vm->_tp_float)) return vm->PyInt((_Int)vm->PyFloat_AS_C(args[0]));
if (args[0]->isType(vm->_tp_bool)) return vm->PyInt(vm->PyBool_AS_C(args[0]) ? 1 : 0);
if (args[0]->isType(vm->_tp_str)) {
const _Str& s = vm->PyStr_AS_C(args[0]);
try{
_Int val = std::stoll(s.str());
return vm->PyInt(val);
}catch(std::invalid_argument&){
vm->valueError("invalid literal for int(): '" + s + "'");
}
}
vm->typeError("int() argument must be a int, float, bool or str");
return vm->None;
});
_vm->bindMethod("int", "__floordiv__", [](VM* vm, PyVarList args) { _vm->bindMethod("int", "__floordiv__", [](VM* vm, PyVarList args) {
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
vm->typeError("unsupported operand type(s) for " "//" ); vm->typeError("unsupported operand type(s) for " "//" );
@ -167,6 +189,27 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
/************ PyFloat ************/ /************ PyFloat ************/
_vm->bindMethod("float", "__new__", [](VM* vm, PyVarList args) {
if(args.size() == 0) return vm->PyFloat(0.0);
vm->__checkArgSize(args, 1);
if (args[0]->isType(vm->_tp_int)) return vm->PyFloat((_Float)vm->PyInt_AS_C(args[0]));
if (args[0]->isType(vm->_tp_float)) return args[0];
if (args[0]->isType(vm->_tp_bool)) return vm->PyFloat(vm->PyBool_AS_C(args[0]) ? 1.0 : 0.0);
if (args[0]->isType(vm->_tp_str)) {
const _Str& s = vm->PyStr_AS_C(args[0]);
if(s == "inf") return vm->PyFloat(_FLOAT_INF_POS);
if(s == "-inf") return vm->PyFloat(_FLOAT_INF_NEG);
try{
_Float val = std::stod(s.str());
return vm->PyFloat(val);
}catch(std::invalid_argument&){
vm->valueError("invalid literal for float(): '" + s + "'");
}
}
vm->typeError("float() argument must be a int, float, bool or str");
return vm->None;
});
_vm->bindMethod("float", "__neg__", [](VM* vm, PyVarList args) { _vm->bindMethod("float", "__neg__", [](VM* vm, PyVarList args) {
return vm->PyFloat(-1.0 * vm->PyFloat_AS_C(args[0])); return vm->PyFloat(-1.0 * vm->PyFloat_AS_C(args[0]));
}); });
@ -177,7 +220,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_StrStream ss; _StrStream ss;
ss << std::setprecision(std::numeric_limits<_Float>::max_digits10-1) << val; ss << std::setprecision(std::numeric_limits<_Float>::max_digits10-1) << val;
std::string s = ss.str(); std::string s = ss.str();
if(std::all_of(s.begin(), s.end(), isdigit)) s += ".0"; if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0";
return vm->PyStr(s); return vm->PyStr(s);
}); });
@ -210,6 +253,11 @@ void __initializeBuiltinFunctions(VM* _vm) {
return args[0]; // str is immutable return args[0]; // str is immutable
}); });
_vm->bindMethod("str", "__iter__", [](VM* vm, PyVarList args) {
auto it = std::make_shared<StringIterator>(vm, args[0]);
return vm->PyIter(it);
});
_vm->bindMethod("str", "__repr__", [](VM* vm, PyVarList args) { _vm->bindMethod("str", "__repr__", [](VM* vm, PyVarList args) {
const _Str& _self = vm->PyStr_AS_C(args[0]); const _Str& _self = vm->PyStr_AS_C(args[0]);
// we just do a simple repr here, no escaping // we just do a simple repr here, no escaping
@ -308,7 +356,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
/************ PyList ************/ /************ PyList ************/
_vm->bindMethod("list", "__iter__", [](VM* vm, PyVarList args) { _vm->bindMethod("list", "__iter__", [](VM* vm, PyVarList args) {
vm->__checkType(args[0], vm->_tp_list); vm->__checkType(args[0], vm->_tp_list);
auto iter = std::make_shared<VectorIterator>(args[0]); auto iter = std::make_shared<VectorIterator>(vm, args[0]);
return vm->PyIter(iter); return vm->PyIter(iter);
}); });
@ -395,9 +443,15 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
/************ PyTuple ************/ /************ PyTuple ************/
_vm->bindMethod("tuple", "__new__", [](VM* vm, PyVarList args) {
vm->__checkArgSize(args, 1);
PyVarList _list = vm->PyList_AS_C(vm->call(vm->builtins->attribs["list"], args));
return vm->PyTuple(_list);
});
_vm->bindMethod("tuple", "__iter__", [](VM* vm, PyVarList args) { _vm->bindMethod("tuple", "__iter__", [](VM* vm, PyVarList args) {
vm->__checkType(args[0], vm->_tp_tuple); vm->__checkType(args[0], vm->_tp_tuple);
auto iter = std::make_shared<VectorIterator>(args[0]); auto iter = std::make_shared<VectorIterator>(vm, args[0]);
return vm->PyIter(iter); return vm->PyIter(iter);
}); });

View File

@ -75,6 +75,14 @@ public:
return _s != other._s; return _s != other._s;
} }
bool operator==(const char* other) const {
return _s == other;
}
bool operator!=(const char* other) const {
return _s != other;
}
bool operator<(const _Str& other) const { bool operator<(const _Str& other) const {
return _s < other._s; return _s < other._s;
} }
@ -116,12 +124,12 @@ public:
return _s; return _s;
} }
static const std::size_t npos = std::string::npos; const char* c_str() const {
operator const char*() const {
return _s.c_str(); return _s.c_str();
} }
static const std::size_t npos = std::string::npos;
_Str __lstrip() const { _Str __lstrip() const {
std::string copy(_s); std::string copy(_s);
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) { copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) {

View File

@ -132,7 +132,7 @@ private:
{ {
const PyVar& expr = frame->topValue(this); const PyVar& expr = frame->topValue(this);
if(expr == None) break; if(expr == None) break;
_stdout(PyStr_AS_C(asRepr(expr))); _stdout(PyStr_AS_C(asRepr(expr)).c_str());
_stdout("\n"); _stdout("\n");
} break; } break;
case OP_POP_TOP: frame->popValue(this); break; case OP_POP_TOP: frame->popValue(this); break;
@ -799,8 +799,19 @@ void CompoundPointer::del(VM* vm, Frame* frame) const{
for (auto& ptr : pointers) ptr->del(vm, frame); for (auto& ptr : pointers) ptr->del(vm, frame);
} }
/**************** Frame ****************/ /***** Frame's Impl *****/
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){ inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
if(v->isType(vm->_tp_pointer)) v = vm->PyPointer_AS_C(v)->get(vm, this); if(v->isType(vm->_tp_pointer)) v = vm->PyPointer_AS_C(v)->get(vm, this);
return v; return v;
} }
/***** Iterators' Impl *****/
PyVar RangeIterator::next(){
PyVar val = vm->PyInt(current);
current += r.step;
return val;
}
PyVar StringIterator::next(){
return vm->PyStr(str->u8_getitem(index++));
}