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);
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()
}
@ -110,7 +110,7 @@ void add_module_cjson(VM* vm){
const char* start = cJSON_GetErrorPtr();
const char* end = start;
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);
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);
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) {
@ -321,7 +321,7 @@ PyObject* lua_popx_to_python(VM* vm) {
default: {
const char* type_name = lua_typename(_L, type);
lua_pop(_L, 1);
vm->RuntimeError(fmt("unsupported lua type: '", type_name, "'"));
vm->RuntimeError(_S("unsupported lua type: '", type_name, "'"));
}
}
PK_UNREACHABLE()

View File

@ -19,7 +19,7 @@ namespace pkpy {
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \
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()); \
} \
PyObject* type = vm->new_type_object(mod, #name, base); \

View File

@ -291,7 +291,7 @@ struct NameDictImpl{
V operator[](StrName key) const {
V val = try_get_likely_found(key);
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;
}

View File

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

View File

@ -340,22 +340,22 @@ public:
void RuntimeError(const Str& msg){ _builtin_error("RuntimeError", msg); }
void ZeroDivisionError(const Str& msg){ _builtin_error("ZeroDivisionError", msg); }
void ZeroDivisionError(){ _builtin_error("ZeroDivisionError", "division by zero"); }
void NameError(StrName name){ _builtin_error("NameError", fmt("name ", name.escape() + " is not defined")); }
void UnboundLocalError(StrName name){ _builtin_error("UnboundLocalError", fmt("local variable ", name.escape() + " referenced before assignment")); }
void NameError(StrName name){ _builtin_error("NameError", _S("name ", name.escape() + " is not defined")); }
void UnboundLocalError(StrName name){ _builtin_error("UnboundLocalError", _S("local variable ", name.escape() + " referenced before assignment")); }
void KeyError(PyObject* obj){ _builtin_error("KeyError", obj); }
void ImportError(const Str& msg){ _builtin_error("ImportError", msg); }
void BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
StrName name_0 = _type_name(vm, _tp(_0));
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){
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{
_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); }

View File

@ -546,7 +546,7 @@ __NEXT_STEP:;
TARGET(GOTO) {
StrName _name(byte.arg);
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);
} DISPATCH();
/*****************************************/
@ -680,7 +680,7 @@ __NEXT_STEP:;
_name = StrName::get(CAST(Str&, key).sv());
PyObject* value = _0->attr().try_get_likely_found(_name);
if(value == nullptr){
ImportError(fmt("cannot import name ", _name.escape()));
ImportError(_S("cannot import name ", _name.escape()));
}else{
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){
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) \
@ -61,12 +61,12 @@ namespace pkpy{
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 vm->ValueError(fmt("invalid hex char: '", s[i], "'"));
else vm->ValueError(_S("invalid hex char: '", s[i], "'"));
c <<= 4;
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 vm->ValueError(fmt("invalid hex char: '", s[i+1], "'"));
else vm->ValueError(_S("invalid hex char: '", s[i+1], "'"));
buffer.p[i/2] = c;
}
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){ \
VoidP& self = _CAST(VoidP&, obj); \
return VAR(fmt("<", CNAME, "* at ", self.hex(), ">")); \
return VAR(_S("<", CNAME, "* at ", self.hex(), ">")); \
}); \
BIND_PRIMITIVE(char, "char")

View File

@ -133,7 +133,7 @@ namespace pkpy{
void Compiler::consume(TokenIndex expected) {
if (!match(expected)){
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
// get the stack size of the try block
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->push(obj); // push exception object
_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]);
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;
});

View File

@ -1273,7 +1273,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(VM::tp_module, [](VM* vm, PyObject* _0) {
const Str& path = CAST(Str&, _0->attr(__path__));
return VAR(fmt("<module ", path.escape(), ">"));
return VAR(_S("<module ", path.escape(), ">"));
});
// tp_property
@ -1339,7 +1339,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(VM::tp_exception, [](VM* vm, PyObject* _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) {
@ -1363,7 +1363,7 @@ void VM::post_init(){
_all_types[tp_module].m__getattr__ = [](VM* vm, PyObject* obj, StrName name) -> PyObject*{
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) {

View File

@ -8,7 +8,7 @@ typedef int (*LuaStyleFuncC)(VM*);
#define PK_ASSERT_N_EXTRA_ELEMENTS(n) \
int __ex_count = count_extra_elements(vm, 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())); \
return false; \
}

View File

@ -3,7 +3,7 @@
namespace pkpy {
REPL::REPL(VM* vm) : vm(vm){
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("Type \"exit()\" to exit." "\n");
}

View File

@ -26,7 +26,7 @@ namespace pkpy{
if(!first) ss << ", ";
first = false;
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) << ": ";
write_object(v);
@ -55,7 +55,7 @@ namespace pkpy{
}else if(obj_t == vm->tp_dict){
write_dict(_CAST(Dict&, obj));
}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());
const PyTypeInfo& base_info = _all_types[base];
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{
obj,
@ -316,7 +316,7 @@ namespace pkpy{
out = _import_handler(filename.data, filename.size, &out_size);
}
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;
}
PK_ASSERT(out_size >= 0)
@ -442,7 +442,7 @@ i64 VM::py_hash(PyObject* obj){
has_custom_eq = f != _t(tp_object)->attr(__eq__);
}
if(has_custom_eq){
TypeError(fmt("unhashable type: ", ti->name.escape()));
TypeError(_S("unhashable type: ", ti->name.escape()));
PK_UNREACHABLE()
}else{
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
// it is because Module objects are not garbage collected
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
_modules.set(name, obj);
@ -557,20 +557,20 @@ static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
switch(byte.op){
case OP_LOAD_CONST: case OP_FORMAT_STRING: case OP_IMPORT_PATH:
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;
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_BEGIN_CLASS: case OP_GOTO:
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;
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;
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;
}
return argStr;
@ -789,7 +789,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
int decl_argc = decl->args.size();
if(args.size() < decl_argc){
vm->TypeError(fmt(
vm->TypeError(_S(
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;
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;
@ -833,7 +833,7 @@ void VM::_prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, con
}else{
// otherwise, set as **kwargs if possible
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{
Dict& dict = _CAST(Dict&, vkwargs);
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();
if(decl->is_simple){
if(args.size() != decl->args.size()){
TypeError(fmt(
TypeError(_S(
co->name, "() takes ", decl->args.size(), " positional arguments but ", args.size(), " were given"
));
}
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);
int i = 0;
@ -1145,7 +1145,7 @@ void VM::setattr(PyObject* obj, StrName name, PyObject* value){
if(prop.setter != vm->None){
call(prop.setter, obj, value);
}else{
TypeError(fmt("readonly attribute: ", name.escape()));
TypeError(_S("readonly attribute: ", name.escape()));
}
return;
}
@ -1170,7 +1170,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
CodeObject_ co;
try{
// 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&){
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{
if(args.size() != argc && argc != -1) {
vm->TypeError(fmt("expected ", argc, " arguments, got ", args.size()));
vm->TypeError(_S("expected ", argc, " arguments, got ", args.size()));
}
}