This commit is contained in:
blueloveTH 2023-01-11 18:25:03 +08:00
parent 01c7ab2af3
commit 176211611c
4 changed files with 96 additions and 99 deletions

View File

@ -4,7 +4,7 @@
class RangeIterator : public BaseIterator { class RangeIterator : public BaseIterator {
private: private:
_Int current; i64 current;
_Range r; _Range r;
public: public:
RangeIterator(VM* vm, PyVar _ref) : BaseIterator(vm, _ref) { RangeIterator(VM* vm, PyVar _ref) : BaseIterator(vm, _ref) {

View File

@ -2,8 +2,8 @@
#include "safestl.h" #include "safestl.h"
typedef int64_t _Int; typedef int64_t i64;
typedef double _Float; typedef double f64;
struct CodeObject; struct CodeObject;
struct BaseRef; struct BaseRef;
@ -35,9 +35,9 @@ struct _BoundedMethod {
}; };
struct _Range { struct _Range {
_Int start = 0; i64 start = 0;
_Int stop = -1; i64 stop = -1;
_Int step = 1; i64 step = 1;
}; };
struct _Slice { struct _Slice {
@ -71,12 +71,9 @@ struct PyObject {
PyVar _type; PyVar _type;
PyVarDict attribs; PyVarDict attribs;
inline bool isType(const PyVar& type){ return this->_type == type; } inline bool is_type(const PyVar& type) const noexcept{ return this->_type == type; }
inline virtual void* value() = 0; inline virtual void* value() = 0;
// currently __name__ is only used for 'type'
PyVar _typeName(){ return _type->attribs[__name__]; }
PyObject(const PyVar& type) : _type(type) {} PyObject(const PyVar& type) : _type(type) {}
virtual ~PyObject() = default; virtual ~PyObject() = default;
}; };
@ -90,5 +87,5 @@ struct Py_ : PyObject {
}; };
#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_valueT) #define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_valueT)
#define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName()) #define UNION_NAME(obj) UNION_GET(_Str, (obj)->attribs[__name__])
#define UNION_NAME(obj) UNION_GET(_Str, (obj)->attribs[__name__]) #define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_type->attribs[__name__])

View File

@ -19,7 +19,7 @@ _Code VM::compile(_Str source, _Str filename, CompileMode mode) {
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
if(!vm->is_int_or_float(args[0], args[1])) \ if(!vm->is_int_or_float(args[0], args[1])) \
vm->typeError("unsupported operand type(s) for " #op ); \ vm->typeError("unsupported operand type(s) for " #op ); \
if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \ if(args._index(0)->is_type(vm->_tp_int) && args._index(1)->is_type(vm->_tp_int)){ \
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
}else{ \ }else{ \
return vm->PyFloat(vm->num_to_float(args._index(0)) op vm->num_to_float(args._index(1))); \ return vm->PyFloat(vm->num_to_float(args._index(0)) op vm->num_to_float(args._index(1))); \
@ -92,7 +92,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindBuiltinFunc("chr", [](VM* vm, const pkpy::ArgList& args) { _vm->bindBuiltinFunc("chr", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 1); vm->check_args_size(args, 1);
_Int i = vm->PyInt_AS_C(args[0]); i64 i = vm->PyInt_AS_C(args[0]);
if (i < 0 || i > 128) vm->valueError("chr() arg not in range(128)"); if (i < 0 || i > 128) vm->valueError("chr() arg not in range(128)");
return vm->PyStr(std::string(1, (char)i)); return vm->PyStr(std::string(1, (char)i));
}); });
@ -101,7 +101,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
vm->check_args_size(args, 1); vm->check_args_size(args, 1);
_Str s = vm->PyStr_AS_C(args[0]); _Str s = vm->PyStr_AS_C(args[0]);
if (s.size() != 1) vm->typeError("ord() expected an ASCII character"); if (s.size() != 1) vm->typeError("ord() expected an ASCII character");
return vm->PyInt((_Int)s[0]); return vm->PyInt((i64)s[0]);
}); });
_vm->bindBuiltinFunc("globals", [](VM* vm, const pkpy::ArgList& args) { _vm->bindBuiltinFunc("globals", [](VM* vm, const pkpy::ArgList& args) {
@ -198,7 +198,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethodMulti({"int", "float"}, "__truediv__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethodMulti({"int", "float"}, "__truediv__", [](VM* vm, const pkpy::ArgList& args) {
if(!vm->is_int_or_float(args[0], args[1])) if(!vm->is_int_or_float(args[0], args[1]))
vm->typeError("unsupported operand type(s) for " "/" ); vm->typeError("unsupported operand type(s) for " "/" );
_Float rhs = vm->num_to_float(args[1]); f64 rhs = vm->num_to_float(args[1]);
if (rhs == 0) vm->zeroDivisionError(); if (rhs == 0) vm->zeroDivisionError();
return vm->PyFloat(vm->num_to_float(args[0]) / rhs); return vm->PyFloat(vm->num_to_float(args[0]) / rhs);
}); });
@ -206,10 +206,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethodMulti({"int", "float"}, "__pow__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethodMulti({"int", "float"}, "__pow__", [](VM* vm, const pkpy::ArgList& args) {
if(!vm->is_int_or_float(args[0], args[1])) if(!vm->is_int_or_float(args[0], args[1]))
vm->typeError("unsupported operand type(s) for " "**" ); vm->typeError("unsupported operand type(s) for " "**" );
if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ if(args[0]->is_type(vm->_tp_int) && args[1]->is_type(vm->_tp_int)){
return vm->PyInt((_Int)round(pow(vm->PyInt_AS_C(args[0]), vm->PyInt_AS_C(args[1])))); return vm->PyInt((i64)round(pow(vm->PyInt_AS_C(args[0]), vm->PyInt_AS_C(args[1]))));
}else{ }else{
return vm->PyFloat((_Float)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1]))); return vm->PyFloat((f64)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
} }
}); });
@ -217,14 +217,14 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("int", "__new__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("int", "__new__", [](VM* vm, const pkpy::ArgList& args) {
if(args.size() == 0) return vm->PyInt(0); if(args.size() == 0) return vm->PyInt(0);
vm->check_args_size(args, 1); vm->check_args_size(args, 1);
if (args[0]->isType(vm->_tp_int)) return args[0]; if (args[0]->is_type(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]->is_type(vm->_tp_float)) return vm->PyInt((i64)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]->is_type(vm->_tp_bool)) return vm->PyInt(vm->PyBool_AS_C(args[0]) ? 1 : 0);
if (args[0]->isType(vm->_tp_str)) { if (args[0]->is_type(vm->_tp_str)) {
const _Str& s = vm->PyStr_AS_C(args[0]); const _Str& s = vm->PyStr_AS_C(args[0]);
try{ try{
size_t parsed = 0; size_t parsed = 0;
_Int val = std::stoll(s, &parsed, 10); i64 val = std::stoll(s, &parsed, 10);
if(parsed != s.size()) throw std::invalid_argument(""); if(parsed != s.size()) throw std::invalid_argument("");
return vm->PyInt(val); return vm->PyInt(val);
}catch(std::invalid_argument&){ }catch(std::invalid_argument&){
@ -236,17 +236,17 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
_vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) {
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) if(!args[0]->is_type(vm->_tp_int) || !args[1]->is_type(vm->_tp_int))
vm->typeError("unsupported operand type(s) for " "//" ); vm->typeError("unsupported operand type(s) for " "//" );
_Int rhs = vm->PyInt_AS_C(args._index(1)); i64 rhs = vm->PyInt_AS_C(args._index(1));
if(rhs == 0) vm->zeroDivisionError(); if(rhs == 0) vm->zeroDivisionError();
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) / rhs); return vm->PyInt(vm->PyInt_AS_C(args._index(0)) / rhs);
}); });
_vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) {
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) if(!args[0]->is_type(vm->_tp_int) || !args[1]->is_type(vm->_tp_int))
vm->typeError("unsupported operand type(s) for " "%" ); vm->typeError("unsupported operand type(s) for " "%" );
_Int rhs = vm->PyInt_AS_C(args._index(1)); i64 rhs = vm->PyInt_AS_C(args._index(1));
if(rhs == 0) vm->zeroDivisionError(); if(rhs == 0) vm->zeroDivisionError();
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) % rhs); return vm->PyInt(vm->PyInt_AS_C(args._index(0)) % rhs);
}); });
@ -261,7 +261,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
#define __INT_BITWISE_OP(name,op) \ #define __INT_BITWISE_OP(name,op) \
_vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ if(!args[0]->is_type(vm->_tp_int) || !args[1]->is_type(vm->_tp_int)) \
vm->typeError("unsupported operand type(s) for " #op ); \ vm->typeError("unsupported operand type(s) for " #op ); \
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
}); });
@ -278,15 +278,15 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) {
if(args.size() == 0) return vm->PyFloat(0.0); if(args.size() == 0) return vm->PyFloat(0.0);
vm->check_args_size(args, 1); vm->check_args_size(args, 1);
if (args[0]->isType(vm->_tp_int)) return vm->PyFloat((_Float)vm->PyInt_AS_C(args[0])); if (args[0]->is_type(vm->_tp_int)) return vm->PyFloat((f64)vm->PyInt_AS_C(args[0]));
if (args[0]->isType(vm->_tp_float)) return args[0]; if (args[0]->is_type(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]->is_type(vm->_tp_bool)) return vm->PyFloat(vm->PyBool_AS_C(args[0]) ? 1.0 : 0.0);
if (args[0]->isType(vm->_tp_str)) { if (args[0]->is_type(vm->_tp_str)) {
const _Str& s = vm->PyStr_AS_C(args[0]); const _Str& s = vm->PyStr_AS_C(args[0]);
if(s == "inf") return vm->PyFloat(INFINITY); if(s == "inf") return vm->PyFloat(INFINITY);
if(s == "-inf") return vm->PyFloat(-INFINITY); if(s == "-inf") return vm->PyFloat(-INFINITY);
try{ try{
_Float val = std::stod(s); f64 val = std::stod(s);
return vm->PyFloat(val); return vm->PyFloat(val);
}catch(std::invalid_argument&){ }catch(std::invalid_argument&){
vm->valueError("invalid literal for float(): '" + s + "'"); vm->valueError("invalid literal for float(): '" + s + "'");
@ -297,17 +297,17 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
_vm->bindMethod("float", "__repr__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("float", "__repr__", [](VM* vm, const pkpy::ArgList& args) {
_Float val = vm->PyFloat_AS_C(args[0]); f64 val = vm->PyFloat_AS_C(args[0]);
if(std::isinf(val) || std::isnan(val)) return vm->PyStr(std::to_string(val)); if(std::isinf(val) || std::isnan(val)) return vm->PyStr(std::to_string(val));
_StrStream ss; _StrStream ss;
ss << std::setprecision(std::numeric_limits<_Float>::max_digits10-1) << val; ss << std::setprecision(std::numeric_limits<f64>::max_digits10-1) << val;
std::string s = ss.str(); std::string s = ss.str();
if(std::all_of(s.begin()+1, 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);
}); });
_vm->bindMethod("float", "__json__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("float", "__json__", [](VM* vm, const pkpy::ArgList& args) {
_Float val = vm->PyFloat_AS_C(args[0]); f64 val = vm->PyFloat_AS_C(args[0]);
if(std::isinf(val) || std::isnan(val)){ if(std::isinf(val) || std::isnan(val)){
vm->valueError("cannot jsonify 'nan' or 'inf'"); vm->valueError("cannot jsonify 'nan' or 'inf'");
} }
@ -321,7 +321,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
_vm->bindMethod("str", "__add__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("str", "__add__", [](VM* vm, const pkpy::ArgList& args) {
if(!args[0]->isType(vm->_tp_str) || !args[1]->isType(vm->_tp_str)) if(!args[0]->is_type(vm->_tp_str) || !args[1]->is_type(vm->_tp_str))
vm->typeError("unsupported operand type(s) for " "+" ); vm->typeError("unsupported operand type(s) for " "+" );
const _Str& lhs = vm->PyStr_AS_C(args[0]); const _Str& lhs = vm->PyStr_AS_C(args[0]);
const _Str& rhs = vm->PyStr_AS_C(args[1]); const _Str& rhs = vm->PyStr_AS_C(args[1]);
@ -360,7 +360,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
}); });
_vm->bindMethod("str", "__eq__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("str", "__eq__", [](VM* vm, const pkpy::ArgList& args) {
if(args[0]->isType(vm->_tp_str) && args[1]->isType(vm->_tp_str)) if(args[0]->is_type(vm->_tp_str) && args[1]->is_type(vm->_tp_str))
return vm->PyBool(vm->PyStr_AS_C(args[0]) == vm->PyStr_AS_C(args[1])); return vm->PyBool(vm->PyStr_AS_C(args[0]) == vm->PyStr_AS_C(args[1]));
return vm->PyBool(args[0] == args[1]); // fallback return vm->PyBool(args[0] == args[1]); // fallback
}); });
@ -368,7 +368,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("str", "__getitem__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("str", "__getitem__", [](VM* vm, const pkpy::ArgList& args) {
const _Str& _self (vm->PyStr_AS_C(args[0])); const _Str& _self (vm->PyStr_AS_C(args[0]));
if(args[1]->isType(vm->_tp_slice)){ if(args[1]->is_type(vm->_tp_slice)){
_Slice s = vm->PySlice_AS_C(args[1]); _Slice s = vm->PySlice_AS_C(args[1]);
s.normalize(_self.u8_length()); s.normalize(_self.u8_length());
return vm->PyStr(_self.u8_substr(s.start, s.stop)); return vm->PyStr(_self.u8_substr(s.start, s.stop));
@ -440,9 +440,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
vm->check_args_size(args, 2, true); vm->check_args_size(args, 2, true);
const _Str& _self = vm->PyStr_AS_C(args[0]); const _Str& _self = vm->PyStr_AS_C(args[0]);
PyVarList* _list; PyVarList* _list;
if(args[1]->isType(vm->_tp_list)){ if(args[1]->is_type(vm->_tp_list)){
_list = &vm->PyList_AS_C(args[1]); _list = &vm->PyList_AS_C(args[1]);
}else if(args[1]->isType(vm->_tp_tuple)){ }else if(args[1]->is_type(vm->_tp_tuple)){
_list = &vm->PyTuple_AS_C(args[1]); _list = &vm->PyTuple_AS_C(args[1]);
}else{ }else{
vm->typeError("can only join a list or tuple"); vm->typeError("can only join a list or tuple");
@ -508,7 +508,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("list", "__getitem__", [](VM* vm, const pkpy::ArgList& args) { _vm->bindMethod("list", "__getitem__", [](VM* vm, const pkpy::ArgList& args) {
const PyVarList& _self = vm->PyList_AS_C(args[0]); const PyVarList& _self = vm->PyList_AS_C(args[0]);
if(args[1]->isType(vm->_tp_slice)){ if(args[1]->is_type(vm->_tp_slice)){
_Slice s = vm->PySlice_AS_C(args[1]); _Slice s = vm->PySlice_AS_C(args[1]);
s.normalize(_self.size()); s.normalize(_self.size());
PyVarList _new_list; PyVarList _new_list;
@ -718,8 +718,8 @@ void __addModuleMath(VM* vm){
vm->bindFunc(mod, "isclose", [](VM* vm, const pkpy::ArgList& args) { vm->bindFunc(mod, "isclose", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 2); vm->check_args_size(args, 2);
_Float a = vm->num_to_float(args[0]); f64 a = vm->num_to_float(args[0]);
_Float b = vm->num_to_float(args[1]); f64 b = vm->num_to_float(args[1]);
return vm->PyBool(fabs(a - b) < 1e-9); return vm->PyBool(fabs(a - b) < 1e-9);
}); });
@ -741,7 +741,7 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
if(fromStart && m.position() != 0){ if(fromStart && m.position() != 0){
return vm->None; return vm->None;
} }
PyVar ret = vm->new_object(vm->_userTypes["re.Match"], (_Int)1); PyVar ret = vm->new_object(vm->_userTypes["re.Match"], (i64)1);
vm->setattr(ret, "_start", vm->PyInt( vm->setattr(ret, "_start", vm->PyInt(
string.__to_u8_index(m.position()) string.__to_u8_index(m.position())
)); ));

106
src/vm.h
View File

@ -87,7 +87,7 @@ protected:
pkpy::ArgList items = frame->pop_n_reversed(byte.arg); pkpy::ArgList items = frame->pop_n_reversed(byte.arg);
bool done = false; bool done = false;
for(int i=0; i<items.size(); i++){ for(int i=0; i<items.size(); i++){
if(!items[i]->isType(_tp_ref)) { if(!items[i]->is_type(_tp_ref)) {
done = true; done = true;
PyVarList values = items.toList(); PyVarList values = items.toList();
for(int j=i; j<values.size(); j++) frame->try_deref(this, values[j]); for(int j=i; j<values.size(); j++) frame->try_deref(this, values[j]);
@ -377,16 +377,16 @@ public:
initializeBuiltinClasses(); initializeBuiltinClasses();
_small_integers.reserve(300); _small_integers.reserve(300);
for(_Int i=-5; i<=256; i++) _small_integers.push_back(new_object(_tp_int, i)); for(i64 i=-5; i<=256; i++) _small_integers.push_back(new_object(_tp_int, i));
} }
void keyboardInterrupt(){ void keyboardInterrupt(){
_stop_flag = true; _stop_flag = true;
} }
void sleepForSecs(_Float sec){ void sleepForSecs(f64 sec){
_Int ms = (_Int)(sec * 1000); i64 ms = (i64)(sec * 1000);
for(_Int i=0; i<ms; i+=20){ for(i64 i=0; i<ms; i+=20){
test_stop_flag(); test_stop_flag();
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
emscripten_sleep(20); emscripten_sleep(20);
@ -408,7 +408,7 @@ public:
} }
PyVar asRepr(const PyVar& obj){ PyVar asRepr(const PyVar& obj){
if(obj->isType(_tp_type)) return PyStr("<class '" + UNION_GET(_Str, obj->attribs[__name__]) + "'>"); if(obj->is_type(_tp_type)) return PyStr("<class '" + UNION_GET(_Str, obj->attribs[__name__]) + "'>");
return call(obj, __repr__); return call(obj, __repr__);
} }
@ -418,9 +418,9 @@ public:
const PyVar& asBool(const PyVar& obj){ const PyVar& asBool(const PyVar& obj){
if(obj == None) return False; if(obj == None) return False;
if(obj->_type == _tp_bool) return obj; if(obj->is_type(_tp_bool)) return obj;
if(obj->_type == _tp_int) return PyBool(PyInt_AS_C(obj) != 0); if(obj->is_type(_tp_int)) return PyBool(PyInt_AS_C(obj) != 0);
if(obj->_type == _tp_float) return PyBool(PyFloat_AS_C(obj) != 0.0); if(obj->is_type(_tp_float)) return PyBool(PyFloat_AS_C(obj) != 0.0);
PyVarOrNull len_fn = getattr(obj, __len__, false); PyVarOrNull len_fn = getattr(obj, __len__, false);
if(len_fn != nullptr){ if(len_fn != nullptr){
PyVar ret = call(len_fn); PyVar ret = call(len_fn);
@ -461,13 +461,13 @@ public:
} }
PyVar call(const PyVar& _callable, pkpy::ArgList args, const pkpy::ArgList& kwargs, bool opCall){ PyVar call(const PyVar& _callable, pkpy::ArgList args, const pkpy::ArgList& kwargs, bool opCall){
if(_callable->isType(_tp_type)){ if(_callable->is_type(_tp_type)){
auto it = _callable->attribs.find(__new__); auto it = _callable->attribs.find(__new__);
PyVar obj; PyVar obj;
if(it != _callable->attribs.end()){ if(it != _callable->attribs.end()){
obj = call(it->second, args, kwargs, false); obj = call(it->second, args, kwargs, false);
}else{ }else{
obj = new_object(_callable, (_Int)-1); obj = new_object(_callable, (i64)-1);
PyVarOrNull init_fn = getattr(obj, __init__, false); PyVarOrNull init_fn = getattr(obj, __init__, false);
if (init_fn != nullptr) call(init_fn, args, kwargs, false); if (init_fn != nullptr) call(init_fn, args, kwargs, false);
} }
@ -475,7 +475,7 @@ public:
} }
const PyVar* callable = &_callable; const PyVar* callable = &_callable;
if((*callable)->isType(_tp_bounded_method)){ if((*callable)->is_type(_tp_bounded_method)){
auto& bm = PyBoundedMethod_AS_C((*callable)); auto& bm = PyBoundedMethod_AS_C((*callable));
// TODO: avoid insertion here, bad performance // TODO: avoid insertion here, bad performance
pkpy::ArgList new_args(args.size()+1); pkpy::ArgList new_args(args.size()+1);
@ -485,11 +485,11 @@ public:
args = std::move(new_args); args = std::move(new_args);
} }
if((*callable)->isType(_tp_native_function)){ if((*callable)->is_type(_tp_native_function)){
const auto& f = UNION_GET(_CppFunc, *callable); const auto& f = UNION_GET(_CppFunc, *callable);
// _CppFunc do not support kwargs // _CppFunc do not support kwargs
return f(this, args); return f(this, args);
} else if((*callable)->isType(_tp_function)){ } else if((*callable)->is_type(_tp_function)){
const _Func& fn = PyFunction_AS_C((*callable)); const _Func& fn = PyFunction_AS_C((*callable));
PyVarDict locals; PyVarDict locals;
int i = 0; int i = 0;
@ -605,7 +605,7 @@ public:
} }
PyVar new_user_type_object(PyVar mod, _Str name, PyVar base){ PyVar new_user_type_object(PyVar mod, _Str name, PyVar base){
PyVar obj = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)1, _tp_type); PyVar obj = pkpy::make_shared<PyObject, Py_<i64>>((i64)1, _tp_type);
setattr(obj, __base__, base); setattr(obj, __base__, base);
_Str fullName = UNION_NAME(mod) + "." +name; _Str fullName = UNION_NAME(mod) + "." +name;
setattr(obj, __name__, PyStr(fullName)); setattr(obj, __name__, PyStr(fullName));
@ -616,7 +616,7 @@ public:
PyVar new_type_object(_Str name, PyVar base=nullptr) { PyVar new_type_object(_Str name, PyVar base=nullptr) {
if(base == nullptr) base = _tp_object; if(base == nullptr) base = _tp_object;
PyVar obj = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)0, _tp_type); PyVar obj = pkpy::make_shared<PyObject, Py_<i64>>((i64)0, _tp_type);
setattr(obj, __base__, base); setattr(obj, __base__, base);
_types[name] = obj; _types[name] = obj;
return obj; return obj;
@ -624,12 +624,12 @@ public:
template<typename T> template<typename T>
inline PyVar new_object(PyVar type, T _value) { inline PyVar new_object(PyVar type, T _value) {
if(!type->isType(_tp_type)) UNREACHABLE(); if(!type->is_type(_tp_type)) UNREACHABLE();
return pkpy::make_shared<PyObject, Py_<T>>(_value, type); return pkpy::make_shared<PyObject, Py_<T>>(_value, type);
} }
PyVar newModule(_Str name) { PyVar newModule(_Str name) {
PyVar obj = new_object(_tp_module, (_Int)-2); PyVar obj = new_object(_tp_module, (i64)-2);
setattr(obj, __name__, PyStr(name)); setattr(obj, __name__, PyStr(name));
_modules[name] = obj; _modules[name] = obj;
return obj; return obj;
@ -643,12 +643,12 @@ public:
PyVarDict::iterator it; PyVarDict::iterator it;
PyObject* cls; PyObject* cls;
if(obj->isType(_tp_super)){ if(obj->is_type(_tp_super)){
const PyVar* root = &obj; const PyVar* root = &obj;
int depth = 1; int depth = 1;
while(true){ while(true){
root = &UNION_GET(PyVar, *root); root = &UNION_GET(PyVar, *root);
if(!(*root)->isType(_tp_super)) break; if(!(*root)->is_type(_tp_super)) break;
depth++; depth++;
} }
cls = (*root)->_type.get(); cls = (*root)->_type.get();
@ -666,7 +666,7 @@ public:
it = cls->attribs.find(name); it = cls->attribs.find(name);
if(it != cls->attribs.end()){ if(it != cls->attribs.end()){
PyVar valueFromCls = it->second; PyVar valueFromCls = it->second;
if(valueFromCls->isType(_tp_function) || valueFromCls->isType(_tp_native_function)){ if(valueFromCls->is_type(_tp_function) || valueFromCls->is_type(_tp_native_function)){
return PyBoundedMethod({obj, std::move(valueFromCls)}); return PyBoundedMethod({obj, std::move(valueFromCls)});
}else{ }else{
return valueFromCls; return valueFromCls;
@ -680,7 +680,7 @@ public:
template<typename T> template<typename T>
void setattr(PyObject* obj, const _Str& name, T&& value) { void setattr(PyObject* obj, const _Str& name, T&& value) {
while(obj->isType(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get(); while(obj->is_type(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get();
obj->attribs[name] = value; obj->attribs[name] = value;
} }
@ -724,26 +724,26 @@ public:
} }
inline bool is_int_or_float(const PyVar& obj) const{ inline bool is_int_or_float(const PyVar& obj) const{
return obj->isType(_tp_int) || obj->isType(_tp_float); return obj->is_type(_tp_int) || obj->is_type(_tp_float);
} }
inline bool is_int_or_float(const PyVar& obj1, const PyVar& obj2) const{ inline bool is_int_or_float(const PyVar& obj1, const PyVar& obj2) const{
return is_int_or_float(obj1) && is_int_or_float(obj2); return is_int_or_float(obj1) && is_int_or_float(obj2);
} }
inline _Float num_to_float(const PyVar& obj){ inline f64 num_to_float(const PyVar& obj){
if (obj->isType(_tp_int)){ if (obj->is_type(_tp_int)){
return (_Float)PyInt_AS_C(obj); return (f64)PyInt_AS_C(obj);
}else if(obj->isType(_tp_float)){ }else if(obj->is_type(_tp_float)){
return PyFloat_AS_C(obj); return PyFloat_AS_C(obj);
} }
UNREACHABLE(); UNREACHABLE();
} }
PyVar num_negated(const PyVar& obj){ PyVar num_negated(const PyVar& obj){
if (obj->isType(_tp_int)){ if (obj->is_type(_tp_int)){
return PyInt(-PyInt_AS_C(obj)); return PyInt(-PyInt_AS_C(obj));
}else if(obj->isType(_tp_float)){ }else if(obj->is_type(_tp_float)){
return PyFloat(-PyFloat_AS_C(obj)); return PyFloat(-PyFloat_AS_C(obj));
} }
typeError("unsupported operand type(s) for -"); typeError("unsupported operand type(s) for -");
@ -813,7 +813,7 @@ public:
for(int i=0; i<code->co_consts.size(); i++){ for(int i=0; i<code->co_consts.size(); i++){
PyVar obj = code->co_consts[i]; PyVar obj = code->co_consts[i];
if(obj->isType(_tp_function)){ if(obj->is_type(_tp_function)){
const auto& f = PyFunction_AS_C(obj); const auto& f = PyFunction_AS_C(obj);
ss << disassemble(f->code); ss << disassemble(f->code);
} }
@ -836,17 +836,17 @@ public:
inline const BaseRef* PyRef_AS_C(const PyVar& obj) inline const BaseRef* PyRef_AS_C(const PyVar& obj)
{ {
if(!obj->isType(_tp_ref)) typeError("expected an l-value"); if(!obj->is_type(_tp_ref)) typeError("expected an l-value");
return (const BaseRef*)(obj->value()); return (const BaseRef*)(obj->value());
} }
__DEF_PY_AS_C(Int, _Int, _tp_int) __DEF_PY_AS_C(Int, i64, _tp_int)
inline PyVar PyInt(_Int value) { inline PyVar PyInt(i64 value) {
if(value >= -5 && value <= 256) return _small_integers[value + 5]; if(value >= -5 && value <= 256) return _small_integers[value + 5];
return new_object(_tp_int, value); return new_object(_tp_int, value);
} }
DEF_NATIVE(Float, _Float, _tp_float) DEF_NATIVE(Float, f64, _tp_float)
DEF_NATIVE(Str, _Str, _tp_str) DEF_NATIVE(Str, _Str, _tp_str)
DEF_NATIVE(List, PyVarList, _tp_list) DEF_NATIVE(List, PyVarList, _tp_list)
DEF_NATIVE(Tuple, PyVarList, _tp_tuple) DEF_NATIVE(Tuple, PyVarList, _tp_tuple)
@ -862,8 +862,8 @@ public:
inline const PyVar& PyBool(bool value){return value ? True : False;} inline const PyVar& PyBool(bool value){return value ? True : False;}
void initializeBuiltinClasses(){ void initializeBuiltinClasses(){
_tp_object = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)0, nullptr); _tp_object = pkpy::make_shared<PyObject, Py_<i64>>((i64)0, nullptr);
_tp_type = pkpy::make_shared<PyObject, Py_<_Int>>((_Int)0, nullptr); _tp_type = pkpy::make_shared<PyObject, Py_<i64>>((i64)0, nullptr);
_types["object"] = _tp_object; _types["object"] = _tp_object;
_types["type"] = _tp_type; _types["type"] = _tp_type;
@ -888,8 +888,8 @@ public:
_tp_bounded_method = new_type_object("_bounded_method"); _tp_bounded_method = new_type_object("_bounded_method");
_tp_super = new_type_object("super"); _tp_super = new_type_object("super");
this->None = new_object(_types["NoneType"], (_Int)0); this->None = new_object(_types["NoneType"], (i64)0);
this->Ellipsis = new_object(_types["ellipsis"], (_Int)0); this->Ellipsis = new_object(_types["ellipsis"], (i64)0);
this->True = new_object(_tp_bool, true); this->True = new_object(_tp_bool, true);
this->False = new_object(_tp_bool, false); this->False = new_object(_tp_bool, false);
this->builtins = newModule("builtins"); this->builtins = newModule("builtins");
@ -904,7 +904,7 @@ public:
setattr(type, __name__, PyStr(name)); setattr(type, __name__, PyStr(name));
} }
this->__py2py_call_signal = new_object(_tp_object, (_Int)7); this->__py2py_call_signal = new_object(_tp_object, (i64)7);
std::vector<_Str> publicTypes = {"type", "object", "bool", "int", "float", "str", "list", "tuple", "range"}; std::vector<_Str> publicTypes = {"type", "object", "bool", "int", "float", "str", "list", "tuple", "range"};
for (auto& name : publicTypes) { for (auto& name : publicTypes) {
@ -912,19 +912,19 @@ public:
} }
} }
_Int hash(const PyVar& obj){ i64 hash(const PyVar& obj){
if (obj->isType(_tp_int)) return PyInt_AS_C(obj); if (obj->is_type(_tp_int)) return PyInt_AS_C(obj);
if (obj->isType(_tp_bool)) return PyBool_AS_C(obj) ? 1 : 0; if (obj->is_type(_tp_bool)) return PyBool_AS_C(obj) ? 1 : 0;
if (obj->isType(_tp_float)){ if (obj->is_type(_tp_float)){
_Float val = PyFloat_AS_C(obj); f64 val = PyFloat_AS_C(obj);
return (_Int)std::hash<_Float>()(val); return (i64)std::hash<f64>()(val);
} }
if (obj->isType(_tp_str)) return PyStr_AS_C(obj).hash(); if (obj->is_type(_tp_str)) return PyStr_AS_C(obj).hash();
if (obj->isType(_tp_type)) return (_Int)obj.get(); if (obj->is_type(_tp_type)) return (i64)obj.get();
if (obj->isType(_tp_tuple)) { if (obj->is_type(_tp_tuple)) {
_Int x = 1000003; i64 x = 1000003;
for (const auto& item : PyTuple_AS_C(obj)) { for (const auto& item : PyTuple_AS_C(obj)) {
_Int y = hash(item); i64 y = hash(item);
// this is recommended by Github Copilot // this is recommended by Github Copilot
// i am not sure whether it is a good idea // i am not sure whether it is a good idea
x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2)); x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
@ -983,7 +983,7 @@ public:
inline void check_type(const PyVar& obj, const PyVar& type){ inline void check_type(const PyVar& obj, const PyVar& type){
#ifndef PKPY_NO_TYPE_CHECK #ifndef PKPY_NO_TYPE_CHECK
if(!obj->isType(type)) typeError("expected '" + UNION_NAME(type) + "', but got '" + UNION_TP_NAME(obj) + "'"); if(!obj->is_type(type)) typeError("expected '" + UNION_NAME(type) + "', but got '" + UNION_TP_NAME(obj) + "'");
#endif #endif
} }
@ -1089,7 +1089,7 @@ PyVar TupleRef::get(VM* vm, Frame* frame) const{
} }
void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{ void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{
if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){ if(!val->is_type(vm->_tp_tuple) && !val->is_type(vm->_tp_list)){
vm->typeError("only tuple or list can be unpacked"); vm->typeError("only tuple or list can be unpacked");
} }
const PyVarList& args = UNION_GET(PyVarList, val); const PyVarList& args = UNION_GET(PyVarList, val);
@ -1106,7 +1106,7 @@ void TupleRef::del(VM* vm, Frame* frame) const{
/***** Frame's Impl *****/ /***** Frame's Impl *****/
inline void Frame::try_deref(VM* vm, PyVar& v){ inline void Frame::try_deref(VM* vm, PyVar& v){
if(v->isType(vm->_tp_ref)) v = vm->PyRef_AS_C(v)->get(vm, this); if(v->is_type(vm->_tp_ref)) v = vm->PyRef_AS_C(v)->get(vm, this);
} }
/***** Iterators' Impl *****/ /***** Iterators' Impl *****/