Merge pull request #57 from ValKmjolnir/develop
🐛 fix boolify result issue
This commit is contained in:
commit
9cbefa1003
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
10
src/nasal.h
10
src/nasal.h
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
104
src/nasal_type.h
104
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 @@ 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&);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue