diff --git a/module/fib.cpp b/module/fib.cpp index 36cee414..99f23412 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -124,7 +124,7 @@ module_func_info func_tbl[] = { } -NASAL_EXTERN module_func_info* get() { +NASAL_EXPORT module_func_info* get() { return fib_module::func_tbl; } diff --git a/module/keyboard.cpp b/module/keyboard.cpp index 875ed9af..33e830ee 100644 --- a/module/keyboard.cpp +++ b/module/keyboard.cpp @@ -111,7 +111,7 @@ module_func_info func_tbl[] = { {nullptr, nullptr} }; -NASAL_EXTERN module_func_info* get() { +NASAL_EXPORT module_func_info* get() { return func_tbl; } diff --git a/module/matrix.cpp b/module/matrix.cpp index 3108427a..7485f0a7 100644 --- a/module/matrix.cpp +++ b/module/matrix.cpp @@ -295,7 +295,7 @@ module_func_info func_tbl[] = { {nullptr, nullptr} }; -NASAL_EXTERN module_func_info* get() { +NASAL_EXPORT module_func_info* get() { return func_tbl; } diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 41f843c1..3c1ace48 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -262,7 +262,7 @@ module_func_info func_tbl[] = { {nullptr, nullptr} }; -NASAL_EXTERN module_func_info* get() { +NASAL_EXPORT module_func_info* get() { return func_tbl; } diff --git a/src/nasal.h b/src/nasal.h index fb5ed9ff..4e869144 100644 --- a/src/nasal.h +++ b/src/nasal.h @@ -1,7 +1,7 @@ #pragma once #ifndef __nasver__ -#define __nasver__ "11.3" +#define __nasver__ "11.3.1" #endif #include @@ -19,3 +19,11 @@ using f64 = double; // virtual machine stack depth, both global depth and value stack depth const u32 VM_STACK_DEPTH = UINT16_MAX; + +// avoid error loading function bug in MSVC version nasal.exe +#ifdef _MSC_VER + // and fuck MSVC again + #define NASAL_EXPORT extern "C" __declspec(dllexport) +#else + #define NASAL_EXPORT extern "C" __attribute__((visibility("default"))) +#endif diff --git a/src/nasal_gc.h b/src/nasal_gc.h index 399773e3..5312d60c 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -126,13 +126,4 @@ struct module_func_info { // module function "get" type typedef module_func_info* (*get_func_ptr)(); - -// avoid error loading function bug in MSVC version nasal.exe -#ifdef _MSC_VER - // and fuck MSVC again - #define NASAL_EXTERN extern "C" __declspec(dllexport) -#else - #define NASAL_EXTERN extern "C" -#endif - } diff --git a/src/nasal_type.cpp b/src/nasal_type.cpp index 0df7ff3f..588fbc2a 100644 --- a/src/nasal_type.cpp +++ b/src/nasal_type.cpp @@ -279,8 +279,10 @@ void nas_val::clear() { } } -f64 var::to_num() { - return type!=vm_type::vm_str? val.num:util::str_to_num(str().c_str()); +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() { @@ -288,8 +290,8 @@ std::string var::to_str() { return str(); } else if (type==vm_type::vm_num) { auto 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); + 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; } @@ -315,8 +317,8 @@ std::ostream& operator<<(std::ostream& out, var& ref) { return out; } -bool var::object_check(const std::string& name) { - return is_ghost() && ghost().type_name==name && ghost().pointer; +bool var::object_check(const std::string& name) const { + return is_ghost() && ghost().type_name == name && ghost().pointer; } var var::none() { @@ -347,54 +349,6 @@ var var::addr(var* p) { return {vm_type::vm_addr, p}; } -var* var::addr() const { - return val.addr; -} - -u64 var::ret() const { - return val.ret; -} - -i64& var::cnt() { - return val.cnt; -} - -f64 var::num() const { - return val.num; -} - -std::string& var::str() { - return *val.gcobj->ptr.str; -} - -nas_vec& var::vec() { - return *val.gcobj->ptr.vec; -} - -nas_hash& var::hash() { - return *val.gcobj->ptr.hash; -} - -nas_func& var::func() { - return *val.gcobj->ptr.func; -} - -nas_upval& var::upval() { - return *val.gcobj->ptr.upval; -} - -nas_ghost& var::ghost() { - return *val.gcobj->ptr.obj; -} - -nas_co& var::co() { - return *val.gcobj->ptr.co; -} - -nas_map& var::map() { - return *val.gcobj->ptr.map; -} - var nas_err(const std::string& error_function_name, const std::string& info) { std::cerr << "[vm] " << error_function_name << ": " << info << "\n"; return var::none(); diff --git a/src/nasal_type.h b/src/nasal_type.h index f3e45c4f..029f9dac 100644 --- a/src/nasal_type.h +++ b/src/nasal_type.h @@ -47,8 +47,32 @@ struct nas_ghost; // objects struct nas_co; // coroutine struct nas_map; // mapper -// union type -struct nas_val; // nas_val includes gc-managed types +// nas_val includes gc-managed types +struct nas_val { + enum class gc_status: u8 { + uncollected = 0, + collected, + found + }; + + gc_status mark; + vm_type type; // value type + u8 immutable; // used to mark if a string is immutable + union elem { + std::string* str; + nas_vec* vec; + nas_hash* hash; + nas_func* func; + nas_upval* upval; + nas_ghost* obj; + nas_co* co; + nas_map* map; + } ptr; + + nas_val(vm_type); + ~nas_val(); + void clear(); +}; struct var { public: @@ -78,11 +102,6 @@ struct var { return type!=nr.type || val.gcobj!=nr.val.gcobj; } - // number and string can be translated to each other - f64 to_num(); - std::string to_str(); - bool object_check(const std::string&); - public: // create new var object static var none(); @@ -95,18 +114,33 @@ struct var { public: // get value - var* addr() const; - u64 ret() const; - i64& cnt(); - f64 num() const; - std::string& str(); - nas_vec& vec(); - nas_hash& hash(); - nas_func& func(); - nas_upval& upval(); - nas_ghost& ghost(); - nas_co& co(); - nas_map& map(); + var* addr() const { return val.addr; } + u64 ret() const { return val.ret; } + i64& cnt() { return val.cnt; } + f64 num() const { return val.num; } + +public: + // get gc object + std::string& str() { return *val.gcobj->ptr.str; } + nas_vec& vec() { return *val.gcobj->ptr.vec; } + nas_hash& hash() { return *val.gcobj->ptr.hash; } + nas_func& func() { return *val.gcobj->ptr.func; } + nas_upval& upval() { return *val.gcobj->ptr.upval; } + nas_ghost& ghost() { return *val.gcobj->ptr.obj; } + nas_co& co() { return *val.gcobj->ptr.co; } + nas_map& map() { return *val.gcobj->ptr.map; } + + +public: + // get const gc object + const std::string& str() const { return *val.gcobj->ptr.str; } + const nas_vec& vec() const { return *val.gcobj->ptr.vec; } + const nas_hash& hash() const { return *val.gcobj->ptr.hash; } + const nas_func& func() const { return *val.gcobj->ptr.func; } + const nas_upval& upval() const { return *val.gcobj->ptr.upval; } + const nas_ghost& ghost() const { return *val.gcobj->ptr.obj; } + const nas_co& co() const { return *val.gcobj->ptr.co; } + const nas_map& map() const { return *val.gcobj->ptr.map; } public: bool is_none() const { return type==vm_type::vm_none; } @@ -123,6 +157,12 @@ struct var { bool is_ghost() const { return type==vm_type::vm_ghost; } bool is_coroutine() const { return type==vm_type::vm_co; } bool is_map() const { return type==vm_type::vm_map; } + +public: + // number and string can be translated to each other + f64 to_num() const; + std::string to_str(); + bool object_check(const std::string&) const; }; struct nas_vec { @@ -266,32 +306,6 @@ struct nas_map { var* get_memory(const std::string&); }; -struct nas_val { - enum class gc_status: u8 { - uncollected = 0, - collected, - found - }; - - gc_status mark; - vm_type type; // value type - u8 immutable; // used to mark if a string is immutable - union { - std::string* str; - nas_vec* vec; - nas_hash* hash; - nas_func* func; - nas_upval* upval; - nas_ghost* obj; - nas_co* co; - nas_map* map; - } ptr; - - nas_val(vm_type); - ~nas_val(); - void clear(); -}; - std::ostream& operator<<(std::ostream&, nas_vec&); std::ostream& operator<<(std::ostream&, nas_hash&); std::ostream& operator<<(std::ostream&, nas_func&); diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 1ea2444a..0829bce0 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -96,7 +96,7 @@ class vm { protected: /* vm calculation functions*/ - inline bool cond(var&); + inline bool boolify(const var&); protected: /* vm operands */ @@ -320,12 +320,20 @@ class vm { } }; -inline bool vm::cond(var& val) { +inline bool vm::boolify(const var& val) { if (val.is_num()) { return val.num(); } else if (val.is_str()) { const f64 num = util::str_to_num(val.str().c_str()); - return std::isnan(num)? !val.str().empty():num; + return std::isnan(num)? !val.str().empty() : num; + } else if (val.is_vec()) { + return val.vec().size() > 0; + } else if (val.is_hash()) { + return val.hash().size() > 0; + } else if (val.is_func() || val.is_ghost() || val.is_coroutine()) { + return true; + } else if (val.is_map()) { + return val.map().size() > 0; } return false; } @@ -707,14 +715,14 @@ inline void vm::o_jmp() { inline void vm::o_jt() { // jump true needs to reserve the result on stack // because conditional expression in nasal has return value - if (cond(ctx.top[0])) { + if (boolify(ctx.top[0])) { ctx.pc = imm[ctx.pc]-1; } } inline void vm::o_jf() { // jump false doesn't need to reserve result - if (!cond(ctx.top[0])) { + if (!boolify(ctx.top[0])) { ctx.pc = imm[ctx.pc]-1; } --ctx.top; diff --git a/src/nasal_web.h b/src/nasal_web.h index 3bc7d98f..8de3ee88 100644 --- a/src/nasal_web.h +++ b/src/nasal_web.h @@ -3,12 +3,6 @@ #include "nasal.h" -#ifdef _WIN32 - #define NASAL_EXPORT __declspec(dllexport) -#else - #define NASAL_EXPORT __attribute__((visibility("default"))) -#endif - #ifdef __cplusplus extern "C" { #endif