diff --git a/src/nasal_type.cpp b/src/nasal_type.cpp index 8a38b11..561f68c 100644 --- a/src/nasal_type.cpp +++ b/src/nasal_type.cpp @@ -6,22 +6,6 @@ namespace nasal { -var nas_vec::get_value(const i32 index) { - i32 size = elems.size(); - if (index<-size || index>=size) { - return var::none(); - } - return elems[index>=0? index:index+size]; -} - -var* nas_vec::get_memory(const i32 index) { - i32 size = elems.size(); - if (index<-size || index>=size) { - return nullptr; - } - return &elems[index>=0? index:index+size]; -} - std::ostream& operator<<(std::ostream& out, nas_vec& vec) { if (!vec.elems.size() || vec.printed) { out << (vec.elems.size()? "[..]":"[]"); @@ -40,7 +24,8 @@ std::ostream& operator<<(std::ostream& out, nas_vec& vec) { var nas_hash::get_value(const std::string& key) { if (elems.count(key)) { return elems.at(key); - } else if (!elems.count("parents")) { + } + if (!elems.count("parents")) { return var::none(); } @@ -63,7 +48,8 @@ var nas_hash::get_value(const std::string& key) { var* nas_hash::get_memory(const std::string& key) { if (elems.count(key)) { return &elems.at(key); - } else if (!elems.count("parents")) { + } + if (!elems.count("parents")) { return nullptr; } @@ -279,12 +265,6 @@ void nas_val::clear() { } } -f64 var::to_num() const { - return type != vm_type::vm_str - ? val.num - : util::str_to_num(str().c_str()); -} - std::string var::to_str() { if (type==vm_type::vm_str) { return str(); diff --git a/src/nasal_type.h b/src/nasal_type.h index 3c240d5..fb283ed 100644 --- a/src/nasal_type.h +++ b/src/nasal_type.h @@ -1,6 +1,7 @@ #pragma once #include "nasal.h" +#include "util/util.h" #include #include @@ -173,8 +174,13 @@ public: bool is_map() const { return type == vm_type::vm_map; } public: - // number and string can be translated to each other - f64 to_num() const; + // convert to number + f64 to_num() const { + return type != vm_type::vm_str + ? val.num + : util::str_to_num(str().c_str()); + } + // convert to string std::string to_str(); inline bool object_check(const std::string&) const; friend std::ostream& operator<<(std::ostream&, var&); @@ -187,8 +193,20 @@ struct nas_vec { bool printed = false; auto size() const { return elems.size(); } - var get_value(const i32); - var* get_memory(const i32); + var get_value(const i32 index) { + i32 size = elems.size(); + if (index < -size || index >= size) { + return var::none(); + } + return elems[index >= 0 ? index : index + size]; + } + var* get_memory(const i32 index) { + i32 size = elems.size(); + if (index < -size || index >= size) { + return nullptr; + } + return &elems[index >= 0 ? index : index + size]; + } friend std::ostream& operator<<(std::ostream&, nas_vec&); }; diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 62c1f87..312d031 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -97,6 +97,7 @@ protected: protected: /* vm calculation functions*/ inline bool boolify(const var&); + inline void set_frame(const nas_func&, var*); protected: /* vm operands */ @@ -342,6 +343,15 @@ inline bool vm::boolify(const var& val) { return false; } +inline void vm::set_frame(const nas_func& func, var* local) { + ctx.top[0] = ctx.upvalr; + (++ctx.top)[0] = var::addr(ctx.localr); + (++ctx.top)[0] = var::ret(ctx.pc); // rewrite top with vm_ret + ctx.pc = func.entry - 1; + ctx.localr = local; + ctx.upvalr = nil; +} + inline void vm::o_repl() { // reserved for repl mode stack top value output if (allow_repl_output) { @@ -935,12 +945,7 @@ inline void vm::o_callfv() { ? parameter_size + 1 : func.local_size - 1] = dynamic; - ctx.top[0] = ctx.upvalr; - (++ctx.top)[0] = var::addr(ctx.localr); - (++ctx.top)[0] = var::ret(ctx.pc); - ctx.pc = func.entry-1; - ctx.localr = local; - ctx.upvalr = nil; + set_frame(func, local); } inline void vm::o_callfh() { @@ -987,12 +992,7 @@ inline void vm::o_callfh() { return; } - ctx.top[0] = ctx.upvalr; - (++ctx.top)[0] = var::addr(ctx.localr); - (++ctx.top)[0] = var::ret(ctx.pc); // rewrite top with vm_ret - ctx.pc=func.entry-1; - ctx.localr = local; - ctx.upvalr = nil; + set_frame(func, local); } inline void vm::o_callb() { diff --git a/src/natives/dylib_lib.cpp b/src/natives/dylib_lib.cpp index d405974..61e1002 100644 --- a/src/natives/dylib_lib.cpp +++ b/src/natives/dylib_lib.cpp @@ -18,35 +18,64 @@ void dynamic_library_destructor(void* pointer) { #endif } +std::vector possible_dylib_path() { + const auto env_path = std::string(getenv("PATH")); + const auto sep = (util::is_windows()? ";":":"); + const auto path_front = util::is_windows()? "\\module\\":"/module/"; + + // do split string + std::vector env_path_vec = {"."}; + usize last = 0; + usize pos = env_path.find(sep, 0); + while(pos != std::string::npos) { + if (pos > last) { + env_path_vec.push_back(env_path.substr(last, pos - last)); + } + last = pos + 1; + pos = env_path.find(sep, last); + } + if (last != env_path.length()) { + env_path_vec.push_back(env_path.substr(last)); + } + + for (auto& p : env_path_vec) { + p += path_front; + } + + return env_path_vec; +} + std::string search_dynamic_library_path(const std::string& dlname) { const auto ext = (util::is_windows()? ".dll":".so"); const auto lib_path = (util::is_windows()? ".\\":"./") + dlname + ext; if (fs::exists(lib_path)) { return lib_path; } - const auto env_path = std::string(getenv("PATH")); - const auto sep = (util::is_windows()? ";":":"); - - // do split string - std::vector env_path_vec = {"."}; - usize last = 0; - usize pos = env_path.find(sep, 0); - while(pos!=std::string::npos) { - if (pos>last) { - env_path_vec.push_back(env_path.substr(last, pos-last)); + // macos may use .dylib as extension + if (util::is_macos()) { + const auto dylib_path = "./" + dlname + ".dylib"; + if (fs::exists(dylib_path)) { + return dylib_path; } - last = pos + 1; - pos = env_path.find(sep, last); - } - if (last!=env_path.length()) { - env_path_vec.push_back(env_path.substr(last)); } - const auto path_front = util::is_windows()? "\\module\\":"/module/"; - for(auto& p : env_path_vec) { - p += path_front + lib_path; - if (fs::exists(p)) { - return p; + // search library in PATH + const auto possible_path = possible_dylib_path(); + for(const auto& p : possible_path) { + const auto env_p = p + lib_path; + if (fs::exists(env_p)) { + return env_p; + } + } + + // macos may use .dylib as extension + if (util::is_macos()) { + const auto dylib_path = "./" + dlname + ".dylib"; + for(const auto& p : possible_path) { + const auto env_p = p + dylib_path; + if (fs::exists(env_p)) { + return env_p; + } } } return ""; @@ -61,7 +90,7 @@ var builtin_dlopen(context* ctx, gc* ngc) { const auto dlname = search_dynamic_library_path(dl.str()); if (dlname.empty()) { return nas_err("dylib::dlopen", - "cannot find dynamic lib <" + dl.str() + ">" + "cannot find dynamic library <" + dl.str() + ">" ); } diff --git a/src/natives/dylib_lib.h b/src/natives/dylib_lib.h index 67a9ef0..c4ae80f 100644 --- a/src/natives/dylib_lib.h +++ b/src/natives/dylib_lib.h @@ -13,11 +13,13 @@ #include #include +#include namespace nasal { void dynamic_library_destructor(void*); +std::vector possible_dylib_path(); std::string search_dynamic_library_path(const std::string&); var builtin_dlopen(context*, gc*);