From b77d7fafb184e9030dd51b8430362d11bcf52e3b Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Fri, 15 Sep 2023 00:04:19 +0800 Subject: [PATCH] :zap: using c++ cast --- src/bits_lib.cpp | 22 +++++++++---------- src/dylib_lib.cpp | 20 ++++++++++++----- src/fg_props.cpp | 3 ++- src/io_lib.cpp | 47 +++++++++++++++++++++++---------------- src/math_lib.cpp | 14 ++++++------ src/nasal_builtin.cpp | 20 ++++++++++------- src/nasal_gc.cpp | 7 +++--- src/nasal_opcode.cpp | 5 +++-- src/nasal_vm.cpp | 51 ++++++++++++++++++++++++------------------- src/nasal_vm.h | 2 +- src/unix_lib.cpp | 30 ++++++++++++------------- 11 files changed, 126 insertions(+), 95 deletions(-) diff --git a/src/bits_lib.cpp b/src/bits_lib.cpp index 398a563..a4000d8 100644 --- a/src/bits_lib.cpp +++ b/src/bits_lib.cpp @@ -3,21 +3,21 @@ namespace nasal { var builtin_u32xor(var* local, gc& ngc) { - return var::num((f64)( + return var::num(static_cast( static_cast(local[1].num()) ^ static_cast(local[2].num()) )); } var builtin_u32and(var* local, gc& ngc) { - return var::num((f64)( + return var::num(static_cast( static_cast(local[1].num()) & static_cast(local[2].num()) )); } var builtin_u32or(var* local, gc& ngc) { - return var::num((f64)( + return var::num(static_cast( static_cast(local[1].num()) | static_cast(local[2].num()) )); @@ -47,8 +47,8 @@ var builtin_fld(var* local, gc& ngc) { if (startbit.type!=vm_num || length.type!=vm_num) { return nas_err("fld", "\"startbit\",\"len\" must be number"); } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); + u32 bit = static_cast(startbit.num()); + u32 len = static_cast(length.num()); if (bit+len>8*str.str().length()) { return nas_err("fld", "bitfield out of bounds"); } @@ -59,7 +59,7 @@ var builtin_fld(var* local, gc& ngc) { res |= 1<<(bit+len-i-1); } } - return var::num((f64)res); + return var::num(static_cast(res)); } var builtin_sfld(var* local, gc& ngc) { @@ -76,8 +76,8 @@ var builtin_sfld(var* local, gc& ngc) { if (startbit.type!=vm_num || length.type!=vm_num) { return nas_err("sfld", "\"startbit\",\"len\" must be number"); } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); + u32 bit = static_cast(startbit.num()); + u32 len = static_cast(length.num()); if (bit+len>8*str.str().length()) { return nas_err("sfld", "bitfield out of bounds"); } @@ -109,9 +109,9 @@ var builtin_setfld(var* local, gc& ngc) { if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) { return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number"); } - u32 bit = (u32)startbit.num(); - u32 len = (u32)length.num(); - u64 val = (u64)value.num(); + u32 bit = static_cast(startbit.num()); + u32 len = static_cast(length.num()); + u64 val = static_cast(value.num()); if (bit+len>8*str.str().length()) { return nas_err("setfld", "bitfield out of bounds"); } diff --git a/src/dylib_lib.cpp b/src/dylib_lib.cpp index e004439..75c8aee 100644 --- a/src/dylib_lib.cpp +++ b/src/dylib_lib.cpp @@ -7,7 +7,7 @@ const auto func_addr_type_name = "faddr"; void dylib_destructor(void* ptr) { #ifdef _WIN32 - FreeLibrary((HMODULE)ptr); + FreeLibrary(static_cast(ptr)); #else dlclose(ptr); #endif @@ -41,7 +41,10 @@ var builtin_dlopen(var* local, gc& ngc) { ret.hash().elems["lib"] = lib; #ifdef _WIN32 - void* func = (void*)GetProcAddress((HMODULE)lib.obj().ptr, "get"); + void* func = (void*)GetProcAddress( + static_cast(lib.obj().ptr), + "get" + ); #else void* func = dlsym(lib.obj().ptr, "get"); #endif @@ -49,7 +52,7 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - module_func_info* tbl = ((get_func_ptr)func)(); + module_func_info* tbl = reinterpret_cast(func)(); if (!tbl) { return nas_err("dlopen", "failed to get module functions"); } @@ -80,7 +83,11 @@ var builtin_dlcallv(var* local, gc& ngc) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec = args.vec().elems; - return ((module_func)fp.obj().ptr)(vec.data(), vec.size(), &ngc); + return reinterpret_cast(fp.obj().ptr)( + vec.data(), + vec.size(), + &ngc + ); } var builtin_dlcall(var* local, gc& ngc) { @@ -92,10 +99,11 @@ var builtin_dlcall(var* local, gc& ngc) { var* local_frame_start = local+2; usize local_frame_size = ngc.rctx->top-local_frame_start; // arguments' stored place begins at local +2 - return ((module_func)fp.obj().ptr)( + return reinterpret_cast(fp.obj().ptr)( local_frame_start, local_frame_size, - &ngc); + &ngc + ); } nasal_builtin_table dylib_lib_native[] = { diff --git a/src/fg_props.cpp b/src/fg_props.cpp index 84082a9..fd958f7 100644 --- a/src/fg_props.cpp +++ b/src/fg_props.cpp @@ -23,7 +23,8 @@ var builtin_logprint(var* local, gc& ngc) { default: return nas_err("logprint", "incorrect log level " + - std::to_string(level.num())); + std::to_string(level.num()) + ); } for(auto& i : elems.vec().elems) { out << i << " "; diff --git a/src/io_lib.cpp b/src/io_lib.cpp index 9d5530b..d057e1e 100644 --- a/src/io_lib.cpp +++ b/src/io_lib.cpp @@ -5,10 +5,10 @@ namespace nasal { const auto file_type_name = "file"; void filehandle_destructor(void* ptr) { - if ((FILE*)ptr==stdin) { + if (static_cast(ptr)==stdin) { return; } - fclose((FILE*)ptr); + fclose(static_cast(ptr)); } var builtin_readfile(var* local, gc& ngc) { @@ -92,7 +92,7 @@ var builtin_read(var* local, gc& ngc) { if (!buff) { return nas_err("read", "malloc failed"); } - f64 res = fread(buff,1,len.num(), (FILE*)fd.obj().ptr); + f64 res = fread(buff, 1, len.num(), static_cast(fd.obj().ptr)); buf.str() = buff; buf.val.gcobj->unmut = true; delete []buff; @@ -108,7 +108,12 @@ var builtin_write(var* local, gc& ngc) { if (str.type!=vm_str) { return nas_err("write", "\"str\" must be string"); } - return var::num((f64)fwrite(str.str().c_str(), 1, str.str().length(), (FILE*)fd.obj().ptr)); + return var::num(static_cast(fwrite( + str.str().c_str(), + 1, + str.str().length(), + static_cast(fd.obj().ptr) + ))); } var builtin_seek(var* local, gc& ngc) { @@ -118,7 +123,11 @@ var builtin_seek(var* local, gc& ngc) { if (!fd.objchk(file_type_name)) { return nas_err("seek", "not a valid filehandle"); } - return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); + return var::num(static_cast(fseek( + static_cast(fd.obj().ptr), + pos.num(), + whence.num() + ))); } var builtin_tell(var* local, gc& ngc) { @@ -126,7 +135,7 @@ var builtin_tell(var* local, gc& ngc) { if (!fd.objchk(file_type_name)) { return nas_err("tell", "not a valid filehandle"); } - return var::num((f64)ftell((FILE*)fd.obj().ptr)); + return var::num(static_cast(ftell(static_cast(fd.obj().ptr)))); } var builtin_readln(var* local, gc& ngc) { @@ -136,7 +145,7 @@ var builtin_readln(var* local, gc& ngc) { } var str = ngc.alloc(vm_str); char c; - while((c = fgetc((FILE*)fd.obj().ptr))!=EOF) { + while((c = fgetc(static_cast(fd.obj().ptr)))!=EOF) { if (c=='\r') { continue; } @@ -162,17 +171,17 @@ var builtin_stat(var* local, gc& ngc) { } var ret = ngc.alloc(vm_vec); ret.vec().elems = { - var::num((f64)buf.st_dev), - var::num((f64)buf.st_ino), - var::num((f64)buf.st_mode), - var::num((f64)buf.st_nlink), - var::num((f64)buf.st_uid), - var::num((f64)buf.st_gid), - var::num((f64)buf.st_rdev), - var::num((f64)buf.st_size), - var::num((f64)buf.st_atime), - var::num((f64)buf.st_mtime), - var::num((f64)buf.st_ctime) + var::num(static_cast(buf.st_dev)), + var::num(static_cast(buf.st_ino)), + var::num(static_cast(buf.st_mode)), + var::num(static_cast(buf.st_nlink)), + var::num(static_cast(buf.st_uid)), + var::num(static_cast(buf.st_gid)), + var::num(static_cast(buf.st_rdev)), + var::num(static_cast(buf.st_size)), + var::num(static_cast(buf.st_atime)), + var::num(static_cast(buf.st_mtime)), + var::num(static_cast(buf.st_ctime)) }; return ret; } @@ -182,7 +191,7 @@ var builtin_eof(var* local, gc& ngc) { if (!fd.objchk(file_type_name)) { return nas_err("readln", "not a valid filehandle"); } - return var::num((f64)feof((FILE*)fd.obj().ptr)); + return var::num(static_cast(feof(static_cast(fd.obj().ptr)))); } nasal_builtin_table io_lib_native[] = { diff --git a/src/math_lib.cpp b/src/math_lib.cpp index 9b0af0e..2804e1d 100644 --- a/src/math_lib.cpp +++ b/src/math_lib.cpp @@ -13,37 +13,37 @@ var builtin_pow(var* local, gc& ngc) { var builtin_sin(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?sin(val.num()):std::nan("")); + return var::num(val.type==vm_num? sin(val.num()):std::nan("")); } var builtin_cos(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?cos(val.num()):std::nan("")); + return var::num(val.type==vm_num? cos(val.num()):std::nan("")); } var builtin_tan(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?tan(val.num()):std::nan("")); + return var::num(val.type==vm_num? tan(val.num()):std::nan("")); } var builtin_exp(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?exp(val.num()):std::nan("")); + return var::num(val.type==vm_num? exp(val.num()):std::nan("")); } var builtin_lg(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?log(val.num())/log(10.0):std::nan("")); + return var::num(val.type==vm_num? log(val.num())/log(10.0):std::nan("")); } var builtin_ln(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?log(val.num()):std::nan("")); + return var::num(val.type==vm_num? log(val.num()):std::nan("")); } var builtin_sqrt(var* local, gc& ngc) { var val = local[1]; - return var::num(val.type==vm_num?sqrt(val.num()):std::nan("")); + return var::num(val.type==vm_num? sqrt(val.num()):std::nan("")); } var builtin_atan2(var* local, gc& ngc) { diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 8e70a01..8d078d1 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -60,7 +60,7 @@ var builtin_system(var* local, gc& ngc) { if (str.type!=vm_str) { return var::num(-1); } - return var::num((f64)system(str.str().c_str())); + return var::num(static_cast(system(str.str().c_str()))); } var builtin_input(var* local, gc& ngc) { @@ -119,7 +119,7 @@ var builtin_rand(var* local, gc& ngc) { return nas_err("rand", "\"seed\" must be nil or number"); } if (val.type==vm_num) { - srand((u32)val.num()); + srand(static_cast(val.num())); return nil; } f64 num = 0; @@ -134,7 +134,8 @@ var builtin_id(var* local, gc& ngc) { std::stringstream ss; ss << "0"; if (val.type>vm_num) { - ss << "x" << std::hex << (u64)val.val.gcobj << std::dec; + ss << "x" << std::hex; + ss << reinterpret_cast(val.val.gcobj) << std::dec; } return ngc.newstr(ss.str()); } @@ -204,7 +205,7 @@ var builtin_time(var* local, gc& ngc) { return nas_err("time", "\"begin\" must be number"); } time_t begin = (time_t)val.num(); - return var::num((f64)time(&begin)); + return var::num(static_cast(time(&begin))); } var builtin_contains(var* local, gc& ngc) { @@ -261,9 +262,9 @@ var builtin_find(var* local, gc& ngc) { var haystack = local[2]; usize pos = haystack.tostr().find(needle.tostr()); if (pos==std::string::npos) { - return var::num((f64)-1); + return var::num(-1.0); } - return var::num((f64)pos); + return var::num(static_cast(pos)); } var builtin_type(var* local, gc& ngc) { @@ -350,7 +351,10 @@ var builtin_cmp(var* local, gc& ngc) { if (a.type!=vm_str || b.type!=vm_str) { return nas_err("cmp", "\"a\" and \"b\" must be string"); } - return var::num((f64)strcmp(a.str().c_str(), b.str().c_str())); + return var::num(static_cast(strcmp( + a.str().c_str(), + b.str().c_str() + ))); } var builtin_chr(var* local, gc& ngc) { @@ -608,7 +612,7 @@ var builtin_ghosttype(var* local, gc& ngc) { } const auto& name = arg.obj().get_ghost_name(); if (!name.length()) { - return var::num((u64)arg.obj().ptr); + return var::num(reinterpret_cast(arg.obj().ptr)); } return ngc.newstr(name); } diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index d2b46ff..a2046fe 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -130,7 +130,8 @@ void nas_ghost::clear() { std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) { out << ""; + out << " at 0x" << std::hex; + out << reinterpret_cast(ghost.ptr) << std::dec << ">"; return out; } @@ -268,11 +269,11 @@ bool var::objchk(const std::string& name) { } var var::none() { - return {vm_none, (u32)0}; + return {vm_none, static_cast(0)}; } var var::nil() { - return {vm_nil, (u32)0}; + return {vm_nil, static_cast(0)}; } var var::ret(u32 pc) { diff --git a/src/nasal_opcode.cpp b/src/nasal_opcode.cpp index 2b448ba..f581997 100644 --- a/src/nasal_opcode.cpp +++ b/src/nasal_opcode.cpp @@ -47,7 +47,7 @@ void codestream::dump(std::ostream& out) const { auto num = code.num; out << hex << "0x" << setw(6) << setfill('0') << index << " " - << setw(2) << setfill('0') << (u32)op << " " + << setw(2) << setfill('0') << static_cast(op) << " " << setw(2) << setfill('0') << ((num>>16)&0xff) << " " << setw(2) << setfill('0') << ((num>>8)&0xff) << " " << setw(2) << setfill('0') << (num&0xff) << " " @@ -92,7 +92,8 @@ void codestream::dump(std::ostream& out) const { out << hex << "0x" << num << dec; break; case op_callb: out << hex << "0x" << num << " <" << natives[num].name - << "@0x" << (u64)natives[num].func << dec << ">"; break; + << "@0x" << reinterpret_cast(natives[num].func) + << dec << ">"; break; case op_upval: case op_mupval: case op_loadu: out << hex << "0x" << ((num>>16)&0xffff) diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index 3952ec9..0fa761c 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -53,40 +53,42 @@ void vm::init( } void vm::valinfo(var& val) { - const nas_val* p = val.val.gcobj; + const auto p = reinterpret_cast(val.val.gcobj); switch(val.type) { case vm_none: std::clog << "| null |"; break; case vm_ret: std::clog << "| pc | 0x" << std::hex << val.ret() << std::dec; break; case vm_addr: std::clog << "| addr | 0x" << std::hex - << (u64)val.addr() << std::dec; break; + << reinterpret_cast(val.addr()) + << std::dec; break; case vm_cnt: std::clog << "| cnt | " << val.cnt(); break; case vm_nil: std::clog << "| nil |"; break; case vm_num: std::clog << "| num | " << val.num(); break; - case vm_str: std::clog << "| str | <0x" << std::hex << (u64)p + case vm_str: std::clog << "| str | <0x" << std::hex << p << "> " << rawstr(val.str(), 16) << std::dec; break; - case vm_func: std::clog << "| func | <0x" << std::hex << (u64)p + case vm_func: std::clog << "| func | <0x" << std::hex << p << "> entry:0x" << val.func().entry << std::dec; break; - case vm_upval:std::clog << "| upval| <0x" << std::hex << (u64)p + case vm_upval:std::clog << "| upval| <0x" << std::hex << p << std::dec << "> [" << val.upval().size << " val]"; break; - case vm_vec: std::clog << "| vec | <0x" << std::hex << (u64)p + case vm_vec: std::clog << "| vec | <0x" << std::hex << p << std::dec << "> [" << val.vec().size() << " val]"; break; - case vm_hash: std::clog << "| hash | <0x" << std::hex << (u64)p + case vm_hash: std::clog << "| hash | <0x" << std::hex << p << std::dec << "> {" << val.hash().size() << " val}"; break; - case vm_obj: std::clog << "| obj | <0x" << std::hex << (u64)p - << "> obj:0x" << (u64)val.obj().ptr + case vm_obj: std::clog << "| obj | <0x" << std::hex << p + << "> obj:0x" + << reinterpret_cast(val.obj().ptr) << std::dec; break; - case vm_co: std::clog << "| co | <0x" << std::hex << (u64)p + case vm_co: std::clog << "| co | <0x" << std::hex << p << std::dec << "> coroutine"; break; - case vm_map: std::clog << "| nmspc| <0x" << std::hex << (u64)p + case vm_map: std::clog << "| nmspc| <0x" << std::hex << p << std::dec << "> namespace [" << val.map().mapper.size() << " val]"; break; - default: std::clog << "| err | <0x" << std::hex << (u64)p + default: std::clog << "| err | <0x" << std::hex << p << std::dec << "> unknown object"; break; } std::clog << "\n"; @@ -128,8 +130,8 @@ void vm::traceback() { void vm::stackinfo(const u32 limit = 10) { var* top = ctx.top; var* bottom = ctx.stack; - std::clog << "stack (0x" << std::hex << (u64)bottom << std::dec; - std::clog << ", limit " << limit << ", total "; + std::clog << "stack (0x" << std::hex << reinterpret_cast(bottom); + std::clog << std::dec << ", limit " << limit << ", total "; std::clog << (top(top-bottom+1)) << ")\n"; for(u32 i = 0; i=bottom; ++i, --top) { std::clog << " 0x" << std::hex @@ -144,11 +146,16 @@ void vm::reginfo() { std::clog << "registers (" << (ngc.cort? "coroutine":"main") << ")\n" << std::hex << " [pc ] | pc | 0x" << ctx.pc << "\n" - << " [global] | addr | 0x" << (u64)global << "\n" - << " [local ] | addr | 0x" << (u64)ctx.localr << "\n" - << " [memr ] | addr | 0x" << (u64)ctx.memr << "\n" - << " [canary] | addr | 0x" << (u64)ctx.canary << "\n" - << " [top ] | addr | 0x" << (u64)ctx.top << "\n" + << " [global] | addr | 0x" + << reinterpret_cast(global) << "\n" + << " [local ] | addr | 0x" + << reinterpret_cast(ctx.localr) << "\n" + << " [memr ] | addr | 0x" + << reinterpret_cast(ctx.memr) << "\n" + << " [canary] | addr | 0x" + << reinterpret_cast(ctx.canary) << "\n" + << " [top ] | addr | 0x" + << reinterpret_cast(ctx.top) << "\n" << std::dec; std::clog << " [funcr ] "; valinfo(ctx.funcr); std::clog << " [upval ] "; valinfo(ctx.upvalr); @@ -159,7 +166,7 @@ void vm::gstate() { return; } std::clog << "global (0x" << std::hex - << (u64)global << ")\n" << std::dec; + << reinterpret_cast(global) << ")\n" << std::dec; for(usize i = 0; i(ctx.localr) + << " <+" << static_cast(ctx.localr-ctx.stack) << ">)\n" << std::dec; for(u32 i = 0; i(val.str().empty())); } else { ctx.top[0] = num? zero:one; } diff --git a/src/unix_lib.cpp b/src/unix_lib.cpp index 64ab0c2..e3ecad2 100644 --- a/src/unix_lib.cpp +++ b/src/unix_lib.cpp @@ -6,7 +6,7 @@ const auto dir_type_name = "dir"; void dir_entry_destructor(void* ptr) { #ifndef _MSC_VER - closedir((DIR*)ptr); + closedir(static_cast(ptr)); #else FindClose(ptr); #endif @@ -19,11 +19,11 @@ var builtin_pipe(var* local, gc& ngc) { if (pipe(fd)==-1) { return nas_err("pipe", "failed to create pipe"); } - res.vec().elems.push_back(var::num((f64)fd[0])); - res.vec().elems.push_back(var::num((f64)fd[1])); + res.vec().elems.push_back(var::num(static_cast(fd[0]))); + res.vec().elems.push_back(var::num(static_cast(fd[1]))); return res; #endif - return nas_err("pipe", "not supported"); + return nas_err("pipe", "not supported on windows"); } var builtin_fork(var* local, gc& ngc) { @@ -32,9 +32,9 @@ var builtin_fork(var* local, gc& ngc) { if (res<0) { return nas_err("fork", "failed to fork a process"); } - return var::num((f64)res); + return var::num(static_cast(res)); #endif - return nas_err("fork", "not supported"); + return nas_err("fork", "not supported on windows"); } var builtin_waitpid(var* local, gc& ngc) { @@ -44,14 +44,14 @@ var builtin_waitpid(var* local, gc& ngc) { return nas_err("waitpid", "pid and nohang must be number"); } #ifndef _WIN32 - i32 ret_pid,status; - ret_pid = waitpid(pid.num(),&status,nohang.num()==0? 0:WNOHANG); + i32 ret_pid, status; + ret_pid = waitpid(pid.num(), &status, nohang.num()==0? 0:WNOHANG); var vec = ngc.alloc(vm_vec); - vec.vec().elems.push_back(var::num((f64)ret_pid)); - vec.vec().elems.push_back(var::num((f64)status)); + vec.vec().elems.push_back(var::num(static_cast(ret_pid))); + vec.vec().elems.push_back(var::num(static_cast(status))); return vec; #endif - return nas_err("waitpid", "not supported"); + return nas_err("waitpid", "not supported on windows"); } var builtin_opendir(var* local, gc& ngc) { @@ -62,7 +62,7 @@ var builtin_opendir(var* local, gc& ngc) { #ifdef _MSC_VER WIN32_FIND_DATAA data; HANDLE p; - p = FindFirstFileA((path.str()+"\\*.*").c_str(),&data); + p = FindFirstFileA((path.str()+"\\*.*").c_str(), &data); if (p==INVALID_HANDLE_VALUE) { return nas_err("opendir", "cannot open dir <"+path.str()+">"); } @@ -89,7 +89,7 @@ var builtin_readdir(var* local, gc& ngc) { } return ngc.newstr(data.cFileName); #else - dirent* p = readdir((DIR*)handle.obj().ptr); + dirent* p = readdir(static_cast(handle.obj().ptr)); return p? ngc.newstr(p->d_name):nil; #endif } @@ -106,9 +106,9 @@ var builtin_closedir(var* local, gc& ngc) { var builtin_chdir(var* local, gc& ngc) { var path = local[1]; if (path.type!=vm_str) { - return var::num((f64)-1); + return var::num(-1.0); } - return var::num((f64)chdir(path.str().c_str())); + return var::num(static_cast(chdir(path.str().c_str()))); } var builtin_environ(var* local, gc& ngc) {