mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-07 10:40:16 +00:00
up
This commit is contained in:
parent
944f98be6f
commit
3a0c495e78
@ -1029,7 +1029,7 @@ __LISTCOMP:
|
|||||||
if(match(TK("-"))){
|
if(match(TK("-"))){
|
||||||
consume(TK("@num"));
|
consume(TK("@num"));
|
||||||
PyVar val = parser->prev.value;
|
PyVar val = parser->prev.value;
|
||||||
return vm->numNegated(val);
|
return vm->num_negated(val);
|
||||||
}
|
}
|
||||||
if(match(TK("@num"))) return parser->prev.value;
|
if(match(TK("@num"))) return parser->prev.value;
|
||||||
if(match(TK("@str"))) return parser->prev.value;
|
if(match(TK("@str"))) return parser->prev.value;
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
#ifdef OPCODE
|
#ifdef OPCODE
|
||||||
|
|
||||||
OPCODE(NO_OP)
|
OPCODE(NO_OP)
|
||||||
OPCODE(DELETED_OP)
|
|
||||||
|
|
||||||
OPCODE(IMPORT_NAME)
|
OPCODE(IMPORT_NAME)
|
||||||
OPCODE(PRINT_EXPR)
|
OPCODE(PRINT_EXPR)
|
||||||
OPCODE(POP_TOP)
|
OPCODE(POP_TOP)
|
||||||
|
OPCODE(DUP_TOP)
|
||||||
OPCODE(CALL)
|
OPCODE(CALL)
|
||||||
OPCODE(RETURN_VALUE)
|
OPCODE(RETURN_VALUE)
|
||||||
|
|
||||||
@ -18,8 +17,6 @@ OPCODE(CONTAINS_OP)
|
|||||||
OPCODE(UNARY_NEGATIVE)
|
OPCODE(UNARY_NEGATIVE)
|
||||||
OPCODE(UNARY_NOT)
|
OPCODE(UNARY_NOT)
|
||||||
|
|
||||||
OPCODE(DUP_TOP)
|
|
||||||
|
|
||||||
OPCODE(BUILD_LIST)
|
OPCODE(BUILD_LIST)
|
||||||
OPCODE(BUILD_MAP)
|
OPCODE(BUILD_MAP)
|
||||||
OPCODE(BUILD_SET)
|
OPCODE(BUILD_SET)
|
||||||
@ -30,6 +27,11 @@ OPCODE(LIST_APPEND)
|
|||||||
OPCODE(GET_ITER)
|
OPCODE(GET_ITER)
|
||||||
OPCODE(FOR_ITER)
|
OPCODE(FOR_ITER)
|
||||||
|
|
||||||
|
OPCODE(WITH_ENTER)
|
||||||
|
OPCODE(WITH_EXIT)
|
||||||
|
OPCODE(LOOP_BREAK)
|
||||||
|
OPCODE(LOOP_CONTINUE)
|
||||||
|
|
||||||
OPCODE(POP_JUMP_IF_FALSE)
|
OPCODE(POP_JUMP_IF_FALSE)
|
||||||
OPCODE(JUMP_ABSOLUTE)
|
OPCODE(JUMP_ABSOLUTE)
|
||||||
OPCODE(SAFE_JUMP_ABSOLUTE)
|
OPCODE(SAFE_JUMP_ABSOLUTE)
|
||||||
@ -44,30 +46,22 @@ OPCODE(LOAD_EVAL_FN)
|
|||||||
OPCODE(LOAD_LAMBDA)
|
OPCODE(LOAD_LAMBDA)
|
||||||
OPCODE(LOAD_ELLIPSIS)
|
OPCODE(LOAD_ELLIPSIS)
|
||||||
OPCODE(LOAD_NAME)
|
OPCODE(LOAD_NAME)
|
||||||
OPCODE(LOAD_NAME_REF) // no arg
|
OPCODE(LOAD_NAME_REF)
|
||||||
|
|
||||||
OPCODE(ASSERT)
|
OPCODE(ASSERT)
|
||||||
OPCODE(RAISE_ERROR)
|
OPCODE(RAISE_ERROR)
|
||||||
|
|
||||||
OPCODE(STORE_FUNCTION)
|
OPCODE(STORE_FUNCTION)
|
||||||
OPCODE(BUILD_CLASS)
|
OPCODE(BUILD_CLASS)
|
||||||
OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
OPCODE(BUILD_ATTR_REF)
|
||||||
OPCODE(BUILD_INDEX_REF) // no arg, [ptr, expr] -> (*ptr)[expr]
|
OPCODE(BUILD_INDEX_REF)
|
||||||
OPCODE(STORE_NAME_REF) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack
|
OPCODE(STORE_NAME_REF)
|
||||||
OPCODE(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr
|
OPCODE(STORE_REF)
|
||||||
OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr
|
OPCODE(DELETE_REF)
|
||||||
|
|
||||||
OPCODE(BUILD_SMART_TUPLE) // if all elements are pointers, build a compound pointer, otherwise build a tuple
|
OPCODE(BUILD_SMART_TUPLE)
|
||||||
OPCODE(BUILD_STRING) // arg is the expr count, build a string from the top of the stack
|
OPCODE(BUILD_STRING)
|
||||||
|
|
||||||
OPCODE(GOTO)
|
OPCODE(GOTO)
|
||||||
|
|
||||||
OPCODE(WITH_ENTER)
|
|
||||||
OPCODE(WITH_EXIT)
|
|
||||||
|
|
||||||
OPCODE(RAISE_VARARGS)
|
|
||||||
|
|
||||||
OPCODE(LOOP_BREAK)
|
|
||||||
OPCODE(LOOP_CONTINUE)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
196
src/pocketpy.h
196
src/pocketpy.h
@ -17,22 +17,22 @@ _Code VM::compile(_Str source, _Str filename, CompileMode mode) {
|
|||||||
|
|
||||||
#define BIND_NUM_ARITH_OPT(name, op) \
|
#define BIND_NUM_ARITH_OPT(name, op) \
|
||||||
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
||||||
if(!vm->isIntOrFloat(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)->isType(vm->_tp_int) && args._index(1)->isType(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->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \
|
return vm->PyFloat(vm->num_to_float(args._index(0)) op vm->num_to_float(args._index(1))); \
|
||||||
} \
|
} \
|
||||||
});
|
});
|
||||||
|
|
||||||
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
||||||
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
_vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
||||||
if(!vm->isIntOrFloat(args[0], args[1])){ \
|
if(!vm->is_int_or_float(args[0], args[1])){ \
|
||||||
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
} \
|
} \
|
||||||
return vm->PyBool(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \
|
return vm->PyBool(vm->num_to_float(args._index(0)) op vm->num_to_float(args._index(1))); \
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -51,62 +51,62 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
#undef BIND_NUM_LOGICAL_OPT
|
#undef BIND_NUM_LOGICAL_OPT
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("__sys_stdout_write", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("__sys_stdout_write", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
(*vm->_stdout) << vm->PyStr_AS_C(args[0]);
|
(*vm->_stdout) << vm->PyStr_AS_C(args[0]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("super", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("super", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 0);
|
vm->check_args_size(args, 0);
|
||||||
auto it = vm->topFrame()->f_locals.find(m_self);
|
auto it = vm->top_frame()->f_locals.find(m_self);
|
||||||
if(it == vm->topFrame()->f_locals.end()) vm->typeError("super() can only be called in a class method");
|
if(it == vm->top_frame()->f_locals.end()) vm->typeError("super() can only be called in a class method");
|
||||||
return vm->newObject(vm->_tp_super, it->second);
|
return vm->new_object(vm->_tp_super, it->second);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("eval", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("eval", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
||||||
_Code code = vm->compile(expr, "<eval>", EVAL_MODE);
|
_Code code = vm->compile(expr, "<eval>", EVAL_MODE);
|
||||||
return vm->_exec(code, vm->topFrame()->_module, vm->topFrame()->f_locals_copy());
|
return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->f_locals_copy());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("isinstance", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("isinstance", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2);
|
vm->check_args_size(args, 2);
|
||||||
return vm->PyBool(vm->isInstance(args[0], args[1]));
|
return vm->PyBool(vm->isinstance(args[0], args[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("repr", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("repr", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->asRepr(args[0]);
|
return vm->asRepr(args[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("hash", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("hash", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyInt(vm->hash(args[0]));
|
return vm->PyInt(vm->hash(args[0]));
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("len", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("len", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->call(args[0], __len__, pkpy::noArg());
|
return vm->call(args[0], __len__, pkpy::noArg());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("chr", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("chr", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
_Int i = vm->PyInt_AS_C(args[0]);
|
_Int 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));
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("ord", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("ord", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(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((_Int)s[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("globals", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("globals", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 0);
|
vm->check_args_size(args, 0);
|
||||||
const auto& d = vm->topFrame()->f_globals();
|
const auto& d = vm->top_frame()->f_globals();
|
||||||
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
||||||
for (const auto& [k, v] : d) {
|
for (const auto& [k, v] : d) {
|
||||||
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
||||||
@ -115,8 +115,8 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("locals", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("locals", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 0);
|
vm->check_args_size(args, 0);
|
||||||
const auto& d = vm->topFrame()->f_locals;
|
const auto& d = vm->top_frame()->f_locals;
|
||||||
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
||||||
for (const auto& [k, v] : d) {
|
for (const auto& [k, v] : d) {
|
||||||
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
||||||
@ -125,14 +125,14 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("hex", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("hex", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::hex << vm->PyInt_AS_C(args[0]);
|
ss << std::hex << vm->PyInt_AS_C(args[0]);
|
||||||
return vm->PyStr("0x" + ss.str());
|
return vm->PyStr("0x" + ss.str());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc("dir", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc("dir", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
std::vector<_Str> names;
|
std::vector<_Str> names;
|
||||||
for (auto& [k, _] : args[0]->attribs) names.push_back(k);
|
for (auto& [k, _] : args[0]->attribs) names.push_back(k);
|
||||||
for (auto& [k, _] : args[0]->_type->attribs) {
|
for (auto& [k, _] : args[0]->_type->attribs) {
|
||||||
@ -156,12 +156,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("type", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("type", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return args[0]->_type;
|
return args[0]->_type;
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("type", "__eq__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("type", "__eq__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2, true);
|
vm->check_args_size(args, 2, true);
|
||||||
return vm->PyBool(args[0] == args[1]);
|
return vm->PyBool(args[0] == args[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("range", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("range", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkType(args[0], vm->_tp_range);
|
vm->check_type(args[0], vm->_tp_range);
|
||||||
return vm->PyIter(
|
return vm->PyIter(
|
||||||
pkpy::make_shared<BaseIterator, RangeIterator>(vm, args[0])
|
pkpy::make_shared<BaseIterator, RangeIterator>(vm, args[0])
|
||||||
);
|
);
|
||||||
@ -196,27 +196,27 @@ 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->isIntOrFloat(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->numToFloat(args[1]);
|
_Float rhs = vm->num_to_float(args[1]);
|
||||||
if (rhs == 0) vm->zeroDivisionError();
|
if (rhs == 0) vm->zeroDivisionError();
|
||||||
return vm->PyFloat(vm->numToFloat(args[0]) / rhs);
|
return vm->PyFloat(vm->num_to_float(args[0]) / rhs);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethodMulti({"int", "float"}, "__pow__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethodMulti({"int", "float"}, "__pow__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(!vm->isIntOrFloat(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]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){
|
||||||
return vm->PyInt((_Int)round(pow(vm->PyInt_AS_C(args[0]), vm->PyInt_AS_C(args[1]))));
|
return vm->PyInt((_Int)round(pow(vm->PyInt_AS_C(args[0]), vm->PyInt_AS_C(args[1]))));
|
||||||
}else{
|
}else{
|
||||||
return vm->PyFloat((_Float)pow(vm->numToFloat(args[0]), vm->numToFloat(args[1])));
|
return vm->PyFloat((_Float)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/************ PyInt ************/
|
/************ PyInt ************/
|
||||||
_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->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
if (args[0]->isType(vm->_tp_int)) return args[0];
|
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_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_bool)) return vm->PyInt(vm->PyBool_AS_C(args[0]) ? 1 : 0);
|
||||||
@ -277,7 +277,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
/************ PyFloat ************/
|
/************ PyFloat ************/
|
||||||
_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->__checkArgSize(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]->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_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_bool)) return vm->PyFloat(vm->PyBool_AS_C(args[0]) ? 1.0 : 0.0);
|
||||||
@ -316,7 +316,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
/************ PyString ************/
|
/************ PyString ************/
|
||||||
_vm->bindMethod("str", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->asStr(args[0]);
|
return vm->asStr(args[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "upper", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "upper", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
const _Str& _self (vm->PyStr_AS_C(args[0]));
|
const _Str& _self (vm->PyStr_AS_C(args[0]));
|
||||||
_StrStream ss;
|
_StrStream ss;
|
||||||
for(auto c : _self) ss << (char)toupper(c);
|
for(auto c : _self) ss << (char)toupper(c);
|
||||||
@ -400,7 +400,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "lower", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "lower", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
const _Str& _self (vm->PyStr_AS_C(args[0]));
|
const _Str& _self (vm->PyStr_AS_C(args[0]));
|
||||||
_StrStream ss;
|
_StrStream ss;
|
||||||
for(auto c : _self) ss << (char)tolower(c);
|
for(auto c : _self) ss << (char)tolower(c);
|
||||||
@ -408,7 +408,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "replace", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "replace", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 3, true);
|
vm->check_args_size(args, 3, true);
|
||||||
const _Str& _self = vm->PyStr_AS_C(args[0]);
|
const _Str& _self = vm->PyStr_AS_C(args[0]);
|
||||||
const _Str& _old = vm->PyStr_AS_C(args[1]);
|
const _Str& _old = vm->PyStr_AS_C(args[1]);
|
||||||
const _Str& _new = vm->PyStr_AS_C(args[2]);
|
const _Str& _new = vm->PyStr_AS_C(args[2]);
|
||||||
@ -423,21 +423,21 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "startswith", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "startswith", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(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]);
|
||||||
const _Str& _prefix = vm->PyStr_AS_C(args[1]);
|
const _Str& _prefix = vm->PyStr_AS_C(args[1]);
|
||||||
return vm->PyBool(_self.find(_prefix) == 0);
|
return vm->PyBool(_self.find(_prefix) == 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "endswith", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "endswith", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(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]);
|
||||||
const _Str& _suffix = vm->PyStr_AS_C(args[1]);
|
const _Str& _suffix = vm->PyStr_AS_C(args[1]);
|
||||||
return vm->PyBool(_self.rfind(_suffix) == _self.length() - _suffix.length());
|
return vm->PyBool(_self.rfind(_suffix) == _self.length() - _suffix.length());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("str", "join", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("str", "join", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(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]->isType(vm->_tp_list)){
|
||||||
@ -457,21 +457,21 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
/************ PyList ************/
|
/************ PyList ************/
|
||||||
_vm->bindMethod("list", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("list", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkType(args[0], vm->_tp_list);
|
vm->check_type(args[0], vm->_tp_list);
|
||||||
return vm->PyIter(
|
return vm->PyIter(
|
||||||
pkpy::make_shared<BaseIterator, VectorIterator>(vm, args[0])
|
pkpy::make_shared<BaseIterator, VectorIterator>(vm, args[0])
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("list", "append", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("list", "append", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2, true);
|
vm->check_args_size(args, 2, true);
|
||||||
PyVarList& _self = vm->PyList_AS_C(args[0]);
|
PyVarList& _self = vm->PyList_AS_C(args[0]);
|
||||||
_self.push_back(args[1]);
|
_self.push_back(args[1]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("list", "insert", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("list", "insert", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 3, true);
|
vm->check_args_size(args, 3, true);
|
||||||
PyVarList& _self = vm->PyList_AS_C(args[0]);
|
PyVarList& _self = vm->PyList_AS_C(args[0]);
|
||||||
int _index = (int)vm->PyInt_AS_C(args[1]);
|
int _index = (int)vm->PyInt_AS_C(args[1]);
|
||||||
if(_index < 0) _index += _self.size();
|
if(_index < 0) _index += _self.size();
|
||||||
@ -482,13 +482,13 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("list", "clear", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("list", "clear", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
vm->PyList_AS_C(args[0]).clear();
|
vm->PyList_AS_C(args[0]).clear();
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("list", "copy", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("list", "copy", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
return vm->PyList(vm->PyList_AS_C(args[0]));
|
return vm->PyList(vm->PyList_AS_C(args[0]));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -540,13 +540,13 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
/************ PyTuple ************/
|
/************ PyTuple ************/
|
||||||
_vm->bindMethod("tuple", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("tuple", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
PyVarList _list = vm->PyList_AS_C(vm->call(vm->builtins->attribs["list"], args));
|
PyVarList _list = vm->PyList_AS_C(vm->call(vm->builtins->attribs["list"], args));
|
||||||
return vm->PyTuple(_list);
|
return vm->PyTuple(_list);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("tuple", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("tuple", "__iter__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkType(args[0], vm->_tp_tuple);
|
vm->check_type(args[0], vm->_tp_tuple);
|
||||||
return vm->PyIter(
|
return vm->PyIter(
|
||||||
pkpy::make_shared<BaseIterator, VectorIterator>(vm, args[0])
|
pkpy::make_shared<BaseIterator, VectorIterator>(vm, args[0])
|
||||||
);
|
);
|
||||||
@ -566,7 +566,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
/************ PyBool ************/
|
/************ PyBool ************/
|
||||||
_vm->bindMethod("bool", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("bool", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->asBool(args[0]);
|
return vm->asBool(args[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -604,7 +604,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindMethod("_bounded_method", "__call__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("_bounded_method", "__call__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkType(args[0], vm->_tp_bounded_method);
|
vm->check_type(args[0], vm->_tp_bounded_method);
|
||||||
const _BoundedMethod& _self = vm->PyBoundedMethod_AS_C(args[0]);
|
const _BoundedMethod& _self = vm->PyBoundedMethod_AS_C(args[0]);
|
||||||
pkpy::ArgList newArgs(args.size());
|
pkpy::ArgList newArgs(args.size());
|
||||||
newArgs[0] = _self.obj;
|
newArgs[0] = _self.obj;
|
||||||
@ -635,11 +635,11 @@ void __addModuleTime(VM* vm){
|
|||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "sleep", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "sleep", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
if(!vm->isIntOrFloat(args[0])){
|
if(!vm->is_int_or_float(args[0])){
|
||||||
vm->typeError("time.sleep() argument must be int or float");
|
vm->typeError("time.sleep() argument must be int or float");
|
||||||
}
|
}
|
||||||
double sec = vm->numToFloat(args[0]);
|
double sec = vm->num_to_float(args[0]);
|
||||||
vm->sleepForSecs(sec);
|
vm->sleepForSecs(sec);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
@ -648,89 +648,89 @@ void __addModuleTime(VM* vm){
|
|||||||
void __addModuleSys(VM* vm){
|
void __addModuleSys(VM* vm){
|
||||||
PyVar mod = vm->newModule("sys");
|
PyVar mod = vm->newModule("sys");
|
||||||
vm->bindFunc(mod, "getrefcount", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "getrefcount", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyInt(args[0].use_count());
|
return vm->PyInt(args[0].use_count());
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "getrecursionlimit", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "getrecursionlimit", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 0);
|
vm->check_args_size(args, 0);
|
||||||
return vm->PyInt(vm->maxRecursionDepth);
|
return vm->PyInt(vm->maxRecursionDepth);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "setrecursionlimit", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "setrecursionlimit", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
vm->maxRecursionDepth = (int)vm->PyInt_AS_C(args[0]);
|
vm->maxRecursionDepth = (int)vm->PyInt_AS_C(args[0]);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->setAttr(mod, "version", vm->PyStr(PK_VERSION));
|
vm->setattr(mod, "version", vm->PyStr(PK_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
void __addModuleJson(VM* vm){
|
void __addModuleJson(VM* vm){
|
||||||
PyVar mod = vm->newModule("json");
|
PyVar mod = vm->newModule("json");
|
||||||
vm->bindFunc(mod, "loads", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "loads", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
||||||
_Code code = vm->compile(expr, "<json>", JSON_MODE);
|
_Code code = vm->compile(expr, "<json>", JSON_MODE);
|
||||||
return vm->_exec(code, vm->topFrame()->_module, vm->topFrame()->f_locals_copy());
|
return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->f_locals_copy());
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "dumps", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "dumps", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->asJson(args[0]);
|
return vm->asJson(args[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void __addModuleMath(VM* vm){
|
void __addModuleMath(VM* vm){
|
||||||
PyVar mod = vm->newModule("math");
|
PyVar mod = vm->newModule("math");
|
||||||
vm->setAttr(mod, "pi", vm->PyFloat(3.1415926535897932384));
|
vm->setattr(mod, "pi", vm->PyFloat(3.1415926535897932384));
|
||||||
vm->setAttr(mod, "e" , vm->PyFloat(2.7182818284590452354));
|
vm->setattr(mod, "e" , vm->PyFloat(2.7182818284590452354));
|
||||||
|
|
||||||
vm->bindFunc(mod, "log", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "log", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(log(vm->numToFloat(args[0])));
|
return vm->PyFloat(log(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "log10", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "log10", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(log10(vm->numToFloat(args[0])));
|
return vm->PyFloat(log10(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "log2", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "log2", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(log2(vm->numToFloat(args[0])));
|
return vm->PyFloat(log2(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "sin", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "sin", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(sin(vm->numToFloat(args[0])));
|
return vm->PyFloat(sin(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "cos", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "cos", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(cos(vm->numToFloat(args[0])));
|
return vm->PyFloat(cos(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "tan", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "tan", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyFloat(tan(vm->numToFloat(args[0])));
|
return vm->PyFloat(tan(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "isclose", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "isclose", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2);
|
vm->check_args_size(args, 2);
|
||||||
_Float a = vm->numToFloat(args[0]);
|
_Float a = vm->num_to_float(args[0]);
|
||||||
_Float b = vm->numToFloat(args[1]);
|
_Float b = vm->num_to_float(args[1]);
|
||||||
return vm->PyBool(fabs(a - b) < 1e-9);
|
return vm->PyBool(fabs(a - b) < 1e-9);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "isnan", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "isnan", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyBool(std::isnan(vm->numToFloat(args[0])));
|
return vm->PyBool(std::isnan(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "isinf", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "isinf", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
return vm->PyBool(std::isinf(vm->numToFloat(args[0])));
|
return vm->PyBool(std::isinf(vm->num_to_float(args[0])));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,18 +741,18 @@ 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->newObject(vm->_userTypes["re.Match"], (_Int)1);
|
PyVar ret = vm->new_object(vm->_userTypes["re.Match"], (_Int)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())
|
||||||
));
|
));
|
||||||
vm->setAttr(ret, "_end", vm->PyInt(
|
vm->setattr(ret, "_end", vm->PyInt(
|
||||||
string.__to_u8_index(m.position() + m.length())
|
string.__to_u8_index(m.position() + m.length())
|
||||||
));
|
));
|
||||||
PyVarList groups(m.size());
|
PyVarList groups(m.size());
|
||||||
for(size_t i = 0; i < m.size(); ++i){
|
for(size_t i = 0; i < m.size(); ++i){
|
||||||
groups[i] = vm->PyStr(m[i].str());
|
groups[i] = vm->PyStr(m[i].str());
|
||||||
}
|
}
|
||||||
vm->setAttr(ret, "_groups", vm->PyTuple(groups));
|
vm->setattr(ret, "_groups", vm->PyTuple(groups));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return vm->None;
|
return vm->None;
|
||||||
@ -760,51 +760,51 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
|
|||||||
|
|
||||||
void __addModuleRe(VM* vm){
|
void __addModuleRe(VM* vm){
|
||||||
PyVar mod = vm->newModule("re");
|
PyVar mod = vm->newModule("re");
|
||||||
PyVar _tp_match = vm->newUserClassType(mod, "Match", vm->_tp_object);
|
PyVar _tp_match = vm->new_user_type_object(mod, "Match", vm->_tp_object);
|
||||||
|
|
||||||
vm->bindMethod("re.Match", "start", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindMethod("re.Match", "start", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
PyVar self = args[0];
|
PyVar self = args[0];
|
||||||
return vm->getAttr(self, "_start");
|
return vm->getattr(self, "_start");
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindMethod("re.Match", "end", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindMethod("re.Match", "end", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
PyVar self = args[0];
|
PyVar self = args[0];
|
||||||
return vm->getAttr(self, "_end");
|
return vm->getattr(self, "_end");
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindMethod("re.Match", "span", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindMethod("re.Match", "span", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 1, true);
|
vm->check_args_size(args, 1, true);
|
||||||
PyVar self = args[0];
|
PyVar self = args[0];
|
||||||
PyVarList vec = { vm->getAttr(self, "_start"), vm->getAttr(self, "_end") };
|
PyVarList vec = { vm->getattr(self, "_start"), vm->getattr(self, "_end") };
|
||||||
return vm->PyTuple(vec);
|
return vm->PyTuple(vec);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2, true);
|
vm->check_args_size(args, 2, true);
|
||||||
int index = (int)vm->PyInt_AS_C(args[1]);
|
int index = (int)vm->PyInt_AS_C(args[1]);
|
||||||
const auto& vec = vm->PyTuple_AS_C(vm->getAttr(args[0], "_groups"));
|
const auto& vec = vm->PyTuple_AS_C(vm->getattr(args[0], "_groups"));
|
||||||
vm->normalizedIndex(index, vec.size());
|
vm->normalizedIndex(index, vec.size());
|
||||||
return vec[index];
|
return vec[index];
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "match", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "match", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2);
|
vm->check_args_size(args, 2);
|
||||||
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
||||||
const _Str& string = vm->PyStr_AS_C(args[1]);
|
const _Str& string = vm->PyStr_AS_C(args[1]);
|
||||||
return __regex_search(pattern, string, true, vm);
|
return __regex_search(pattern, string, true, vm);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "search", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "search", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2);
|
vm->check_args_size(args, 2);
|
||||||
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
||||||
const _Str& string = vm->PyStr_AS_C(args[1]);
|
const _Str& string = vm->PyStr_AS_C(args[1]);
|
||||||
return __regex_search(pattern, string, false, vm);
|
return __regex_search(pattern, string, false, vm);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "sub", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "sub", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 3);
|
vm->check_args_size(args, 3);
|
||||||
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
||||||
const _Str& repl = vm->PyStr_AS_C(args[1]);
|
const _Str& repl = vm->PyStr_AS_C(args[1]);
|
||||||
const _Str& string = vm->PyStr_AS_C(args[2]);
|
const _Str& string = vm->PyStr_AS_C(args[2]);
|
||||||
@ -813,7 +813,7 @@ void __addModuleRe(VM* vm){
|
|||||||
});
|
});
|
||||||
|
|
||||||
vm->bindFunc(mod, "split", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc(mod, "split", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 2);
|
vm->check_args_size(args, 2);
|
||||||
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
||||||
const _Str& string = vm->PyStr_AS_C(args[1]);
|
const _Str& string = vm->PyStr_AS_C(args[1]);
|
||||||
std::regex re(pattern);
|
std::regex re(pattern);
|
||||||
|
|||||||
182
src/vm.h
182
src/vm.h
@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
#define __DEF_PY_AS_C(type, ctype, ptype) \
|
#define __DEF_PY_AS_C(type, ctype, ptype) \
|
||||||
inline ctype& Py##type##_AS_C(const PyVar& obj) { \
|
inline ctype& Py##type##_AS_C(const PyVar& obj) { \
|
||||||
__checkType(obj, ptype); \
|
check_type(obj, ptype); \
|
||||||
return UNION_GET(ctype, obj); \
|
return UNION_GET(ctype, obj); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __DEF_PY(type, ctype, ptype) \
|
#define __DEF_PY(type, ctype, ptype) \
|
||||||
inline PyVar Py##type(ctype value) { \
|
inline PyVar Py##type(ctype value) { \
|
||||||
return newObject(ptype, value); \
|
return new_object(ptype, value); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEF_NATIVE(type, ctype, ptype) \
|
#define DEF_NATIVE(type, ctype, ptype) \
|
||||||
@ -50,7 +50,7 @@ protected:
|
|||||||
case OP_LOAD_CONST: frame->push(frame->code->co_consts[byte.arg]); break;
|
case OP_LOAD_CONST: frame->push(frame->code->co_consts[byte.arg]); break;
|
||||||
case OP_LOAD_LAMBDA: {
|
case OP_LOAD_LAMBDA: {
|
||||||
PyVar obj = frame->code->co_consts[byte.arg];
|
PyVar obj = frame->code->co_consts[byte.arg];
|
||||||
setAttr(obj, __module__, frame->_module);
|
setattr(obj, __module__, frame->_module);
|
||||||
frame->push(obj);
|
frame->push(obj);
|
||||||
} break;
|
} break;
|
||||||
case OP_LOAD_NAME_REF: {
|
case OP_LOAD_NAME_REF: {
|
||||||
@ -112,13 +112,13 @@ protected:
|
|||||||
pkpy::ArgList args(2);
|
pkpy::ArgList args(2);
|
||||||
args[1] = frame->pop_value(this); // obj
|
args[1] = frame->pop_value(this); // obj
|
||||||
args[0] = frame->top_value_offset(this, -2); // list
|
args[0] = frame->top_value_offset(this, -2); // list
|
||||||
fastCall(m_append, std::move(args));
|
fast_call(m_append, std::move(args));
|
||||||
} break;
|
} break;
|
||||||
case OP_STORE_FUNCTION:
|
case OP_STORE_FUNCTION:
|
||||||
{
|
{
|
||||||
PyVar obj = frame->pop_value(this);
|
PyVar obj = frame->pop_value(this);
|
||||||
const _Func& fn = PyFunction_AS_C(obj);
|
const _Func& fn = PyFunction_AS_C(obj);
|
||||||
setAttr(obj, __module__, frame->_module);
|
setattr(obj, __module__, frame->_module);
|
||||||
frame->f_globals()[fn->name] = obj;
|
frame->f_globals()[fn->name] = obj;
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_CLASS:
|
case OP_BUILD_CLASS:
|
||||||
@ -126,14 +126,14 @@ protected:
|
|||||||
const _Str& clsName = frame->code->co_names[byte.arg].first;
|
const _Str& clsName = frame->code->co_names[byte.arg].first;
|
||||||
PyVar clsBase = frame->pop_value(this);
|
PyVar clsBase = frame->pop_value(this);
|
||||||
if(clsBase == None) clsBase = _tp_object;
|
if(clsBase == None) clsBase = _tp_object;
|
||||||
__checkType(clsBase, _tp_type);
|
check_type(clsBase, _tp_type);
|
||||||
PyVar cls = newUserClassType(frame->_module, clsName, clsBase);
|
PyVar cls = new_user_type_object(frame->_module, clsName, clsBase);
|
||||||
while(true){
|
while(true){
|
||||||
PyVar fn = frame->pop_value(this);
|
PyVar fn = frame->pop_value(this);
|
||||||
if(fn == None) break;
|
if(fn == None) break;
|
||||||
const _Func& f = PyFunction_AS_C(fn);
|
const _Func& f = PyFunction_AS_C(fn);
|
||||||
setAttr(fn, __module__, frame->_module);
|
setattr(fn, __module__, frame->_module);
|
||||||
setAttr(cls, f->name, fn);
|
setattr(cls, f->name, fn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case OP_RETURN_VALUE: return frame->pop_value(this);
|
case OP_RETURN_VALUE: return frame->pop_value(this);
|
||||||
@ -146,19 +146,15 @@ protected:
|
|||||||
case OP_POP_TOP: frame->pop_value(this); break;
|
case OP_POP_TOP: frame->pop_value(this); break;
|
||||||
case OP_BINARY_OP:
|
case OP_BINARY_OP:
|
||||||
{
|
{
|
||||||
frame->push(
|
pkpy::ArgList args(2);
|
||||||
fastCall(BINARY_SPECIAL_METHODS[byte.arg],
|
args._index(1) = frame->pop_value(this);
|
||||||
frame->pop_n_values_reversed(this, 2))
|
args._index(0) = frame->top_value(this);
|
||||||
);
|
frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
|
||||||
// pkpy::ArgList args(2);
|
|
||||||
// args._index(1) = frame->pop_value(this);
|
|
||||||
// args._index(0) = frame->top_value(this);
|
|
||||||
// frame->top() = fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
|
|
||||||
} break;
|
} break;
|
||||||
case OP_BITWISE_OP:
|
case OP_BITWISE_OP:
|
||||||
{
|
{
|
||||||
frame->push(
|
frame->push(
|
||||||
fastCall(BITWISE_SPECIAL_METHODS[byte.arg],
|
fast_call(BITWISE_SPECIAL_METHODS[byte.arg],
|
||||||
frame->pop_n_values_reversed(this, 2))
|
frame->pop_n_values_reversed(this, 2))
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
@ -166,7 +162,7 @@ protected:
|
|||||||
{
|
{
|
||||||
// for __ne__ we use the negation of __eq__
|
// for __ne__ we use the negation of __eq__
|
||||||
int op = byte.arg == 3 ? 2 : byte.arg;
|
int op = byte.arg == 3 ? 2 : byte.arg;
|
||||||
PyVar res = fastCall(CMP_SPECIAL_METHODS[op], frame->pop_n_values_reversed(this, 2));
|
PyVar res = fast_call(CMP_SPECIAL_METHODS[op], frame->pop_n_values_reversed(this, 2));
|
||||||
if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
|
if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
|
||||||
frame->push(std::move(res));
|
frame->push(std::move(res));
|
||||||
} break;
|
} break;
|
||||||
@ -186,7 +182,7 @@ protected:
|
|||||||
case OP_UNARY_NEGATIVE:
|
case OP_UNARY_NEGATIVE:
|
||||||
{
|
{
|
||||||
PyVar obj = frame->pop_value(this);
|
PyVar obj = frame->pop_value(this);
|
||||||
frame->push(numNegated(obj));
|
frame->push(num_negated(obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_UNARY_NOT:
|
case OP_UNARY_NOT:
|
||||||
{
|
{
|
||||||
@ -204,7 +200,7 @@ protected:
|
|||||||
case OP_ASSERT:
|
case OP_ASSERT:
|
||||||
{
|
{
|
||||||
PyVar expr = frame->pop_value(this);
|
PyVar expr = frame->pop_value(this);
|
||||||
_assert(PyBool_AS_C(expr), "assertion failed");
|
if(asBool(expr) != True) _error("AssertionError", "");
|
||||||
} break;
|
} break;
|
||||||
case OP_RAISE_ERROR:
|
case OP_RAISE_ERROR:
|
||||||
{
|
{
|
||||||
@ -262,11 +258,11 @@ protected:
|
|||||||
case OP_GET_ITER:
|
case OP_GET_ITER:
|
||||||
{
|
{
|
||||||
PyVar obj = frame->pop_value(this);
|
PyVar obj = frame->pop_value(this);
|
||||||
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
PyVarOrNull iter_fn = getattr(obj, __iter__, false);
|
||||||
if(iter_fn != nullptr){
|
if(iter_fn != nullptr){
|
||||||
PyVar tmp = call(iter_fn);
|
PyVar tmp = call(iter_fn);
|
||||||
PyVarRef var = frame->pop();
|
PyVarRef var = frame->pop();
|
||||||
__checkType(var, _tp_ref);
|
check_type(var, _tp_ref);
|
||||||
PyIter_AS_C(tmp)->var = var;
|
PyIter_AS_C(tmp)->var = var;
|
||||||
frame->push(std::move(tmp));
|
frame->push(std::move(tmp));
|
||||||
}else{
|
}else{
|
||||||
@ -311,8 +307,8 @@ protected:
|
|||||||
PyVar stop = frame->pop_value(this);
|
PyVar stop = frame->pop_value(this);
|
||||||
PyVar start = frame->pop_value(this);
|
PyVar start = frame->pop_value(this);
|
||||||
_Slice s;
|
_Slice s;
|
||||||
if(start != None) {__checkType(start, _tp_int); s.start = (int)PyInt_AS_C(start);}
|
if(start != None) {check_type(start, _tp_int); s.start = (int)PyInt_AS_C(start);}
|
||||||
if(stop != None) {__checkType(stop, _tp_int); s.stop = (int)PyInt_AS_C(stop);}
|
if(stop != None) {check_type(stop, _tp_int); s.stop = (int)PyInt_AS_C(stop);}
|
||||||
frame->push(PySlice(s));
|
frame->push(PySlice(s));
|
||||||
} break;
|
} break;
|
||||||
case OP_IMPORT_NAME:
|
case OP_IMPORT_NAME:
|
||||||
@ -381,7 +377,7 @@ public:
|
|||||||
initializeBuiltinClasses();
|
initializeBuiltinClasses();
|
||||||
|
|
||||||
_small_integers.reserve(300);
|
_small_integers.reserve(300);
|
||||||
for(_Int i=-5; i<=256; i++) _small_integers.push_back(newObject(_tp_int, i));
|
for(_Int i=-5; i<=256; i++) _small_integers.push_back(new_object(_tp_int, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboardInterrupt(){
|
void keyboardInterrupt(){
|
||||||
@ -401,12 +397,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyVar asStr(const PyVar& obj){
|
PyVar asStr(const PyVar& obj){
|
||||||
PyVarOrNull str_fn = getAttr(obj, __str__, false);
|
PyVarOrNull str_fn = getattr(obj, __str__, false);
|
||||||
if(str_fn != nullptr) return call(str_fn);
|
if(str_fn != nullptr) return call(str_fn);
|
||||||
return asRepr(obj);
|
return asRepr(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Frame* topFrame() const {
|
inline Frame* top_frame() const {
|
||||||
if(callstack.size() == 0) UNREACHABLE();
|
if(callstack.size() == 0) UNREACHABLE();
|
||||||
return callstack.back().get();
|
return callstack.back().get();
|
||||||
}
|
}
|
||||||
@ -425,7 +421,7 @@ public:
|
|||||||
if(obj->_type == _tp_bool) return obj;
|
if(obj->_type == _tp_bool) return obj;
|
||||||
if(obj->_type == _tp_int) return PyBool(PyInt_AS_C(obj) != 0);
|
if(obj->_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->_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);
|
||||||
return PyBool(PyInt_AS_C(ret) > 0);
|
return PyBool(PyInt_AS_C(ret) > 0);
|
||||||
@ -433,7 +429,7 @@ public:
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar fastCall(const _Str& name, pkpy::ArgList&& args){
|
PyVar fast_call(const _Str& name, pkpy::ArgList&& args){
|
||||||
PyObject* cls = args[0]->_type.get();
|
PyObject* cls = args[0]->_type.get();
|
||||||
while(cls != None.get()) {
|
while(cls != None.get()) {
|
||||||
PyVar* val = cls->attribs.try_get(name);
|
PyVar* val = cls->attribs.try_get(name);
|
||||||
@ -457,11 +453,11 @@ public:
|
|||||||
template<typename ArgT>
|
template<typename ArgT>
|
||||||
inline std::enable_if_t<std::is_same_v<std::remove_const_t<std::remove_reference_t<ArgT>>, pkpy::ArgList>, PyVar>
|
inline std::enable_if_t<std::is_same_v<std::remove_const_t<std::remove_reference_t<ArgT>>, pkpy::ArgList>, PyVar>
|
||||||
call(const PyVar& obj, const _Str& func, ArgT&& args){
|
call(const PyVar& obj, const _Str& func, ArgT&& args){
|
||||||
return call(getAttr(obj, func), std::forward<ArgT>(args), pkpy::noArg(), false);
|
return call(getattr(obj, func), std::forward<ArgT>(args), pkpy::noArg(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PyVar call(const PyVar& obj, const _Str& func){
|
inline PyVar call(const PyVar& obj, const _Str& func){
|
||||||
return call(getAttr(obj, func), pkpy::noArg(), pkpy::noArg(), false);
|
return call(getattr(obj, func), pkpy::noArg(), pkpy::noArg(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
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){
|
||||||
@ -471,8 +467,8 @@ public:
|
|||||||
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 = newObject(_callable, (_Int)-1);
|
obj = new_object(_callable, (_Int)-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);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@ -541,7 +537,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyVar* it_m = (*callable)->attribs.try_get(__module__);
|
PyVar* it_m = (*callable)->attribs.try_get(__module__);
|
||||||
PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module;
|
PyVar _module = it_m != nullptr ? *it_m : top_frame()->_module;
|
||||||
if(opCall){
|
if(opCall){
|
||||||
__pushNewFrame(fn->code, _module, std::move(locals));
|
__pushNewFrame(fn->code, _module, std::move(locals));
|
||||||
return __py2py_call_signal;
|
return __py2py_call_signal;
|
||||||
@ -608,33 +604,33 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar newUserClassType(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_<_Int>>((_Int)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));
|
||||||
_userTypes[fullName] = obj;
|
_userTypes[fullName] = obj;
|
||||||
setAttr(mod, name, obj);
|
setattr(mod, name, obj);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar newClassType(_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_<_Int>>((_Int)0, _tp_type);
|
||||||
setAttr(obj, __base__, base);
|
setattr(obj, __base__, base);
|
||||||
_types[name] = obj;
|
_types[name] = obj;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline PyVar newObject(PyVar type, T _value) {
|
inline PyVar new_object(PyVar type, T _value) {
|
||||||
if(!type->isType(_tp_type)) UNREACHABLE();
|
if(!type->isType(_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 = newObject(_tp_module, (_Int)-2);
|
PyVar obj = new_object(_tp_module, (_Int)-2);
|
||||||
setAttr(obj, __name__, PyStr(name));
|
setattr(obj, __name__, PyStr(name));
|
||||||
_modules[name] = obj;
|
_modules[name] = obj;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -643,7 +639,7 @@ public:
|
|||||||
_lazy_modules[name] = source;
|
_lazy_modules[name] = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVarOrNull getAttr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
PyVarOrNull getattr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
||||||
PyVarDict::iterator it;
|
PyVarDict::iterator it;
|
||||||
PyObject* cls;
|
PyObject* cls;
|
||||||
|
|
||||||
@ -683,14 +679,14 @@ 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->isType(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get();
|
||||||
obj->attribs[name] = value;
|
obj->attribs[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void setAttr(PyVar& obj, const _Str& name, T&& value) {
|
inline void setattr(PyVar& obj, const _Str& name, T&& value) {
|
||||||
setAttr(obj.get(), name, value);
|
setattr(obj.get(), name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) {
|
void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) {
|
||||||
@ -698,7 +694,7 @@ public:
|
|||||||
if(type == nullptr) type = _userTypes.try_get(typeName);
|
if(type == nullptr) type = _userTypes.try_get(typeName);
|
||||||
if(type == nullptr) UNREACHABLE();
|
if(type == nullptr) UNREACHABLE();
|
||||||
PyVar func = PyNativeFunction(fn);
|
PyVar func = PyNativeFunction(fn);
|
||||||
setAttr(*type, funcName, func);
|
setattr(*type, funcName, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindMethodMulti(std::vector<_Str> typeNames, _Str funcName, _CppFunc fn) {
|
void bindMethodMulti(std::vector<_Str> typeNames, _Str funcName, _CppFunc fn) {
|
||||||
@ -712,13 +708,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bindFunc(PyVar module, _Str funcName, _CppFunc fn) {
|
void bindFunc(PyVar module, _Str funcName, _CppFunc fn) {
|
||||||
__checkType(module, _tp_module);
|
check_type(module, _tp_module);
|
||||||
PyVar func = PyNativeFunction(fn);
|
PyVar func = PyNativeFunction(fn);
|
||||||
setAttr(module, funcName, func);
|
setattr(module, funcName, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInstance(PyVar obj, PyVar type){
|
bool isinstance(PyVar obj, PyVar type){
|
||||||
__checkType(type, _tp_type);
|
check_type(type, _tp_type);
|
||||||
PyObject* t = obj->_type.get();
|
PyObject* t = obj->_type.get();
|
||||||
while (t != None.get()){
|
while (t != None.get()){
|
||||||
if (t == type.get()) return true;
|
if (t == type.get()) return true;
|
||||||
@ -727,15 +723,15 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isIntOrFloat(const PyVar& obj){
|
inline bool is_int_or_float(const PyVar& obj) const{
|
||||||
return obj->isType(_tp_int) || obj->isType(_tp_float);
|
return obj->isType(_tp_int) || obj->isType(_tp_float);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isIntOrFloat(const PyVar& obj1, const PyVar& obj2){
|
inline bool is_int_or_float(const PyVar& obj1, const PyVar& obj2) const{
|
||||||
return isIntOrFloat(obj1) && isIntOrFloat(obj2);
|
return is_int_or_float(obj1) && is_int_or_float(obj2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _Float numToFloat(const PyVar& obj){
|
inline _Float num_to_float(const PyVar& obj){
|
||||||
if (obj->isType(_tp_int)){
|
if (obj->isType(_tp_int)){
|
||||||
return (_Float)PyInt_AS_C(obj);
|
return (_Float)PyInt_AS_C(obj);
|
||||||
}else if(obj->isType(_tp_float)){
|
}else if(obj->isType(_tp_float)){
|
||||||
@ -744,7 +740,7 @@ public:
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar numNegated(const PyVar& obj){
|
PyVar num_negated(const PyVar& obj){
|
||||||
if (obj->isType(_tp_int)){
|
if (obj->isType(_tp_int)){
|
||||||
return PyInt(-PyInt_AS_C(obj));
|
return PyInt(-PyInt_AS_C(obj));
|
||||||
}else if(obj->isType(_tp_float)){
|
}else if(obj->isType(_tp_float)){
|
||||||
@ -835,7 +831,7 @@ public:
|
|||||||
template<typename P>
|
template<typename P>
|
||||||
inline PyVarRef PyRef(P&& value) {
|
inline PyVarRef PyRef(P&& value) {
|
||||||
static_assert(std::is_base_of<BaseRef, P>::value, "P should derive from BaseRef");
|
static_assert(std::is_base_of<BaseRef, P>::value, "P should derive from BaseRef");
|
||||||
return newObject(_tp_ref, std::forward<P>(value));
|
return new_object(_tp_ref, std::forward<P>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const BaseRef* PyRef_AS_C(const PyVar& obj)
|
inline const BaseRef* PyRef_AS_C(const PyVar& obj)
|
||||||
@ -847,7 +843,7 @@ public:
|
|||||||
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
||||||
inline PyVar PyInt(_Int value) {
|
inline PyVar PyInt(_Int value) {
|
||||||
if(value >= -5 && value <= 256) return _small_integers[value + 5];
|
if(value >= -5 && value <= 256) return _small_integers[value + 5];
|
||||||
return newObject(_tp_int, value);
|
return new_object(_tp_int, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_NATIVE(Float, _Float, _tp_float)
|
DEF_NATIVE(Float, _Float, _tp_float)
|
||||||
@ -872,47 +868,47 @@ public:
|
|||||||
_types["object"] = _tp_object;
|
_types["object"] = _tp_object;
|
||||||
_types["type"] = _tp_type;
|
_types["type"] = _tp_type;
|
||||||
|
|
||||||
_tp_bool = newClassType("bool");
|
_tp_bool = new_type_object("bool");
|
||||||
_tp_int = newClassType("int");
|
_tp_int = new_type_object("int");
|
||||||
_tp_float = newClassType("float");
|
_tp_float = new_type_object("float");
|
||||||
_tp_str = newClassType("str");
|
_tp_str = new_type_object("str");
|
||||||
_tp_list = newClassType("list");
|
_tp_list = new_type_object("list");
|
||||||
_tp_tuple = newClassType("tuple");
|
_tp_tuple = new_type_object("tuple");
|
||||||
_tp_slice = newClassType("slice");
|
_tp_slice = new_type_object("slice");
|
||||||
_tp_range = newClassType("range");
|
_tp_range = new_type_object("range");
|
||||||
_tp_module = newClassType("module");
|
_tp_module = new_type_object("module");
|
||||||
_tp_ref = newClassType("_ref");
|
_tp_ref = new_type_object("_ref");
|
||||||
|
|
||||||
newClassType("NoneType");
|
new_type_object("NoneType");
|
||||||
newClassType("ellipsis");
|
new_type_object("ellipsis");
|
||||||
|
|
||||||
_tp_function = newClassType("function");
|
_tp_function = new_type_object("function");
|
||||||
_tp_native_function = newClassType("_native_function");
|
_tp_native_function = new_type_object("_native_function");
|
||||||
_tp_native_iterator = newClassType("_native_iterator");
|
_tp_native_iterator = new_type_object("_native_iterator");
|
||||||
_tp_bounded_method = newClassType("_bounded_method");
|
_tp_bounded_method = new_type_object("_bounded_method");
|
||||||
_tp_super = newClassType("super");
|
_tp_super = new_type_object("super");
|
||||||
|
|
||||||
this->None = newObject(_types["NoneType"], (_Int)0);
|
this->None = new_object(_types["NoneType"], (_Int)0);
|
||||||
this->Ellipsis = newObject(_types["ellipsis"], (_Int)0);
|
this->Ellipsis = new_object(_types["ellipsis"], (_Int)0);
|
||||||
this->True = newObject(_tp_bool, true);
|
this->True = new_object(_tp_bool, true);
|
||||||
this->False = newObject(_tp_bool, false);
|
this->False = new_object(_tp_bool, false);
|
||||||
this->builtins = newModule("builtins");
|
this->builtins = newModule("builtins");
|
||||||
this->_main = newModule("__main__");
|
this->_main = newModule("__main__");
|
||||||
|
|
||||||
setAttr(_tp_type, __base__, _tp_object);
|
setattr(_tp_type, __base__, _tp_object);
|
||||||
_tp_type->_type = _tp_type;
|
_tp_type->_type = _tp_type;
|
||||||
setAttr(_tp_object, __base__, None);
|
setattr(_tp_object, __base__, None);
|
||||||
_tp_object->_type = _tp_type;
|
_tp_object->_type = _tp_type;
|
||||||
|
|
||||||
for (auto& [name, type] : _types) {
|
for (auto& [name, type] : _types) {
|
||||||
setAttr(type, __name__, PyStr(name));
|
setattr(type, __name__, PyStr(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->__py2py_call_signal = newObject(_tp_object, (_Int)7);
|
this->__py2py_call_signal = new_object(_tp_object, (_Int)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) {
|
||||||
setAttr(builtins, name, _types[name]);
|
setattr(builtins, name, _types[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,22 +981,18 @@ public:
|
|||||||
_error("AttributeError", "type '" + UNION_TP_NAME(obj) + "' has no attribute '" + name + "'");
|
_error("AttributeError", "type '" + UNION_TP_NAME(obj) + "' has no attribute '" + name + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void __checkType(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->isType(type)) typeError("expected '" + UNION_NAME(type) + "', but got '" + UNION_TP_NAME(obj) + "'");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void __checkArgSize(const pkpy::ArgList& args, int size, bool method=false){
|
inline void check_args_size(const pkpy::ArgList& args, int size, bool method=false){
|
||||||
if(args.size() == size) return;
|
if(args.size() == size) return;
|
||||||
if(method) typeError(args.size()>size ? "too many arguments" : "too few arguments");
|
if(method) typeError(args.size()>size ? "too many arguments" : "too few arguments");
|
||||||
else typeError("expected " + std::to_string(size) + " arguments, but got " + std::to_string(args.size()));
|
else typeError("expected " + std::to_string(size) + " arguments, but got " + std::to_string(args.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _assert(bool val, const _Str& msg){
|
|
||||||
if (!val) _error("AssertionError", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~VM() {
|
virtual ~VM() {
|
||||||
if(!use_stdio){
|
if(!use_stdio){
|
||||||
delete _stdout;
|
delete _stdout;
|
||||||
@ -1065,11 +1057,11 @@ void NameRef::del(VM* vm, Frame* frame) const{
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyVar AttrRef::get(VM* vm, Frame* frame) const{
|
PyVar AttrRef::get(VM* vm, Frame* frame) const{
|
||||||
return vm->getAttr(obj, attr.pair->first);
|
return vm->getattr(obj, attr.pair->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttrRef::set(VM* vm, Frame* frame, PyVar val) const{
|
void AttrRef::set(VM* vm, Frame* frame, PyVar val) const{
|
||||||
vm->setAttr(obj, attr.pair->first, val);
|
vm->setattr(obj, attr.pair->first, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttrRef::del(VM* vm, Frame* frame) const{
|
void AttrRef::del(VM* vm, Frame* frame) const{
|
||||||
@ -1158,7 +1150,7 @@ class ThreadedVM : public VM {
|
|||||||
public:
|
public:
|
||||||
ThreadedVM(bool use_stdio) : VM(use_stdio) {
|
ThreadedVM(bool use_stdio) : VM(use_stdio) {
|
||||||
bindBuiltinFunc("__string_channel_call", [](VM* vm, const pkpy::ArgList& args){
|
bindBuiltinFunc("__string_channel_call", [](VM* vm, const pkpy::ArgList& args){
|
||||||
vm->__checkArgSize(args, 1);
|
vm->check_args_size(args, 1);
|
||||||
_Str data = vm->PyStr_AS_C(args[0]);
|
_Str data = vm->PyStr_AS_C(args[0]);
|
||||||
|
|
||||||
ThreadedVM* tvm = (ThreadedVM*)vm;
|
ThreadedVM* tvm = (ThreadedVM*)vm;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user