✨ improve error info of out-of-range
This commit is contained in:
parent
a298aa3a63
commit
54317a39a7
|
@ -59,7 +59,7 @@ var create_new_ghost(var* args, usize size, gc* ngc) {
|
|||
|
||||
var set_new_ghost(var* args, usize size, gc* ngc) {
|
||||
var res = args[0];
|
||||
if (!res.objchk(ghost_for_test)) {
|
||||
if (!res.object_check(ghost_for_test)) {
|
||||
std::cout << "set_new_ghost: not ghost for test type.\n";
|
||||
return nil;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ var set_new_ghost(var* args, usize size, gc* ngc) {
|
|||
|
||||
var print_new_ghost(var* args, usize size, gc* ngc) {
|
||||
var res = args[0];
|
||||
if (!res.objchk(ghost_for_test)) {
|
||||
if (!res.object_check(ghost_for_test)) {
|
||||
std::cout << "print_new_ghost: not ghost for test type.\n";
|
||||
return nil;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ var builtin_dlopen(var* local, gc& ngc) {
|
|||
|
||||
var builtin_dlclose(var* local, gc& ngc) {
|
||||
var libptr = local[1];
|
||||
if (!libptr.objchk(dylib_type_name)) {
|
||||
if (!libptr.object_check(dylib_type_name)) {
|
||||
return nas_err("dlclose", "\"lib\" is not a valid dynamic lib");
|
||||
}
|
||||
libptr.obj().clear();
|
||||
|
@ -79,7 +79,7 @@ var builtin_dlclose(var* local, gc& ngc) {
|
|||
var builtin_dlcallv(var* local, gc& ngc) {
|
||||
var fp = local[1];
|
||||
var args = local[2];
|
||||
if (!fp.objchk(func_addr_type_name)) {
|
||||
if (!fp.object_check(func_addr_type_name)) {
|
||||
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
|
||||
}
|
||||
auto& vec = args.vec().elems;
|
||||
|
@ -92,7 +92,7 @@ var builtin_dlcallv(var* local, gc& ngc) {
|
|||
|
||||
var builtin_dlcall(var* local, gc& ngc) {
|
||||
var fp = local[1];
|
||||
if (!fp.objchk(func_addr_type_name)) {
|
||||
if (!fp.object_check(func_addr_type_name)) {
|
||||
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ var builtin_open(var* local, gc& ngc) {
|
|||
|
||||
var builtin_close(var* local, gc& ngc) {
|
||||
var fd = local[1];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("close", "not a valid filehandle");
|
||||
}
|
||||
fd.obj().clear();
|
||||
|
@ -76,7 +76,7 @@ var builtin_read(var* local, gc& ngc) {
|
|||
var fd = local[1];
|
||||
var buf = local[2];
|
||||
var len = local[3];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("read", "not a valid filehandle");
|
||||
}
|
||||
if (buf.type!=vm_str || buf.val.gcobj->unmutable) {
|
||||
|
@ -102,7 +102,7 @@ var builtin_read(var* local, gc& ngc) {
|
|||
var builtin_write(var* local, gc& ngc) {
|
||||
var fd = local[1];
|
||||
var str = local[2];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("write", "not a valid filehandle");
|
||||
}
|
||||
if (str.type!=vm_str) {
|
||||
|
@ -120,7 +120,7 @@ var builtin_seek(var* local, gc& ngc) {
|
|||
var fd = local[1];
|
||||
var pos = local[2];
|
||||
var whence = local[3];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("seek", "not a valid filehandle");
|
||||
}
|
||||
return var::num(static_cast<f64>(fseek(
|
||||
|
@ -132,7 +132,7 @@ var builtin_seek(var* local, gc& ngc) {
|
|||
|
||||
var builtin_tell(var* local, gc& ngc) {
|
||||
var fd = local[1];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("tell", "not a valid filehandle");
|
||||
}
|
||||
return var::num(static_cast<f64>(
|
||||
|
@ -142,7 +142,7 @@ var builtin_tell(var* local, gc& ngc) {
|
|||
|
||||
var builtin_readln(var* local, gc& ngc) {
|
||||
var fd = local[1];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("readln", "not a valid filehandle");
|
||||
}
|
||||
var str = ngc.alloc(vm_str);
|
||||
|
@ -190,7 +190,7 @@ var builtin_stat(var* local, gc& ngc) {
|
|||
|
||||
var builtin_eof(var* local, gc& ngc) {
|
||||
var fd = local[1];
|
||||
if (!fd.objchk(file_type_name)) {
|
||||
if (!fd.object_check(file_type_name)) {
|
||||
return nas_err("readln", "not a valid filehandle");
|
||||
}
|
||||
return var::num(static_cast<f64>(
|
||||
|
|
|
@ -264,7 +264,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) {
|
|||
return out;
|
||||
}
|
||||
|
||||
bool var::objchk(const std::string& name) {
|
||||
bool var::object_check(const std::string& name) {
|
||||
return type==vm_obj && obj().type_name==name && obj().pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
// number and string can be translated to each other
|
||||
f64 to_num();
|
||||
std::string to_str();
|
||||
bool objchk(const std::string&);
|
||||
bool object_check(const std::string&);
|
||||
|
||||
// create new var object
|
||||
static var none();
|
||||
|
|
|
@ -353,6 +353,17 @@ std::string vm::report_key_not_found(
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string vm::report_out_of_range(f64 index, usize real_size) const {
|
||||
auto result = "index out of range: " + std::to_string(index);
|
||||
result += " but max size is " + std::to_string(real_size);
|
||||
if (!real_size) {
|
||||
return result;
|
||||
}
|
||||
result += ", index range is -" + std::to_string(real_size);
|
||||
result += "~" + std::to_string(real_size-1);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string vm::type_name_string(const var& value) const {
|
||||
switch(value.type) {
|
||||
case vm_none: return "none";
|
||||
|
|
|
@ -72,6 +72,7 @@ protected:
|
|||
std::string report_lack_arguments(u32, const nas_func&) const;
|
||||
std::string report_special_call_lack_arguments(var*, const nas_func&) const;
|
||||
std::string report_key_not_found(const std::string&, const nas_hash&) const;
|
||||
std::string report_out_of_range(f64, usize) const;
|
||||
std::string type_name_string(const var&) const;
|
||||
void die(const std::string&);
|
||||
|
||||
|
@ -312,7 +313,9 @@ inline void vm::o_lnot() {
|
|||
ctx.top[0] = num? zero:one;
|
||||
}
|
||||
} break;
|
||||
default: die("incorrect value type"); return;
|
||||
default:
|
||||
die("cannot do not-operation on "+type_name_string(val));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,7 +614,7 @@ inline void vm::o_callv() {
|
|||
if (vec.type==vm_vec) {
|
||||
ctx.top[0] = vec.vec().get_val(val.to_num());
|
||||
if (ctx.top[0].type==vm_none) {
|
||||
die("out of range:"+std::to_string(val.to_num()));
|
||||
die(report_out_of_range(val.to_num(), vec.vec().size()));
|
||||
return;
|
||||
}
|
||||
} else if (vec.type==vm_hash) {
|
||||
|
@ -621,7 +624,7 @@ inline void vm::o_callv() {
|
|||
}
|
||||
ctx.top[0] = vec.hash().get_val(val.str());
|
||||
if (ctx.top[0].type==vm_none) {
|
||||
die("cannot find member \""+val.str()+"\"");
|
||||
die(report_key_not_found(val.str(), vec.hash()));
|
||||
return;
|
||||
} else if (ctx.top[0].type==vm_func) {
|
||||
ctx.top[0].func().local[0] = val; // 'me'
|
||||
|
@ -631,7 +634,7 @@ inline void vm::o_callv() {
|
|||
i32 num = val.to_num();
|
||||
i32 len = str.length();
|
||||
if (num<-len || num>=len) {
|
||||
die("out of range:"+std::to_string(val.to_num()));
|
||||
die(report_out_of_range(num, str.size()));
|
||||
return;
|
||||
}
|
||||
ctx.top[0] = var::num(
|
||||
|
@ -662,7 +665,7 @@ inline void vm::o_callvi() {
|
|||
// cannot use operator[],because this may cause overflow
|
||||
(++ctx.top)[0] = val.vec().get_val(imm[ctx.pc]);
|
||||
if (ctx.top[0].type==vm_none) {
|
||||
die("out of range:"+std::to_string(imm[ctx.pc]));
|
||||
die(report_out_of_range(imm[ctx.pc], val.vec().size()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -853,7 +856,7 @@ inline void vm::o_slc() {
|
|||
var val = (ctx.top--)[0];
|
||||
var res = ctx.top[-1].vec().get_val(val.to_num());
|
||||
if (res.type==vm_none) {
|
||||
die("index " + std::to_string(val.to_num()) + " out of range");
|
||||
die(report_out_of_range(val.to_num(), ctx.top[-1].vec().size()));
|
||||
return;
|
||||
}
|
||||
ctx.top[0].vec().elems.push_back(res);
|
||||
|
@ -880,7 +883,9 @@ inline void vm::o_slc2() {
|
|||
|
||||
if (num1<-size || num1>=size || num2<-size || num2>=size) {
|
||||
die("index " + std::to_string(num1) + ":" +
|
||||
std::to_string(num2) + " out of range");
|
||||
std::to_string(num2) + " out of range, real size is " +
|
||||
std::to_string(size)
|
||||
);
|
||||
return;
|
||||
} else if (num1<=num2) {
|
||||
for(i32 i = num1; i<=num2; ++i) {
|
||||
|
@ -920,7 +925,7 @@ inline void vm::o_mcallv() {
|
|||
if (vec.type==vm_vec) {
|
||||
ctx.memr = vec.vec().get_mem(val.to_num());
|
||||
if (!ctx.memr) {
|
||||
die("index "+std::to_string(val.to_num())+" out of range");
|
||||
die(report_out_of_range(val.to_num(), vec.vec().size()));
|
||||
return;
|
||||
}
|
||||
} else if (vec.type==vm_hash) { // do mcallh but use the mcallv way
|
||||
|
|
|
@ -79,7 +79,7 @@ var builtin_opendir(var* local, gc& ngc) {
|
|||
|
||||
var builtin_readdir(var* local, gc& ngc) {
|
||||
var handle = local[1];
|
||||
if (!handle.objchk(dir_type_name)) {
|
||||
if (!handle.object_check(dir_type_name)) {
|
||||
return nas_err("readdir", "not a valid dir handle");
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
|
@ -96,7 +96,7 @@ var builtin_readdir(var* local, gc& ngc) {
|
|||
|
||||
var builtin_closedir(var* local, gc& ngc) {
|
||||
var handle = local[1];
|
||||
if (!handle.objchk(dir_type_name)) {
|
||||
if (!handle.object_check(dir_type_name)) {
|
||||
return nas_err("closedir", "not a valid dir handle");
|
||||
}
|
||||
handle.obj().clear();
|
||||
|
|
Loading…
Reference in New Issue