blueloveTH 2024-01-26 12:07:33 +08:00
parent fab6d615a1
commit 5ffb446d4a
15 changed files with 44 additions and 44 deletions

View File

@ -36,7 +36,7 @@ static cJSON* convert_python_object_to_cjson(PyObject* obj, VM* vm){
case VM::tp_tuple.index: return convert_list_to_cjson<Tuple>(_CAST(Tuple&, obj), vm); case VM::tp_tuple.index: return convert_list_to_cjson<Tuple>(_CAST(Tuple&, obj), vm);
default: break; default: break;
} }
vm->TypeError(fmt("unrecognized type ", _type_name(vm, obj_t).escape())); vm->TypeError(_S("unrecognized type ", _type_name(vm, obj_t).escape()));
PK_UNREACHABLE() PK_UNREACHABLE()
} }
@ -110,7 +110,7 @@ void add_module_cjson(VM* vm){
const char* start = cJSON_GetErrorPtr(); const char* start = cJSON_GetErrorPtr();
const char* end = start; const char* end = start;
while(*end != '\0' && *end != '\n') end++; while(*end != '\0' && *end != '\n') end++;
vm->IOError(fmt("cjson: ", std::string_view(start, end-start))); vm->IOError(_S("cjson: ", std::string_view(start, end-start)));
} }
PyObject* output = convert_cjson_to_python_object(json, vm); PyObject* output = convert_cjson_to_python_object(json, vm);
cJSON_Delete(json); cJSON_Delete(json);

View File

@ -285,7 +285,7 @@ void lua_push_from_python(VM* vm, PyObject* val){
lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r); lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r);
return; return;
} }
vm->RuntimeError(fmt("unsupported python type: ", _type_name(vm, t).escape())); vm->RuntimeError(_S("unsupported python type: ", _type_name(vm, t).escape()));
} }
PyObject* lua_popx_to_python(VM* vm) { PyObject* lua_popx_to_python(VM* vm) {
@ -321,7 +321,7 @@ PyObject* lua_popx_to_python(VM* vm) {
default: { default: {
const char* type_name = lua_typename(_L, type); const char* type_name = lua_typename(_L, type);
lua_pop(_L, 1); lua_pop(_L, 1);
vm->RuntimeError(fmt("unsupported lua type: '", type_name, "'")); vm->RuntimeError(_S("unsupported lua type: '", type_name, "'"));
} }
} }
PK_UNREACHABLE() PK_UNREACHABLE()

View File

@ -19,7 +19,7 @@ namespace pkpy {
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \
if(mod_name != #mod) { \ if(mod_name != #mod) { \
Str msg = fmt("register_class() failed: ", mod_name, " != ", #mod); \ Str msg = _S("register_class() failed: ", mod_name, " != ", #mod); \
throw std::runtime_error(msg.str()); \ throw std::runtime_error(msg.str()); \
} \ } \
PyObject* type = vm->new_type_object(mod, #name, base); \ PyObject* type = vm->new_type_object(mod, #name, base); \

View File

@ -291,7 +291,7 @@ struct NameDictImpl{
V operator[](StrName key) const { V operator[](StrName key) const {
V val = try_get_likely_found(key); V val = try_get_likely_found(key);
if(val == default_invalid_value<V>()){ if(val == default_invalid_value<V>()){
throw std::runtime_error(fmt("NameDict key not found: ", key.escape()).str()); throw std::runtime_error(_S("NameDict key not found: ", key.escape()).str());
} }
return val; return val;
} }

View File

@ -154,7 +154,7 @@ struct SStream{
}; };
template<typename... Args> template<typename... Args>
Str fmt(Args&&... args) { Str _S(Args&&... args) {
SStream ss; SStream ss;
(ss << ... << args); (ss << ... << args);
return ss.str(); return ss.str();

View File

@ -340,22 +340,22 @@ public:
void RuntimeError(const Str& msg){ _builtin_error("RuntimeError", msg); } void RuntimeError(const Str& msg){ _builtin_error("RuntimeError", msg); }
void ZeroDivisionError(const Str& msg){ _builtin_error("ZeroDivisionError", msg); } void ZeroDivisionError(const Str& msg){ _builtin_error("ZeroDivisionError", msg); }
void ZeroDivisionError(){ _builtin_error("ZeroDivisionError", "division by zero"); } void ZeroDivisionError(){ _builtin_error("ZeroDivisionError", "division by zero"); }
void NameError(StrName name){ _builtin_error("NameError", fmt("name ", name.escape() + " is not defined")); } void NameError(StrName name){ _builtin_error("NameError", _S("name ", name.escape() + " is not defined")); }
void UnboundLocalError(StrName name){ _builtin_error("UnboundLocalError", fmt("local variable ", name.escape() + " referenced before assignment")); } void UnboundLocalError(StrName name){ _builtin_error("UnboundLocalError", _S("local variable ", name.escape() + " referenced before assignment")); }
void KeyError(PyObject* obj){ _builtin_error("KeyError", obj); } void KeyError(PyObject* obj){ _builtin_error("KeyError", obj); }
void ImportError(const Str& msg){ _builtin_error("ImportError", msg); } void ImportError(const Str& msg){ _builtin_error("ImportError", msg); }
void BinaryOptError(const char* op, PyObject* _0, PyObject* _1) { void BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
StrName name_0 = _type_name(vm, _tp(_0)); StrName name_0 = _type_name(vm, _tp(_0));
StrName name_1 = _type_name(vm, _tp(_1)); StrName name_1 = _type_name(vm, _tp(_1));
TypeError(fmt("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape())); TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
} }
void AttributeError(PyObject* obj, StrName name){ void AttributeError(PyObject* obj, StrName name){
if(isinstance(obj, vm->tp_type)){ if(isinstance(obj, vm->tp_type)){
_builtin_error("AttributeError", fmt("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape())); _builtin_error("AttributeError", _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
}else{ }else{
_builtin_error("AttributeError", fmt(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape())); _builtin_error("AttributeError", _S(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape()));
} }
} }
void AttributeError(const Str& msg){ _builtin_error("AttributeError", msg); } void AttributeError(const Str& msg){ _builtin_error("AttributeError", msg); }

View File

@ -546,7 +546,7 @@ __NEXT_STEP:;
TARGET(GOTO) { TARGET(GOTO) {
StrName _name(byte.arg); StrName _name(byte.arg);
int index = co->labels.try_get_likely_found(_name); int index = co->labels.try_get_likely_found(_name);
if(index < 0) RuntimeError(fmt("label ", _name.escape(), " not found")); if(index < 0) RuntimeError(_S("label ", _name.escape(), " not found"));
frame->jump_abs_break(index); frame->jump_abs_break(index);
} DISPATCH(); } DISPATCH();
/*****************************************/ /*****************************************/
@ -680,7 +680,7 @@ __NEXT_STEP:;
_name = StrName::get(CAST(Str&, key).sv()); _name = StrName::get(CAST(Str&, key).sv());
PyObject* value = _0->attr().try_get_likely_found(_name); PyObject* value = _0->attr().try_get_likely_found(_name);
if(value == nullptr){ if(value == nullptr){
ImportError(fmt("cannot import name ", _name.escape())); ImportError(_S("cannot import name ", _name.escape()));
}else{ }else{
frame->f_globals().set(_name, value); frame->f_globals().set(_name, value);
} }

View File

@ -16,7 +16,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
VoidP& self = PK_OBJ_GET(VoidP, obj); VoidP& self = PK_OBJ_GET(VoidP, obj);
return VAR(fmt("<void* at ", self.hex(), ">")); return VAR(_S("<void* at ", self.hex(), ">"));
}); });
#define BIND_CMP(name, op) \ #define BIND_CMP(name, op) \
@ -61,12 +61,12 @@ namespace pkpy{
if(s[i]>='0' && s[i]<='9') c += s[i]-'0'; if(s[i]>='0' && s[i]<='9') c += s[i]-'0';
else if(s[i]>='A' && s[i]<='F') c += s[i]-'A'+10; else if(s[i]>='A' && s[i]<='F') c += s[i]-'A'+10;
else if(s[i]>='a' && s[i]<='f') c += s[i]-'a'+10; else if(s[i]>='a' && s[i]<='f') c += s[i]-'a'+10;
else vm->ValueError(fmt("invalid hex char: '", s[i], "'")); else vm->ValueError(_S("invalid hex char: '", s[i], "'"));
c <<= 4; c <<= 4;
if(s[i+1]>='0' && s[i+1]<='9') c += s[i+1]-'0'; if(s[i+1]>='0' && s[i+1]<='9') c += s[i+1]-'0';
else if(s[i+1]>='A' && s[i+1]<='F') c += s[i+1]-'A'+10; else if(s[i+1]>='A' && s[i+1]<='F') c += s[i+1]-'A'+10;
else if(s[i+1]>='a' && s[i+1]<='f') c += s[i+1]-'a'+10; else if(s[i+1]>='a' && s[i+1]<='f') c += s[i+1]-'a'+10;
else vm->ValueError(fmt("invalid hex char: '", s[i+1], "'")); else vm->ValueError(_S("invalid hex char: '", s[i+1], "'"));
buffer.p[i/2] = c; buffer.p[i/2] = c;
} }
return VAR_T(C99Struct, std::move(buffer)); return VAR_T(C99Struct, std::move(buffer));
@ -235,7 +235,7 @@ void add_module_c(VM* vm){
}); \ }); \
vm->bind__repr__(type_t, [](VM* vm, PyObject* obj){ \ vm->bind__repr__(type_t, [](VM* vm, PyObject* obj){ \
VoidP& self = _CAST(VoidP&, obj); \ VoidP& self = _CAST(VoidP&, obj); \
return VAR(fmt("<", CNAME, "* at ", self.hex(), ">")); \ return VAR(_S("<", CNAME, "* at ", self.hex(), ">")); \
}); \ }); \
BIND_PRIMITIVE(char, "char") BIND_PRIMITIVE(char, "char")

View File

@ -133,7 +133,7 @@ namespace pkpy{
void Compiler::consume(TokenIndex expected) { void Compiler::consume(TokenIndex expected) {
if (!match(expected)){ if (!match(expected)){
SyntaxError( SyntaxError(
fmt("expected '", TK_STR(expected), "', got '", TK_STR(curr().type), "'") _S("expected '", TK_STR(expected), "', got '", TK_STR(curr().type), "'")
); );
} }
} }

View File

@ -34,7 +34,7 @@ namespace pkpy{
PyObject* obj = _s->popx(); // pop exception object PyObject* obj = _s->popx(); // pop exception object
// get the stack size of the try block // get the stack size of the try block
int _stack_size = co->blocks[block].base_stack_size; int _stack_size = co->blocks[block].base_stack_size;
if(stack_size() < _stack_size) throw std::runtime_error(fmt("invalid state: ", stack_size(), '<', _stack_size).str()); if(stack_size() < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(), '<', _stack_size).str());
_s->reset(actual_sp_base() + _locals.size() + _stack_size); // rollback the stack _s->reset(actual_sp_base() + _locals.size() + _stack_size); // rollback the stack
_s->push(obj); // push exception object _s->push(obj); // push exception object
_next_ip = co->blocks[block].end; _next_ip = co->blocks[block].end;

View File

@ -249,7 +249,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float
for(int i=0; i<9; i++) mat.v[i] = CAST_F(args[1+i]); for(int i=0; i<9; i++) mat.v[i] = CAST_F(args[1+i]);
return vm->heap.gcnew<PyMat3x3>(PK_OBJ_GET(Type, args[0]), mat); return vm->heap.gcnew<PyMat3x3>(PK_OBJ_GET(Type, args[0]), mat);
} }
vm->TypeError(fmt("Mat3x3.__new__ takes 0 or 1 or 9 arguments, got ", args.size()-1)); vm->TypeError(_S("Mat3x3.__new__ takes 0 or 1 or 9 arguments, got ", args.size()-1));
return vm->None; return vm->None;
}); });

View File

@ -1273,7 +1273,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(VM::tp_module, [](VM* vm, PyObject* _0) { _vm->bind__repr__(VM::tp_module, [](VM* vm, PyObject* _0) {
const Str& path = CAST(Str&, _0->attr(__path__)); const Str& path = CAST(Str&, _0->attr(__path__));
return VAR(fmt("<module ", path.escape(), ">")); return VAR(_S("<module ", path.escape(), ">"));
}); });
// tp_property // tp_property
@ -1339,7 +1339,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(VM::tp_exception, [](VM* vm, PyObject* _0) { _vm->bind__repr__(VM::tp_exception, [](VM* vm, PyObject* _0) {
Exception& self = _CAST(Exception&, _0); Exception& self = _CAST(Exception&, _0);
return VAR(fmt(_type_name(vm, _0->type), '(', self.msg.escape(), ')')); return VAR(_S(_type_name(vm, _0->type), '(', self.msg.escape(), ')'));
}); });
_vm->bind__str__(VM::tp_exception, [](VM* vm, PyObject* _0) { _vm->bind__str__(VM::tp_exception, [](VM* vm, PyObject* _0) {
@ -1363,7 +1363,7 @@ void VM::post_init(){
_all_types[tp_module].m__getattr__ = [](VM* vm, PyObject* obj, StrName name) -> PyObject*{ _all_types[tp_module].m__getattr__ = [](VM* vm, PyObject* obj, StrName name) -> PyObject*{
const Str& path = CAST(Str&, obj->attr(__path__)); const Str& path = CAST(Str&, obj->attr(__path__));
return vm->py_import(fmt(path, ".", name.sv()), false); return vm->py_import(_S(path, ".", name.sv()), false);
}; };
bind_method<1>(tp_property, "setter", [](VM* vm, ArgsView args) { bind_method<1>(tp_property, "setter", [](VM* vm, ArgsView args) {

View File

@ -8,7 +8,7 @@ typedef int (*LuaStyleFuncC)(VM*);
#define PK_ASSERT_N_EXTRA_ELEMENTS(n) \ #define PK_ASSERT_N_EXTRA_ELEMENTS(n) \
int __ex_count = count_extra_elements(vm, n); \ int __ex_count = count_extra_elements(vm, n); \
if(__ex_count < n){ \ if(__ex_count < n){ \
Str msg = fmt("expected at least ", n, " elements, got ", __ex_count); \ Str msg = _S("expected at least ", n, " elements, got ", __ex_count); \
pkpy_error(vm_handle, "StackError", pkpy_string(msg.c_str())); \ pkpy_error(vm_handle, "StackError", pkpy_string(msg.c_str())); \
return false; \ return false; \
} }

View File

@ -3,7 +3,7 @@
namespace pkpy { namespace pkpy {
REPL::REPL(VM* vm) : vm(vm){ REPL::REPL(VM* vm) : vm(vm){
vm->stdout_write("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") "); vm->stdout_write("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
vm->stdout_write(fmt("[", sizeof(void*)*8, " bit] on ", kPlatformStrings[PK_SYS_PLATFORM], "\n")); vm->stdout_write(_S("[", sizeof(void*)*8, " bit] on ", kPlatformStrings[PK_SYS_PLATFORM], "\n"));
vm->stdout_write("https://github.com/pocketpy/pocketpy" "\n"); vm->stdout_write("https://github.com/pocketpy/pocketpy" "\n");
vm->stdout_write("Type \"exit()\" to exit." "\n"); vm->stdout_write("Type \"exit()\" to exit." "\n");
} }

View File

@ -26,7 +26,7 @@ namespace pkpy{
if(!first) ss << ", "; if(!first) ss << ", ";
first = false; first = false;
if(!is_non_tagged_type(k, vm->tp_str)){ if(!is_non_tagged_type(k, vm->tp_str)){
vm->TypeError(fmt("json keys must be string, got ", _type_name(vm, vm->_tp(k)))); vm->TypeError(_S("json keys must be string, got ", _type_name(vm, vm->_tp(k))));
} }
ss << _CAST(Str&, k).escape(false) << ": "; ss << _CAST(Str&, k).escape(false) << ": ";
write_object(v); write_object(v);
@ -55,7 +55,7 @@ namespace pkpy{
}else if(obj_t == vm->tp_dict){ }else if(obj_t == vm->tp_dict){
write_dict(_CAST(Dict&, obj)); write_dict(_CAST(Dict&, obj));
}else{ }else{
vm->TypeError(fmt("unrecognized type ", _type_name(vm, obj_t).escape())); vm->TypeError(_S("unrecognized type ", _type_name(vm, obj_t).escape()));
} }
} }
@ -198,7 +198,7 @@ namespace pkpy{
PyObject* obj = heap._new<Type>(tp_type, _all_types.size()); PyObject* obj = heap._new<Type>(tp_type, _all_types.size());
const PyTypeInfo& base_info = _all_types[base]; const PyTypeInfo& base_info = _all_types[base];
if(!base_info.subclass_enabled){ if(!base_info.subclass_enabled){
TypeError(fmt("type ", base_info.name.escape(), " is not `subclass_enabled`")); TypeError(_S("type ", base_info.name.escape(), " is not `subclass_enabled`"));
} }
PyTypeInfo info{ PyTypeInfo info{
obj, obj,
@ -316,7 +316,7 @@ namespace pkpy{
out = _import_handler(filename.data, filename.size, &out_size); out = _import_handler(filename.data, filename.size, &out_size);
} }
if(out == nullptr){ if(out == nullptr){
if(throw_err) ImportError(fmt("module ", path.escape(), " not found")); if(throw_err) ImportError(_S("module ", path.escape(), " not found"));
else return nullptr; else return nullptr;
} }
PK_ASSERT(out_size >= 0) PK_ASSERT(out_size >= 0)
@ -442,7 +442,7 @@ i64 VM::py_hash(PyObject* obj){
has_custom_eq = f != _t(tp_object)->attr(__eq__); has_custom_eq = f != _t(tp_object)->attr(__eq__);
} }
if(has_custom_eq){ if(has_custom_eq){
TypeError(fmt("unhashable type: ", ti->name.escape())); TypeError(_S("unhashable type: ", ti->name.escape()));
PK_UNREACHABLE() PK_UNREACHABLE()
}else{ }else{
return PK_BITS(obj); return PK_BITS(obj);
@ -545,7 +545,7 @@ PyObject* VM::new_module(Str name, Str package) {
// we do not allow override in order to avoid memory leak // we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected // it is because Module objects are not garbage collected
if(_modules.contains(name)){ if(_modules.contains(name)){
throw std::runtime_error(fmt("module ", name.escape(), " already exists").str()); throw std::runtime_error(_S("module ", name.escape(), " already exists").str());
} }
// set it into _modules // set it into _modules
_modules.set(name, obj); _modules.set(name, obj);
@ -557,20 +557,20 @@ static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
switch(byte.op){ switch(byte.op){
case OP_LOAD_CONST: case OP_FORMAT_STRING: case OP_IMPORT_PATH: case OP_LOAD_CONST: case OP_FORMAT_STRING: case OP_IMPORT_PATH:
if(vm != nullptr){ if(vm != nullptr){
argStr += fmt(" (", CAST(Str, vm->py_repr(co->consts[byte.arg])), ")").sv(); argStr += _S(" (", CAST(Str, vm->py_repr(co->consts[byte.arg])), ")").sv();
} }
break; break;
case OP_LOAD_NAME: case OP_LOAD_GLOBAL: case OP_LOAD_NONLOCAL: case OP_STORE_GLOBAL: case OP_LOAD_NAME: case OP_LOAD_GLOBAL: case OP_LOAD_NONLOCAL: case OP_STORE_GLOBAL:
case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR: case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
case OP_BEGIN_CLASS: case OP_GOTO: case OP_BEGIN_CLASS: case OP_GOTO:
case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL: case OP_STORE_CLASS_ATTR: case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL: case OP_STORE_CLASS_ATTR:
argStr += fmt(" (", StrName(byte.arg).sv(), ")").sv(); argStr += _S(" (", StrName(byte.arg).sv(), ")").sv();
break; break;
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST: case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST:
argStr += fmt(" (", co->varnames[byte.arg].sv(), ")").sv(); argStr += _S(" (", co->varnames[byte.arg].sv(), ")").sv();
break; break;
case OP_LOAD_FUNCTION: case OP_LOAD_FUNCTION:
argStr += fmt(" (", co->func_decls[byte.arg]->code->name, ")").sv(); argStr += _S(" (", co->func_decls[byte.arg]->code->name, ")").sv();
break; break;
} }
return argStr; return argStr;
@ -789,7 +789,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
int decl_argc = decl->args.size(); int decl_argc = decl->args.size();
if(args.size() < decl_argc){ if(args.size() < decl_argc){
vm->TypeError(fmt( vm->TypeError(_S(
co->name, "() takes ", decl_argc, " positional arguments but ", args.size(), " were given" co->name, "() takes ", decl_argc, " positional arguments but ", args.size(), " were given"
)); ));
} }
@ -813,7 +813,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
if(i >= args.size()) break; if(i >= args.size()) break;
buffer[kv.index] = args[i++]; buffer[kv.index] = args[i++];
} }
if(i < args.size()) TypeError(fmt("too many arguments", " (", decl->code->name, ')')); if(i < args.size()) TypeError(_S("too many arguments", " (", decl->code->name, ')'));
} }
PyObject* vkwargs; PyObject* vkwargs;
@ -833,7 +833,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
}else{ }else{
// otherwise, set as **kwargs if possible // otherwise, set as **kwargs if possible
if(vkwargs == nullptr){ if(vkwargs == nullptr){
TypeError(fmt(key.escape(), " is an invalid keyword argument for ", co->name, "()")); TypeError(_S(key.escape(), " is an invalid keyword argument for ", co->name, "()"));
}else{ }else{
Dict& dict = _CAST(Dict&, vkwargs); Dict& dict = _CAST(Dict&, vkwargs);
dict.set(VAR(key.sv()), kwargs[j+1]); dict.set(VAR(key.sv()), kwargs[j+1]);
@ -897,12 +897,12 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
int co_nlocals = co->varnames.size(); int co_nlocals = co->varnames.size();
if(decl->is_simple){ if(decl->is_simple){
if(args.size() != decl->args.size()){ if(args.size() != decl->args.size()){
TypeError(fmt( TypeError(_S(
co->name, "() takes ", decl->args.size(), " positional arguments but ", args.size(), " were given" co->name, "() takes ", decl->args.size(), " positional arguments but ", args.size(), " were given"
)); ));
} }
if(!kwargs.empty()){ if(!kwargs.empty()){
TypeError(fmt(co->name, "() takes no keyword arguments")); TypeError(_S(co->name, "() takes no keyword arguments"));
} }
s_data.reset(_base + co_nlocals); s_data.reset(_base + co_nlocals);
int i = 0; int i = 0;
@ -1145,7 +1145,7 @@ void VM::setattr(PyObject* obj, StrName name, PyObject* value){
if(prop.setter != vm->None){ if(prop.setter != vm->None){
call(prop.setter, obj, value); call(prop.setter, obj, value);
}else{ }else{
TypeError(fmt("readonly attribute: ", name.escape())); TypeError(_S("readonly attribute: ", name.escape()));
} }
return; return;
} }
@ -1170,7 +1170,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
CodeObject_ co; CodeObject_ co;
try{ try{
// fn(a, b, *c, d=1) -> None // fn(a, b, *c, d=1) -> None
co = compile(fmt("def ", sig, " : pass"), "<bind>", EXEC_MODE); co = compile(_S("def ", sig, " : pass"), "<bind>", EXEC_MODE);
}catch(const Exception&){ }catch(const Exception&){
throw std::runtime_error("invalid signature: " + std::string(sig)); throw std::runtime_error("invalid signature: " + std::string(sig));
} }
@ -1337,7 +1337,7 @@ void Dict::_probe_1(PyObject *key, bool &ok, int &i) const{
void NativeFunc::check_size(VM* vm, ArgsView args) const{ void NativeFunc::check_size(VM* vm, ArgsView args) const{
if(args.size() != argc && argc != -1) { if(args.size() != argc && argc != -1) {
vm->TypeError(fmt("expected ", argc, " arguments, got ", args.size())); vm->TypeError(_S("expected ", argc, " arguments, got ", args.size()));
} }
} }