Merge pull request #57 from ValKmjolnir/develop

🐛 fix boolify result issue
This commit is contained in:
ValK 2024-12-11 20:56:23 +08:00 committed by GitHub
commit 9cbefa1003
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 93 additions and 124 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,7 +1,7 @@
#pragma once
#ifndef __nasver__
#define __nasver__ "11.3"
#define __nasver__ "11.3.1"
#endif
#include <cstddef>
@ -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

View File

@ -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
}

View File

@ -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();

View File

@ -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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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&);

View File

@ -96,7 +96,7 @@ protected:
protected:
/* vm calculation functions*/
inline bool cond(var&);
inline bool boolify(const var&);
protected:
/* vm operands */
@ -320,12 +320,20 @@ public:
}
};
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;

View File

@ -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