mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-24 13:30:18 +00:00
make system safe
remove **kwargs Update obj.h
This commit is contained in:
parent
5765c731a5
commit
47c6639627
@ -795,7 +795,7 @@ __LISTCOMP:
|
||||
case 0: func.args.push_back(name); break;
|
||||
case 1: func.starredArg = name; state+=1; break;
|
||||
case 2: consume(TK("=")); func.kwArgs[name] = consumeLiteral(); break;
|
||||
case 3: func.doubleStarredArg = name; break;
|
||||
case 3: syntaxError("**kwargs is not supported yet"); break;
|
||||
}
|
||||
} while (match(TK(",")));
|
||||
}
|
||||
|
||||
@ -44,6 +44,6 @@ public:
|
||||
}
|
||||
|
||||
PyVar next(){
|
||||
return vec->at(index++);
|
||||
return vec->operator[](index++);
|
||||
}
|
||||
};
|
||||
34
src/obj.h
34
src/obj.h
@ -20,7 +20,31 @@ class VM;
|
||||
|
||||
typedef std::shared_ptr<PyObject> PyVar;
|
||||
typedef PyVar PyVarOrNull;
|
||||
typedef std::vector<PyVar> PyVarList;
|
||||
|
||||
class PyVarList: public std::vector<PyVar> {
|
||||
PyVar& at(size_t) = delete;
|
||||
|
||||
inline void __checkIndex(size_t i) const {
|
||||
if (i >= size()){
|
||||
auto msg = "std::vector index out of range, " + std::to_string(i) + " not in [0, " + std::to_string(size()) + ")";
|
||||
throw std::out_of_range(msg);
|
||||
}
|
||||
}
|
||||
public:
|
||||
PyVar& operator[](size_t i) {
|
||||
__checkIndex(i);
|
||||
return std::vector<PyVar>::operator[](i);
|
||||
}
|
||||
|
||||
const PyVar& operator[](size_t i) const {
|
||||
__checkIndex(i);
|
||||
return std::vector<PyVar>::operator[](i);
|
||||
}
|
||||
|
||||
// define constructors the same as std::vector
|
||||
using std::vector<PyVar>::vector;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<_Str, PyVar> PyVarDict;
|
||||
typedef std::shared_ptr<const BasePointer> _Pointer;
|
||||
|
||||
@ -32,15 +56,13 @@ struct _Func {
|
||||
_Code code;
|
||||
std::vector<_Str> args;
|
||||
_Str starredArg; // empty if no *arg
|
||||
PyVarDict kwArgs; // empty if no k=v
|
||||
_Str doubleStarredArg; // empty if no **kwargs
|
||||
PyVarDict kwArgs; // empty if no k=v
|
||||
|
||||
bool hasName(const _Str& val) const {
|
||||
bool _0 = std::find(args.begin(), args.end(), val) != args.end();
|
||||
bool _1 = starredArg == val;
|
||||
bool _2 = kwArgs.find(val) != kwArgs.end();
|
||||
bool _3 = doubleStarredArg == val;
|
||||
return _0 || _1 || _2 || _3;
|
||||
return _0 || _1 || _2;
|
||||
}
|
||||
};
|
||||
|
||||
@ -81,7 +103,7 @@ public:
|
||||
|
||||
typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,BoundedMethod,_Range,_Slice,_Pointer> _Value;
|
||||
|
||||
#define UNREACHABLE() throw std::runtime_error("Unreachable code")
|
||||
#define UNREACHABLE() throw std::runtime_error("unreachable code! (this should be a bug, please report it)");
|
||||
|
||||
struct PyObject {
|
||||
PyVarDict attribs;
|
||||
|
||||
@ -60,32 +60,32 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("repr", [](VM* vm, PyVarList args) {
|
||||
return vm->asRepr(args.at(0));
|
||||
return vm->asRepr(args[0]);
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("hash", [](VM* vm, PyVarList args) {
|
||||
return vm->PyInt(vm->hash(args.at(0)));
|
||||
return vm->PyInt(vm->hash(args[0]));
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("chr", [](VM* vm, PyVarList args) {
|
||||
_Int i = vm->PyInt_AS_C(args.at(0));
|
||||
_Int i = vm->PyInt_AS_C(args[0]);
|
||||
if (i < 0 || i > 128) vm->valueError("chr() arg not in range(128)");
|
||||
return vm->PyStr(_Str(1, (char)i));
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("round", [](VM* vm, PyVarList args) {
|
||||
return vm->PyInt(_round(vm->numToFloat(args.at(0))));
|
||||
return vm->PyInt(_round(vm->numToFloat(args[0])));
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("ord", [](VM* vm, PyVarList args) {
|
||||
_Str s = vm->PyStr_AS_C(args.at(0));
|
||||
_Str s = vm->PyStr_AS_C(args[0]);
|
||||
if (s.size() != 1) vm->typeError("ord() expected an ASCII character");
|
||||
return vm->PyInt((_Int)s[0]);
|
||||
});
|
||||
|
||||
_vm->bindBuiltinFunc("dir", [](VM* vm, PyVarList args) {
|
||||
PyVarList ret;
|
||||
for (auto& [k, _] : args.at(0)->attribs) ret.push_back(vm->PyStr(k));
|
||||
for (auto& [k, _] : args[0]->attribs) ret.push_back(vm->PyStr(k));
|
||||
return vm->PyList(ret);
|
||||
});
|
||||
|
||||
@ -97,7 +97,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
|
||||
_vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) {
|
||||
vm->_assert(args.size() == 1, "expected 1 argument");
|
||||
return args.at(0)->attribs[__class__];
|
||||
return args[0]->attribs[__class__];
|
||||
});
|
||||
|
||||
_vm->bindMethod("range", "__new__", [](VM* vm, PyVarList args) {
|
||||
@ -112,7 +112,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bindMethod("range", "__iter__", [](VM* vm, PyVarList args) {
|
||||
vm->__checkType(args.at(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);});
|
||||
return vm->PyIter(iter);
|
||||
});
|
||||
@ -215,7 +215,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bindMethod("str", "__eq__", [](VM* vm, PyVarList args) {
|
||||
if(args.at(0)->isType(vm->_tp_str) && args.at(1)->isType(vm->_tp_str))
|
||||
if(args[0]->isType(vm->_tp_str) && args[1]->isType(vm->_tp_str))
|
||||
return vm->PyBool(vm->PyStr_AS_C(args[0]) == vm->PyStr_AS_C(args[1]));
|
||||
return vm->PyBool(args[0] == args[1]); // fallback
|
||||
});
|
||||
@ -299,7 +299,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
|
||||
/************ PyList ************/
|
||||
_vm->bindMethod("list", "__iter__", [](VM* vm, PyVarList args) {
|
||||
vm->__checkType(args.at(0), vm->_tp_list);
|
||||
vm->__checkType(args[0], vm->_tp_list);
|
||||
auto iter = std::make_shared<VectorIterator>(args[0]);
|
||||
return vm->PyIter(iter);
|
||||
});
|
||||
@ -383,7 +383,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
|
||||
/************ PyTuple ************/
|
||||
_vm->bindMethod("tuple", "__iter__", [](VM* vm, PyVarList args) {
|
||||
vm->__checkType(args.at(0), vm->_tp_tuple);
|
||||
vm->__checkType(args[0], vm->_tp_tuple);
|
||||
auto iter = std::make_shared<VectorIterator>(args[0]);
|
||||
return vm->PyIter(iter);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user