diff --git a/module/fib.cpp b/module/fib.cpp index 1bb9046..529d77b 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -53,7 +53,7 @@ void ghost_for_test_destructor(void* ptr) { var create_new_ghost(var* args, usize size, gc* ngc) { var res = ngc->alloc(vm_obj); - res.obj().set(ghost_for_test, ghost_for_test_destructor, new u32); + res.ghost().set(ghost_for_test, ghost_for_test_destructor, new u32); return res; } @@ -64,7 +64,7 @@ var set_new_ghost(var* args, usize size, gc* ngc) { return nil; } f64 num = args[1].num(); - *((u32*)res.obj().pointer) = static_cast(num); + *((u32*)res.ghost().pointer) = static_cast(num); std::cout << "set_new_ghost: successfully set ghost = " << num << "\n"; return nil; } @@ -75,8 +75,8 @@ var print_new_ghost(var* args, usize size, gc* ngc) { std::cout << "print_new_ghost: not ghost for test type.\n"; return nil; } - std::cout << "print_new_ghost: " << res.obj() << " result = " - << *((u32*)res.obj().pointer) << "\n"; + std::cout << "print_new_ghost: " << res.ghost() << " result = " + << *((u32*)res.ghost().pointer) << "\n"; return nil; } diff --git a/src/bits_lib.cpp b/src/bits_lib.cpp index 95639b9..4ca0455 100644 --- a/src/bits_lib.cpp +++ b/src/bits_lib.cpp @@ -49,15 +49,15 @@ var builtin_fld(context* ctx, gc* ngc) { auto startbit = local[2]; auto length = local[3]; if (str.type!=vm_str || str.val.gcobj->unmutable) { - return nas_err("fld", "\"str\" must be mutable string"); + return nas_err("bits::fld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("fld", "\"startbit\",\"len\" must be number"); + return nas_err("bits::fld", "\"startbit\",\"len\" must be number"); } 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"); + return nas_err("bits::fld", "bitfield out of bounds"); } u32 res = 0; auto& s = str.str(); @@ -79,15 +79,15 @@ var builtin_sfld(context* ctx, gc* ngc) { auto startbit = local[2]; auto length = local[3]; if (str.type!=vm_str || str.val.gcobj->unmutable) { - return nas_err("sfld", "\"str\" must be mutable string"); + return nas_err("bits::sfld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("sfld", "\"startbit\",\"len\" must be number"); + return nas_err("bits::sfld", "\"startbit\",\"len\" must be number"); } 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"); + return nas_err("bits::sfld", "bitfield out of bounds"); } u32 res = 0; auto& s = str.str(); @@ -113,16 +113,18 @@ var builtin_setfld(context* ctx, gc* ngc) { auto length = local[3]; auto value = local[4]; if (str.type!=vm_str || str.val.gcobj->unmutable) { - return nas_err("setfld", "\"str\" must be mutable string"); + return nas_err("bits::setfld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) { - return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number"); + return nas_err("bits::setfld", + "\"startbit\", \"len\", \"val\" must be number" + ); } 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"); + return nas_err("bits::setfld", "bitfield out of bounds"); } auto& s = str.str(); for(u32 i = bit; ilocalr[1]; if (length.type!=vm_num || length.num()<=0) { - return nas_err("buf", "\"len\" must be number greater than 0"); + return nas_err("bits::buf", "\"len\" must be number greater than 0"); } var str = ngc->alloc(vm_str); auto& s = str.str(); diff --git a/src/coroutine.cpp b/src/coroutine.cpp index 5603656..c0f5003 100644 --- a/src/coroutine.cpp +++ b/src/coroutine.cpp @@ -75,7 +75,7 @@ var builtin_coresume(context* ctx, gc* ngc) { } // change to coroutine context - ngc->ctxchg(coroutine_object.co()); + ngc->context_change(&coroutine_object.co()); // fetch coroutine's stack top and return // then coroutine's stack top will catch this return value @@ -103,7 +103,7 @@ var builtin_coyield(context* ctx, gc* ngc) { auto coroutine_local_frame = ctx->localr; // vm context will set to main context - ngc->ctxreserve(); + ngc->context_reserve(); // then this will return value to main's stack top[0] // the procedure seems like coroutine.resume returns the value diff --git a/src/dylib_lib.cpp b/src/dylib_lib.cpp index 6d26152..494466d 100644 --- a/src/dylib_lib.cpp +++ b/src/dylib_lib.cpp @@ -2,89 +2,108 @@ namespace nasal { -const auto dylib_type_name = "dylib"; -const auto func_addr_type_name = "faddr"; +const auto dynamic_library_type_name = "dylib"; +const auto function_address_type_name = "faddr"; -void dylib_destructor(void* ptr) { +void dynamic_library_destructor(void* pointer) { #ifdef _WIN32 - FreeLibrary(static_cast(ptr)); + FreeLibrary(static_cast(pointer)); #else - dlclose(ptr); + dlclose(pointer); #endif } -void func_addr_destructor(void* ptr) {} - var builtin_dlopen(context* ctx, gc* ngc) { auto dlname = ctx->localr[1]; if (dlname.type!=vm_str) { - return nas_err("dlopen", "\"libname\" must be string"); + return nas_err("dylib::dlopen", "\"libname\" must be string"); } -#ifdef _WIN32 - wchar_t* str = new wchar_t[dlname.str().size()+1]; - if (!str) { - return nas_err("dlopen", "malloc failed"); - } - memset(str, 0, sizeof(wchar_t)*dlname.str().size()+1); - mbstowcs(str, dlname.str().c_str(),dlname.str().size()+1); - void* ptr = LoadLibraryA(dlname.str().c_str()); - delete []str; -#else - void* ptr = dlopen(dlname.str().c_str(), RTLD_LOCAL|RTLD_LAZY); -#endif - if (!ptr) { - return nas_err("dlopen", "cannot open dynamic lib <"+dlname.str()+">"); - } - auto ret = ngc->temp = ngc->alloc(vm_hash); - auto lib = ngc->alloc(vm_obj); - lib.obj().set(dylib_type_name, dylib_destructor, ptr); - ret.hash().elems["lib"] = lib; + // get library pointer #ifdef _WIN32 - void* func = (void*)GetProcAddress( - static_cast(lib.obj().pointer), - "get" + wchar_t* wide_string = new wchar_t[dlname.str().size()+1]; + if (!wide_string) { + return nas_err("dylib::dlopen", "malloc failed"); + } + memset(wide_string, 0, sizeof(wchar_t) * dlname.str().size() + 1); + mbstowcs(wide_string, dlname.str().c_str(), dlname.str().size() + 1); + // load library by using wide string name + void* dynamic_library_pointer = LoadLibraryA(dlname.str().c_str()); + delete []wide_string; +#else + void* dynamic_library_pointer = dlopen( + dlname.str().c_str(), RTLD_LOCAL|RTLD_LAZY + ); +#endif + + // check library pointer and insert into returned hashmap + if (!dynamic_library_pointer) { + return nas_err("dylib::dlopen", + "cannot open dynamic lib <" + dlname.str() + ">" + ); + } + auto return_hash = ngc->temp = ngc->alloc(vm_hash); + auto library_object = ngc->alloc(vm_obj); + library_object.ghost().set( + dynamic_library_type_name, + dynamic_library_destructor, + dynamic_library_pointer + ); + return_hash.hash().elems["lib"] = library_object; + + // get "get" function, to get the register table +#ifdef _WIN32 + void* register_table_get_function = (void*)GetProcAddress( + static_cast(library_object.ghost().pointer), "get" ); #else - void* func = dlsym(lib.obj().pointer, "get"); + void* register_table_get_function = dlsym( + library_object.ghost().pointer, "get" + ); #endif - if (!func) { - return nas_err("dlopen", "cannot find function"); + if (!register_table_get_function) { + return nas_err("dylib::dlopen", "cannot find function"); } + // get function pointer by name - auto tbl = reinterpret_cast(func)(); - if (!tbl) { - return nas_err("dlopen", "failed to get module functions"); + auto table = reinterpret_cast(register_table_get_function)(); + if (!table) { + return nas_err("dylib::dlopen", "failed to get module functions"); } - for(u32 i = 0; tbl[i].name; ++i) { - void* p = (void*)tbl[i].fd; - var tmp = ngc->alloc(vm_obj); - tmp.obj().set(func_addr_type_name, func_addr_destructor, p); - ret.hash().elems[tbl[i].name] = tmp; + for(u32 i = 0; table[i].name; ++i) { + auto function_pointer = reinterpret_cast(table[i].fd); + auto function_object = ngc->alloc(vm_obj); + function_object.ghost().set( + function_address_type_name, + nullptr, + function_pointer + ); + return_hash.hash().elems[table[i].name] = function_object; } ngc->temp = nil; - return ret; + return return_hash; } var builtin_dlclose(context* ctx, gc* ngc) { - auto libptr = ctx->localr[1]; - if (!libptr.object_check(dylib_type_name)) { - return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); + auto library_pointer = ctx->localr[1]; + if (!library_pointer.object_check(dynamic_library_type_name)) { + return nas_err("dylib::dlclose", "\"lib\" is not a valid dynamic lib"); } - libptr.obj().clear(); + library_pointer.ghost().clear(); return nil; } var builtin_dlcallv(context* ctx, gc* ngc) { - auto local = ctx->localr; - auto fp = local[1]; - auto args = local[2]; - if (!fp.object_check(func_addr_type_name)) { - return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); + auto function_object = ctx->localr[1]; + auto arguments = ctx->localr[2]; + if (!function_object.object_check(function_address_type_name)) { + return nas_err("dylib::dlcall", + "\"ptr\" is not a valid function pointer" + ); } - auto& vec = args.vec().elems; - return reinterpret_cast(fp.obj().pointer)( + auto& vec = arguments.vec().elems; + return reinterpret_cast(function_object.ghost().pointer)( vec.data(), vec.size(), ngc @@ -92,16 +111,18 @@ var builtin_dlcallv(context* ctx, gc* ngc) { } var builtin_dlcall(context* ctx, gc* ngc) { - auto local = ctx->localr; - var fp = local[1]; - if (!fp.object_check(func_addr_type_name)) { - return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); + auto function_object = ctx->localr[1]; + if (!function_object.object_check(function_address_type_name)) { + return nas_err("dylib::dlcall", + "\"ptr\" is not a valid function pointer" + ); } - var* local_frame_start = local+2; - usize local_frame_size = ngc->running_context->top-local_frame_start; - // arguments' stored place begins at local +2 - return reinterpret_cast(fp.obj().pointer)( + // function pointer is at ctx->localr[1] + // so arguments starts from ctx->localr[2] + var* local_frame_start = ctx->localr + 2; + usize local_frame_size = ngc->running_context->top - local_frame_start; + return reinterpret_cast(function_object.ghost().pointer)( local_frame_start, local_frame_size, ngc diff --git a/src/dylib_lib.h b/src/dylib_lib.h index 7eed093..b379f9f 100644 --- a/src/dylib_lib.h +++ b/src/dylib_lib.h @@ -13,8 +13,7 @@ namespace nasal { -void dylib_destructor(void*); -void func_addr_destructor(void*); +void dynamic_library_destructor(void*); var builtin_dlopen(context*, gc*); var builtin_dlclose(context*, gc*); diff --git a/src/fg_props.cpp b/src/fg_props.cpp index 25ddf7e..8c5f371 100644 --- a/src/fg_props.cpp +++ b/src/fg_props.cpp @@ -9,7 +9,7 @@ var builtin_logprint(context* ctx, gc* ngc) { auto level = local[1]; auto elems = local[2]; if (elems.type!=vm_vec) { - return nas_err("logprint", "received argument is not vector."); + return nas_err("fg_env::logprint", "received argument is not vector."); } std::ofstream out("fgfs.log", std::ios::app); switch (static_cast(level.num())) { @@ -22,13 +22,12 @@ var builtin_logprint(context* ctx, gc* ngc) { case SG_DEV_ALERT: out << "[DEV_ALERT]"; break; case SG_MANDATORY_INFO: out << "[MANDATORY_INFO]"; break; default: - return nas_err("logprint", - "incorrect log level " + - std::to_string(level.num()) + return nas_err("fg_env::logprint", + "incorrect log level " + std::to_string(level.num()) ); } - for(auto& i : elems.vec().elems) { - out << i << " "; + for(auto& value : elems.vec().elems) { + out << value << " "; } out << "\n"; return nil; diff --git a/src/io_lib.cpp b/src/io_lib.cpp index 9fdd19a..848ba13 100644 --- a/src/io_lib.cpp +++ b/src/io_lib.cpp @@ -12,11 +12,11 @@ void filehandle_destructor(void* ptr) { } var builtin_readfile(context* ctx, gc* ngc) { - auto val = ctx->localr[1]; - if (val.type!=vm_str) { + auto filename = ctx->localr[1]; + if (filename.type!=vm_str) { return nas_err("io::readfile", "\"filename\" must be string"); } - std::ifstream in(val.str(), std::ios::binary); + std::ifstream in(filename.str(), std::ios::binary); std::stringstream rd; if (!in.fail()) { rd << in.rdbuf(); @@ -26,25 +26,25 @@ var builtin_readfile(context* ctx, gc* ngc) { var builtin_fout(context* ctx, gc* ngc) { auto local = ctx->localr; - auto val = local[1]; - auto str = local[2]; - if (val.type!=vm_str) { + auto filename = local[1]; + auto source = local[2]; + if (filename.type!=vm_str) { return nas_err("io::fout", "\"filename\" must be string"); } - std::ofstream out(val.str()); + std::ofstream out(filename.str()); if (out.fail()) { - return nas_err("io::fout", "cannot open <"+val.str()+">"); + return nas_err("io::fout", "cannot open <" + filename.str() + ">"); } - out << str; + out << source; return nil; } var builtin_exists(context* ctx, gc* ngc) { - auto local = ctx->localr; - if (local[1].type!=vm_str) { + auto filename = ctx->localr[1]; + if (filename.type!=vm_str) { return zero; } - return access(local[1].str().c_str(), F_OK)!=-1? one:zero; + return access(filename.str().c_str(), F_OK)!=-1? one:zero; } var builtin_open(context* ctx, gc* ngc) { @@ -52,118 +52,121 @@ var builtin_open(context* ctx, gc* ngc) { auto name = local[1]; auto mode = local[2]; if (name.type!=vm_str) { - return nas_err("open", "\"filename\" must be string"); + return nas_err("io::open", "\"filename\" must be string"); } if (mode.type!=vm_str) { - return nas_err("open", "\"mode\" must be string"); + return nas_err("io::open", "\"mode\" must be string"); } - FILE* res = fopen(name.str().c_str(), mode.str().c_str()); - if (!res) { - return nas_err("open", "failed to open file <"+name.str()+">"); + auto file_descriptor = fopen(name.str().c_str(), mode.str().c_str()); + if (!file_descriptor) { + return nas_err("io::open", "failed to open file <" + name.str() + ">"); } - var ret = ngc->alloc(vm_obj); - ret.obj().set(file_type_name, filehandle_destructor, res); - return ret; + var return_object = ngc->alloc(vm_obj); + return_object.ghost().set( + file_type_name, filehandle_destructor, file_descriptor + ); + return return_object; } var builtin_close(context* ctx, gc* ngc) { - var fd = ctx->localr[1]; - if (!fd.object_check(file_type_name)) { - return nas_err("close", "not a valid filehandle"); + var file_descriptor = ctx->localr[1]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::close", "not a valid filehandle"); } - fd.obj().clear(); + file_descriptor.ghost().clear(); return nil; } var builtin_read(context* ctx, gc* ngc) { auto local = ctx->localr; - auto fd = local[1]; - auto buf = local[2]; - auto len = local[3]; - if (!fd.object_check(file_type_name)) { - return nas_err("read", "not a valid filehandle"); + auto file_descriptor = local[1]; + auto buffer = local[2]; + auto length = local[3]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::read", "not a valid filehandle"); } - if (buf.type!=vm_str || buf.val.gcobj->unmutable) { - return nas_err("read", "\"buf\" must be mutable string"); + if (buffer.type!=vm_str || buffer.val.gcobj->unmutable) { + return nas_err("io::read", "\"buf\" must be mutable string"); } - if (len.type!=vm_num) { - return nas_err("read", "\"len\" must be number"); + if (length.type!=vm_num) { + return nas_err("io::read", "\"len\" must be number"); } - if (len.num()<=0 || len.num()>=(1<<30)) { - return nas_err("read", "\"len\" less than 1 or too large"); + if (length.num()<=0 || length.num()>=(1<<30)) { + return nas_err("io::read", "\"len\" less than 1 or too large"); } - char* buff = new char[(usize)len.num()+1]; - if (!buff) { - return nas_err("read", "malloc failed"); + auto temp_buffer = new char[static_cast(length.num())+1]; + if (!temp_buffer) { + return nas_err("io::read", "malloc failed"); } - f64 res = fread(buff, 1, len.num(), static_cast(fd.obj().pointer)); - buf.str() = buff; - buf.val.gcobj->unmutable = true; - delete []buff; - return var::num(res); + auto read_size = fread( + temp_buffer, 1, length.num(), + static_cast(file_descriptor.ghost().pointer) + ); + buffer.str() = temp_buffer; + buffer.val.gcobj->unmutable = true; + delete []temp_buffer; + return var::num(read_size); } var builtin_write(context* ctx, gc* ngc) { auto local = ctx->localr; - auto fd = local[1]; - auto str = local[2]; - if (!fd.object_check(file_type_name)) { - return nas_err("write", "not a valid filehandle"); + auto file_descriptor = local[1]; + auto source = local[2]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::write", "not a valid filehandle"); } - if (str.type!=vm_str) { - return nas_err("write", "\"str\" must be string"); + if (source.type!=vm_str) { + return nas_err("io::write", "\"str\" must be string"); } return var::num(static_cast(fwrite( - str.str().c_str(), - 1, - str.str().length(), - static_cast(fd.obj().pointer) + source.str().c_str(), 1, source.str().length(), + static_cast(file_descriptor.ghost().pointer) ))); } var builtin_seek(context* ctx, gc* ngc) { auto local = ctx->localr; - auto fd = local[1]; - auto pos = local[2]; + auto file_descriptor = local[1]; + auto position = local[2]; auto whence = local[3]; - if (!fd.object_check(file_type_name)) { - return nas_err("seek", "not a valid filehandle"); + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::seek", "not a valid filehandle"); } return var::num(static_cast(fseek( - static_cast(fd.obj().pointer), - pos.num(), + static_cast(file_descriptor.ghost().pointer), + position.num(), whence.num() ))); } var builtin_tell(context* ctx, gc* ngc) { - auto fd = ctx->localr[1]; - if (!fd.object_check(file_type_name)) { - return nas_err("tell", "not a valid filehandle"); + auto file_descriptor = ctx->localr[1]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::tell", "not a valid filehandle"); } return var::num(static_cast( - ftell(static_cast(fd.obj().pointer)) + ftell(static_cast(file_descriptor.ghost().pointer)) )); } var builtin_readln(context* ctx, gc* ngc) { - auto fd = ctx->localr[1]; - if (!fd.object_check(file_type_name)) { - return nas_err("readln", "not a valid filehandle"); + auto file_descriptor = ctx->localr[1]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::readln", "not a valid filehandle"); } - auto str = ngc->alloc(vm_str); + auto result = ngc->alloc(vm_str); char c; - while((c = fgetc(static_cast(fd.obj().pointer)))!=EOF) { + while((c = fgetc(static_cast(file_descriptor.ghost().pointer)))!=EOF) { if (c=='\r') { continue; } if (c=='\n') { - return str; + return result; } - str.str() += c; + result.str().push_back(c); } - if (str.str().length()) { - return str; + if (result.str().length()) { + return result; } return nil; } @@ -171,36 +174,36 @@ var builtin_readln(context* ctx, gc* ngc) { var builtin_stat(context* ctx, gc* ngc) { auto name = ctx->localr[1]; if (name.type!=vm_str) { - return nas_err("stat", "\"filename\" must be string"); + return nas_err("io::stat", "\"filename\" must be string"); } - struct stat buf; - if (stat(name.str().c_str(), &buf)<0) { - return nas_err("stat", "failed to open file <"+name.str()+">"); + struct stat buffer; + if (stat(name.str().c_str(), &buffer)<0) { + return nas_err("io::stat", "failed to open file <" + name.str() + ">"); } - auto ret = ngc->alloc(vm_vec); - ret.vec().elems = { - 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)) + auto result = ngc->alloc(vm_vec); + result.vec().elems = { + var::num(static_cast(buffer.st_dev)), + var::num(static_cast(buffer.st_ino)), + var::num(static_cast(buffer.st_mode)), + var::num(static_cast(buffer.st_nlink)), + var::num(static_cast(buffer.st_uid)), + var::num(static_cast(buffer.st_gid)), + var::num(static_cast(buffer.st_rdev)), + var::num(static_cast(buffer.st_size)), + var::num(static_cast(buffer.st_atime)), + var::num(static_cast(buffer.st_mtime)), + var::num(static_cast(buffer.st_ctime)) }; - return ret; + return result; } var builtin_eof(context* ctx, gc* ngc) { - auto fd = ctx->localr[1]; - if (!fd.object_check(file_type_name)) { - return nas_err("readln", "not a valid filehandle"); + auto file_descriptor = ctx->localr[1]; + if (!file_descriptor.object_check(file_type_name)) { + return nas_err("io::readln", "not a valid filehandle"); } return var::num(static_cast( - feof(static_cast(fd.obj().pointer)) + feof(static_cast(file_descriptor.ghost().pointer)) )); } diff --git a/src/nasal_ast.h b/src/nasal_ast.h index 73142c1..55e91e8 100644 --- a/src/nasal_ast.h +++ b/src/nasal_ast.h @@ -77,7 +77,7 @@ public: virtual void accept(ast_visitor*); }; -class call:public expr { +class call: public expr { public: call(const span& location, expr_type node_type): expr(location, node_type) {} @@ -85,7 +85,7 @@ public: virtual void accept(ast_visitor*); }; -class null_expr:public expr { +class null_expr: public expr { public: null_expr(const span& location): expr(location, expr_type::ast_null) {} @@ -93,7 +93,7 @@ public: void accept(ast_visitor*) override; }; -class nil_expr:public expr { +class nil_expr: public expr { public: nil_expr(const span& location): expr(location, expr_type::ast_nil) {} @@ -101,7 +101,7 @@ public: void accept(ast_visitor*) override; }; -class number_literal:public expr { +class number_literal: public expr { private: f64 number; @@ -113,7 +113,7 @@ public: void accept(ast_visitor*) override; }; -class string_literal:public expr { +class string_literal: public expr { private: std::string content; @@ -125,7 +125,7 @@ public: void accept(ast_visitor*) override; }; -class identifier:public expr { +class identifier: public expr { private: std::string name; @@ -137,7 +137,7 @@ public: void accept(ast_visitor*) override; }; -class bool_literal:public expr { +class bool_literal: public expr { private: bool flag; @@ -149,7 +149,7 @@ public: void accept(ast_visitor*) override; }; -class vector_expr:public expr { +class vector_expr: public expr { private: std::vector elements; @@ -162,7 +162,7 @@ public: void accept(ast_visitor*) override; }; -class hash_expr:public expr { +class hash_expr: public expr { private: std::vector members; @@ -175,7 +175,7 @@ public: void accept(ast_visitor*) override; }; -class hash_pair:public expr { +class hash_pair: public expr { private: std::string name; expr* value; @@ -192,7 +192,7 @@ public: void accept(ast_visitor*) override; }; -class function:public expr { +class function: public expr { private: std::vector parameter_list; code_block* block; @@ -209,7 +209,7 @@ public: void accept(ast_visitor*) override; }; -class code_block:public expr { +class code_block: public expr { private: std::vector expressions; @@ -222,7 +222,7 @@ public: void accept(ast_visitor*) override; }; -class parameter:public expr { +class parameter: public expr { public: enum class param_type { normal_parameter, @@ -249,7 +249,7 @@ public: void accept(ast_visitor*) override; }; -class ternary_operator:public expr { +class ternary_operator: public expr { private: expr* condition; expr* left; @@ -269,7 +269,7 @@ public: void accept(ast_visitor*) override; }; -class binary_operator:public expr { +class binary_operator: public expr { public: enum class binary_type { add, @@ -317,7 +317,7 @@ public: void accept(ast_visitor*) override; }; -class unary_operator:public expr { +class unary_operator: public expr { public: enum class unary_type { negative, @@ -344,7 +344,7 @@ public: void accept(ast_visitor*) override; }; -class call_expr:public expr { +class call_expr: public expr { private: expr* first; std::vector calls; @@ -361,7 +361,7 @@ public: void accept(ast_visitor*) override; }; -class call_hash:public call { +class call_hash: public call { private: std::string field; @@ -374,7 +374,7 @@ public: void accept(ast_visitor*) override; }; -class call_vector:public call { +class call_vector: public call { private: std::vector calls; @@ -387,7 +387,7 @@ public: void accept(ast_visitor*) override; }; -class call_function:public call { +class call_function: public call { private: std::vector args; @@ -400,7 +400,7 @@ public: void accept(ast_visitor*) override; }; -class slice_vector:public expr { +class slice_vector: public expr { private: expr* begin; expr* end; @@ -417,7 +417,7 @@ public: void accept(ast_visitor*) override; }; -class definition_expr:public expr { +class definition_expr: public expr { private: identifier* variable_name; multi_identifier* variables; @@ -441,7 +441,7 @@ public: void accept(ast_visitor*) override; }; -class assignment_expr:public expr { +class assignment_expr: public expr { public: enum class assign_type { equal, @@ -474,7 +474,7 @@ public: void accept(ast_visitor*) override; }; -class multi_identifier:public expr { +class multi_identifier: public expr { private: std::vector variables; @@ -487,7 +487,7 @@ public: void accept(ast_visitor*) override; }; -class tuple_expr:public expr { +class tuple_expr: public expr { private: std::vector elements; @@ -500,7 +500,7 @@ public: void accept(ast_visitor*) override; }; -class multi_assign:public expr { +class multi_assign: public expr { private: tuple_expr* tuple; expr* value; @@ -517,7 +517,7 @@ public: void accept(ast_visitor*) override; }; -class while_expr:public expr { +class while_expr: public expr { private: expr* condition; code_block* block; @@ -534,7 +534,7 @@ public: void accept(ast_visitor*) override; }; -class for_expr:public expr { +class for_expr: public expr { private: expr* initializing; expr* condition; @@ -558,7 +558,7 @@ public: void accept(ast_visitor*) override; }; -class iter_expr:public expr { +class iter_expr: public expr { private: identifier* name; call_expr* call; @@ -575,7 +575,7 @@ public: void accept(ast_visitor*) override; }; -class forei_expr:public expr { +class forei_expr: public expr { public: enum class forei_loop_type { foreach, @@ -605,7 +605,7 @@ public: void accept(ast_visitor*) override; }; -class condition_expr:public expr { +class condition_expr: public expr { private: if_expr* if_stmt; std::vector elsif_stmt; @@ -625,7 +625,7 @@ public: void accept(ast_visitor*) override; }; -class if_expr:public expr { +class if_expr: public expr { private: expr* condition; code_block* block; @@ -642,7 +642,7 @@ public: void accept(ast_visitor*) override; }; -class continue_expr:public expr { +class continue_expr: public expr { public: continue_expr(const span& location): expr(location, expr_type::ast_continue) {} @@ -650,7 +650,7 @@ public: void accept(ast_visitor*) override; }; -class break_expr:public expr { +class break_expr: public expr { public: break_expr(const span& location): expr(location, expr_type::ast_break) {} @@ -658,7 +658,7 @@ public: void accept(ast_visitor*) override; }; -class return_expr:public expr { +class return_expr: public expr { private: expr* value; diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 3f8eab8..6bdaf9c 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -632,9 +632,9 @@ var builtin_ghosttype(context* ctx, gc* ngc) { if (arg.type!=vm_obj) { return nas_err("ghosttype", "this is not a ghost object."); } - const auto& name = arg.obj().get_ghost_name(); + const auto& name = arg.ghost().get_ghost_name(); if (!name.length()) { - return var::num(reinterpret_cast(arg.obj().pointer)); + return var::num(reinterpret_cast(arg.ghost().pointer)); } return ngc->newstr(name); } diff --git a/src/nasal_dbg.cpp b/src/nasal_dbg.cpp index a4715cc..d6e4b59 100644 --- a/src/nasal_dbg.cpp +++ b/src/nasal_dbg.cpp @@ -160,7 +160,7 @@ void dbg::step_info() { begin = (ctx.pc>>3)==0? 0:((ctx.pc>>3)<<3); end = (1+(ctx.pc>>3))<<3; codestream::set(const_number, const_string, native_function.data(), files); - std::clog << "next bytecode:\n"; + std::clog << "\nnext bytecode:\n"; for(u32 i = begin; ictx; // set coroutine pointer - cort = &co; + cort = co; // set coroutine state to running cort->status = nas_co::status::running; } -void gc::ctxreserve() { +void gc::context_reserve() { // pc=0 means this coroutine is finished cort->status = running_context->pc? nas_co::status::suspended: diff --git a/src/nasal_gc.h b/src/nasal_gc.h index f5b4497..4ce39e7 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -88,8 +88,8 @@ public: void clear(); void info() const; var alloc(const u8); - void ctxchg(nas_co&); - void ctxreserve(); + void context_change(nas_co*); + void context_reserve(); public: var newstr(char c) { diff --git a/src/nasal_import.cpp b/src/nasal_import.cpp index 54f6f5d..3a5c2cf 100644 --- a/src/nasal_import.cpp +++ b/src/nasal_import.cpp @@ -1,6 +1,8 @@ #include "nasal_import.h" #include "symbol_finder.h" +#include + namespace nasal { linker::linker(): @@ -234,10 +236,14 @@ code_block* linker::import_nasal_lib() { // start importing... if (lex.scan(filename).geterr()) { - err.err("link", "error occurred when analysing library <" + filename + ">"); + err.err("link", + "error occurred when analysing library <" + filename + ">" + ); } if (par.compile(lex).geterr()) { - err.err("link", "error occurred when analysing library <" + filename + ">"); + err.err("link", + "error occurred when analysing library <" + filename + ">" + ); } auto tmp = par.swap(nullptr); @@ -245,41 +251,71 @@ code_block* linker::import_nasal_lib() { return load(tmp, find(filename)); } -std::string linker::generate_module_name(const std::string& filename) { - auto error_name = "error_generated@[" + filename + "]"; - auto pos = filename.find_last_of(".nas"); - if (pos==std::string::npos) { +std::string linker::generate_module_name(const std::string& file_path) { + auto error_name = "module@[" + file_path + "]"; + if (!file_path.length()) { return error_name; } - pos -= 4; - auto split_pos = filename.find_last_of("/"); - if (split_pos==std::string::npos) { - split_pos = filename.find_last_of("\\"); + + // check file suffix and get file suffix position + auto suffix_position = file_path.find(".nas"); + if (suffix_position==std::string::npos) { + err.warn("link", + "get invalid module name from <" + file_path + ">, " + + "will not be easily accessed. " + + "\".nas\" suffix is required." + ); + return error_name; } - auto res = split_pos==std::string::npos? - filename.substr(0, pos + 1): - filename.substr(split_pos + 1, pos - split_pos); - if (!res.length()) { - err.warn("link", "get empty module name from <" + filename + ">, " + - "will not be easily accessed."); + if (suffix_position+4!=file_path.length()) { + err.warn("link", + "get invalid module name from <" + file_path + ">, " + + "will not be easily accessed. " + + "only one \".nas\" suffix is required in the path." + ); + return error_name; } - if (res.length() && '0' <= res[0] && res[0] <= '9') { - err.warn("link", "get module <" + res + "> from <" + filename + ">, " + - "will not be easily accessed."); + + // only get the file name as module name, directory path is not included + auto split_position = file_path.find_last_of("/"); + // find "\\" in windows platform + if (split_position==std::string::npos) { + split_position = file_path.find_last_of("\\"); } - if (res.length() && res.find(".")!=std::string::npos) { - err.warn("link", "get module <" + res + "> from <" + filename + ">, " + - "will not be easily accessed."); + + // split file path to get module name + auto module_name = split_position==std::string::npos? + file_path.substr(0, suffix_position): + file_path.substr(split_position+1, suffix_position-split_position-1); + + // check validation of module name + if (!module_name.length()) { + err.warn("link", + "get empty module name from <" + file_path + ">, " + + "will not be easily accessed." + ); } - return res; + if (module_name.length() && '0' <= module_name[0] && module_name[0] <= '9') { + err.warn("link", + "get module <" + module_name + "> from <" + file_path + ">, " + + "will not be easily accessed." + ); + } + if (module_name.length() && module_name.find(".")!=std::string::npos) { + err.warn("link", + "get module <" + module_name + "> from <" + file_path + ">, " + + "will not be easily accessed." + ); + } + return module_name; } return_expr* linker::generate_module_return(code_block* block) { - auto sf = new symbol_finder; - auto res = new return_expr(block->get_location()); + auto finder = std::unique_ptr(new symbol_finder); + auto result = new return_expr(block->get_location()); auto value = new hash_expr(block->get_location()); - res->set_value(value); - for(const auto& i : sf->do_find(block)) { + result->set_value(value); + for(const auto& i : finder->do_find(block)) { auto pair = new hash_pair(block->get_location()); // do not export symbol begins with '_' if (i.name.length() && i.name[0]=='_') { @@ -289,8 +325,7 @@ return_expr* linker::generate_module_return(code_block* block) { pair->set_value(new identifier(block->get_location(), i.name)); value->add_member(pair); } - delete sf; - return res; + return result; } definition_expr* linker::generate_module_definition(code_block* block) { diff --git a/src/nasal_opcode.cpp b/src/nasal_opcode.cpp index 6977235..8d2478f 100644 --- a/src/nasal_opcode.cpp +++ b/src/nasal_opcode.cpp @@ -28,13 +28,13 @@ const char* opname[] = { }; void codestream::set( - const f64* num_buff, - const std::string* str_buff, - const nasal_builtin_table* native_table_ptr, + const f64* number_list, + const std::string* string_list, + const nasal_builtin_table* native_table, const std::string* file_list) { - nums = num_buff; - strs = str_buff; - natives = native_table_ptr; + const_number = number_list; + const_string = string_list; + natives = native_table; files = file_list; } @@ -62,24 +62,24 @@ void codestream::dump(std::ostream& out) const { case op_addeqc: case op_subeqc: case op_muleqc:case op_diveqc: out << hex << "0x" << num << dec - << " (" << nums[num] << ")"; break; + << " (" << const_number[num] << ")"; break; case op_lnkeqc: out << hex << "0x" << num << dec - << " (" << rawstr(strs[num], 16) << ")"; break; + << " (" << rawstr(const_string[num], 16) << ")"; break; case op_addecp: case op_subecp: case op_mulecp: case op_divecp: out << hex << "0x" << num << dec - << " (" << nums[num] << ") sp-1"; break; + << " (" << const_number[num] << ") sp-1"; break; case op_lnkecp: out << hex << "0x" << num << dec - << " (" << rawstr(strs[num], 16) << ") sp-1"; break; + << " (" << rawstr(const_string[num], 16) << ") sp-1"; break; case op_addc: case op_subc: case op_mulc: case op_divc: case op_lessc: case op_leqc: case op_grtc: case op_geqc: case op_pnum: out << hex << "0x" << num << dec - << " (" << nums[num] << ")"; break; + << " (" << const_number[num] << ")"; break; case op_callvi: case op_newv: case op_callfv: case op_repl: case op_intl: case op_findex: @@ -103,7 +103,7 @@ void codestream::dump(std::ostream& out) const { case op_mcallh: case op_para: case op_deft: case op_dyn: out << hex << "0x" << num << dec - << " (" << rawstr(strs[num], 16) << ")"; break; + << " (" << rawstr(const_string[num], 16) << ")"; break; default: if (files) { out << hex << "0x" << num << dec; diff --git a/src/nasal_opcode.h b/src/nasal_opcode.h index 98e2459..bc31742 100644 --- a/src/nasal_opcode.h +++ b/src/nasal_opcode.h @@ -111,8 +111,8 @@ class codestream { private: opcode code; const u32 index; - inline static const f64* nums = nullptr; - inline static const std::string* strs = nullptr; + inline static const f64* const_number = nullptr; + inline static const std::string* const_string = nullptr; inline static const nasal_builtin_table* natives = nullptr; inline static const std::string* files = nullptr; diff --git a/src/nasal_type.cpp b/src/nasal_type.cpp index 15a6993..de42e25 100644 --- a/src/nasal_type.cpp +++ b/src/nasal_type.cpp @@ -2,20 +2,20 @@ namespace nasal { -var nas_vec::get_value(const i32 n) { +var nas_vec::get_value(const i32 index) { i32 size = elems.size(); - if (n<-size || n>=size) { + if (index<-size || index>=size) { return var::none(); } - return elems[n>=0? n:n+size]; + return elems[index>=0? index:index+size]; } -var* nas_vec::get_memory(const i32 n) { +var* nas_vec::get_memory(const i32 index) { i32 size = elems.size(); - if (n<-size || n>=size) { + if (index<-size || index>=size) { return nullptr; } - return &elems[n>=0? n:n+size]; + return &elems[index>=0? index:index+size]; } std::ostream& operator<<(std::ostream& out, nas_vec& vec) { @@ -194,41 +194,41 @@ nas_val::nas_val(u8 val_type) { type = val_type; unmutable = 0; switch(val_type) { - case vm_str: ptr.str = new std::string; break; - case vm_vec: ptr.vec = new nas_vec; break; - case vm_hash: ptr.hash = new nas_hash; break; - case vm_func: ptr.func = new nas_func; break; + case vm_str: ptr.str = new std::string; break; + case vm_vec: ptr.vec = new nas_vec; break; + case vm_hash: ptr.hash = new nas_hash; break; + case vm_func: ptr.func = new nas_func; break; case vm_upval: ptr.upval = new nas_upval; break; - case vm_obj: ptr.obj = new nas_ghost; break; - case vm_co: ptr.co = new nas_co; break; - case vm_map: ptr.map = new nas_map; break; + case vm_obj: ptr.obj = new nas_ghost; break; + case vm_co: ptr.co = new nas_co; break; + case vm_map: ptr.map = new nas_map; break; } } nas_val::~nas_val() { switch(type) { - case vm_str: delete ptr.str; break; - case vm_vec: delete ptr.vec; break; - case vm_hash: delete ptr.hash; break; - case vm_func: delete ptr.func; break; - case vm_upval:delete ptr.upval;break; - case vm_obj: delete ptr.obj; break; - case vm_co: delete ptr.co; break; - case vm_map: delete ptr.map; break; + case vm_str: delete ptr.str; break; + case vm_vec: delete ptr.vec; break; + case vm_hash: delete ptr.hash; break; + case vm_func: delete ptr.func; break; + case vm_upval:delete ptr.upval; break; + case vm_obj: delete ptr.obj; break; + case vm_co: delete ptr.co; break; + case vm_map: delete ptr.map; break; } type=vm_nil; } void nas_val::clear() { switch(type) { - case vm_str: ptr.str->clear(); break; - case vm_vec: ptr.vec->elems.clear(); break; - case vm_hash: ptr.hash->elems.clear();break; - case vm_func: ptr.func->clear(); break; - case vm_upval:ptr.upval->clear(); break; - case vm_obj: ptr.obj->clear(); break; - case vm_co: ptr.co->clear(); break; - case vm_map: ptr.map->clear(); break; + case vm_str: ptr.str->clear(); break; + case vm_vec: ptr.vec->elems.clear(); break; + case vm_hash: ptr.hash->elems.clear(); break; + case vm_func: ptr.func->clear(); break; + case vm_upval:ptr.upval->clear(); break; + case vm_obj: ptr.obj->clear(); break; + case vm_co: ptr.co->clear(); break; + case vm_map: ptr.map->clear(); break; } } @@ -240,7 +240,7 @@ std::string var::to_str() { if (type==vm_str) { return str(); } else if (type==vm_num) { - std::string tmp=std::to_string(num()); + std::string tmp = std::to_string(num()); tmp.erase(tmp.find_last_not_of('0')+1, std::string::npos); tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos); return tmp; @@ -257,7 +257,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) { case vm_vec: out << ref.vec(); break; case vm_hash: out << ref.hash(); break; case vm_func: out << "func(..) {..}"; break; - case vm_obj: out << ref.obj(); break; + case vm_obj: out << ref.ghost(); break; case vm_co: out << ref.co(); break; case vm_map: out << ref.map(); break; } @@ -265,7 +265,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) { } bool var::object_check(const std::string& name) { - return type==vm_obj && obj().type_name==name && obj().pointer; + return type==vm_obj && ghost().type_name==name && ghost().pointer; } var var::none() { @@ -300,7 +300,7 @@ var* var::addr() { return val.addr; } -u32 var::ret() { +u32 var::ret() const { return val.ret; } @@ -308,7 +308,7 @@ i64& var::cnt() { return val.cnt; } -f64 var::num() { +f64 var::num() const { return val.num; } @@ -332,7 +332,7 @@ nas_upval& var::upval() { return *val.gcobj->ptr.upval; } -nas_ghost& var::obj() { +nas_ghost& var::ghost() { return *val.gcobj->ptr.obj; } diff --git a/src/nasal_type.h b/src/nasal_type.h index 37d7cf7..8bb589b 100644 --- a/src/nasal_type.h +++ b/src/nasal_type.h @@ -23,11 +23,13 @@ enum vm_type:u8 { vm_upval, // upvalue vm_obj, // ghost type vm_co, // coroutine - vm_map // for globals and namespaces + vm_map, // for globals and namespaces + /* mark type range */ + vm_type_size_max }; // size of gc object type -const u32 gc_type_size = vm_map-vm_str+1; +const u32 gc_type_size = vm_type_size_max-vm_str; // basic types struct nas_vec; // vector @@ -85,15 +87,15 @@ public: // get value var* addr(); - u32 ret(); + u32 ret() const; i64& cnt(); - f64 num(); + f64 num() const; std::string& str(); nas_vec& vec(); nas_hash& hash(); nas_func& func(); nas_upval& upval(); - nas_ghost& obj(); + nas_ghost& ghost(); nas_co& co(); nas_map& map(); }; diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index bc943ca..5b2bf10 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -93,7 +93,7 @@ void vm::value_info(var& val) { << " val}"; break; case vm_obj: std::clog << "| obj | <0x" << std::hex << p << "> obj:0x" - << reinterpret_cast(val.obj().pointer) + << reinterpret_cast(val.ghost().pointer) << std::dec; break; case vm_co: std::clog << "| co | <0x" << std::hex << p << std::dec << "> coroutine"; break; @@ -170,12 +170,12 @@ void vm::function_call_trace() { } void vm::trace_back() { - var* bottom = ctx.stack; - var* top = ctx.top; + // var* bottom = ctx.stack; + // var* top = ctx.top; // generate trace back std::stack ret; - for(var* i = bottom; i<=top; ++i) { + for(var* i = ctx.stack; i<=ctx.top; ++i) { if (i->type==vm_ret && i->ret()!=0) { ret.push(i->ret()); } @@ -401,7 +401,7 @@ void vm::die(const std::string& str) { } else { // in coroutine, shut down the coroutine and return to main context ctx.pc = 0; // mark coroutine 'dead' - ngc.ctxreserve(); // switch context to main + ngc.context_reserve(); // switch context to main ctx.top[0] = nil; // generate return value 'nil' } } diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 481627c..45ca5a3 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -1024,7 +1024,7 @@ inline void vm::o_ret() { // because there maybe another function call inside but return here // coroutine function ends with setting pc to 0 if (!ctx.pc) { - ngc.ctxreserve(); + ngc.context_reserve(); } } diff --git a/src/unix_lib.cpp b/src/unix_lib.cpp index 32e5f5f..eb37b4d 100644 --- a/src/unix_lib.cpp +++ b/src/unix_lib.cpp @@ -73,7 +73,7 @@ var builtin_opendir(context* ctx, gc* ngc) { } #endif var ret = ngc->alloc(vm_obj); - ret.obj().set(dir_type_name, dir_entry_destructor, p); + ret.ghost().set(dir_type_name, dir_entry_destructor, p); return ret; } @@ -84,12 +84,12 @@ var builtin_readdir(context* ctx, gc* ngc) { } #ifdef _MSC_VER WIN32_FIND_DATAA data; - if (!FindNextFileA(handle.obj().pointer, &data)) { + if (!FindNextFileA(handle.ghost().pointer, &data)) { return nil; } return ngc->newstr(data.cFileName); #else - dirent* p = readdir(static_cast(handle.obj().pointer)); + dirent* p = readdir(static_cast(handle.ghost().pointer)); return p? ngc->newstr(p->d_name):nil; #endif } @@ -99,7 +99,7 @@ var builtin_closedir(context* ctx, gc* ngc) { if (!handle.object_check(dir_type_name)) { return nas_err("unix::closedir", "not a valid dir handle"); } - handle.obj().clear(); + handle.ghost().clear(); return nil; } diff --git a/test/flush_screen.nas b/test/flush_screen.nas index 231bfda..2c24113 100644 --- a/test/flush_screen.nas +++ b/test/flush_screen.nas @@ -24,5 +24,5 @@ while(1) { res ~= "\n"; } print(res); - unix.sleep(1/20); + unix.sleep(1/15); }