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;
|
return fib_module::func_tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ module_func_info func_tbl[] = {
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
NASAL_EXTERN module_func_info* get() {
|
NASAL_EXPORT module_func_info* get() {
|
||||||
return func_tbl;
|
return func_tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ module_func_info func_tbl[] = {
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
NASAL_EXTERN module_func_info* get() {
|
NASAL_EXPORT module_func_info* get() {
|
||||||
return func_tbl;
|
return func_tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,7 @@ module_func_info func_tbl[] = {
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
NASAL_EXTERN module_func_info* get() {
|
NASAL_EXPORT module_func_info* get() {
|
||||||
return func_tbl;
|
return func_tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/nasal.h
10
src/nasal.h
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef __nasver__
|
#ifndef __nasver__
|
||||||
#define __nasver__ "11.3"
|
#define __nasver__ "11.3.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -19,3 +19,11 @@ using f64 = double;
|
||||||
|
|
||||||
// virtual machine stack depth, both global depth and value stack depth
|
// virtual machine stack depth, both global depth and value stack depth
|
||||||
const u32 VM_STACK_DEPTH = UINT16_MAX;
|
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
|
// module function "get" type
|
||||||
typedef module_func_info* (*get_func_ptr)();
|
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() {
|
f64 var::to_num() const {
|
||||||
return type!=vm_type::vm_str? val.num:util::str_to_num(str().c_str());
|
return type != vm_type::vm_str
|
||||||
|
? val.num
|
||||||
|
: util::str_to_num(str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string var::to_str() {
|
std::string var::to_str() {
|
||||||
|
@ -288,8 +290,8 @@ std::string var::to_str() {
|
||||||
return str();
|
return str();
|
||||||
} else if (type==vm_type::vm_num) {
|
} else if (type==vm_type::vm_num) {
|
||||||
auto tmp = std::to_string(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('0') + 1, std::string::npos);
|
||||||
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
|
tmp.erase(tmp.find_last_not_of('.') + 1, std::string::npos);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,8 +317,8 @@ std::ostream& operator<<(std::ostream& out, var& ref) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool var::object_check(const std::string& name) {
|
bool var::object_check(const std::string& name) const {
|
||||||
return is_ghost() && ghost().type_name==name && ghost().pointer;
|
return is_ghost() && ghost().type_name == name && ghost().pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
var var::none() {
|
var var::none() {
|
||||||
|
@ -347,54 +349,6 @@ var var::addr(var* p) {
|
||||||
return {vm_type::vm_addr, 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) {
|
var nas_err(const std::string& error_function_name, const std::string& info) {
|
||||||
std::cerr << "[vm] " << error_function_name << ": " << info << "\n";
|
std::cerr << "[vm] " << error_function_name << ": " << info << "\n";
|
||||||
return var::none();
|
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_co; // coroutine
|
||||||
struct nas_map; // mapper
|
struct nas_map; // mapper
|
||||||
|
|
||||||
// union type
|
// nas_val includes gc-managed types
|
||||||
struct nas_val; // 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 {
|
struct var {
|
||||||
public:
|
public:
|
||||||
|
@ -78,11 +102,6 @@ public:
|
||||||
return type!=nr.type || val.gcobj!=nr.val.gcobj;
|
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:
|
public:
|
||||||
// create new var object
|
// create new var object
|
||||||
static var none();
|
static var none();
|
||||||
|
@ -95,18 +114,33 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// get value
|
// get value
|
||||||
var* addr() const;
|
var* addr() const { return val.addr; }
|
||||||
u64 ret() const;
|
u64 ret() const { return val.ret; }
|
||||||
i64& cnt();
|
i64& cnt() { return val.cnt; }
|
||||||
f64 num() const;
|
f64 num() const { return val.num; }
|
||||||
std::string& str();
|
|
||||||
nas_vec& vec();
|
public:
|
||||||
nas_hash& hash();
|
// get gc object
|
||||||
nas_func& func();
|
std::string& str() { return *val.gcobj->ptr.str; }
|
||||||
nas_upval& upval();
|
nas_vec& vec() { return *val.gcobj->ptr.vec; }
|
||||||
nas_ghost& ghost();
|
nas_hash& hash() { return *val.gcobj->ptr.hash; }
|
||||||
nas_co& co();
|
nas_func& func() { return *val.gcobj->ptr.func; }
|
||||||
nas_map& map();
|
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:
|
public:
|
||||||
bool is_none() const { return type==vm_type::vm_none; }
|
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_ghost() const { return type==vm_type::vm_ghost; }
|
||||||
bool is_coroutine() const { return type==vm_type::vm_co; }
|
bool is_coroutine() const { return type==vm_type::vm_co; }
|
||||||
bool is_map() const { return type==vm_type::vm_map; }
|
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 {
|
struct nas_vec {
|
||||||
|
@ -266,32 +306,6 @@ public:
|
||||||
var* get_memory(const std::string&);
|
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_vec&);
|
||||||
std::ostream& operator<<(std::ostream&, nas_hash&);
|
std::ostream& operator<<(std::ostream&, nas_hash&);
|
||||||
std::ostream& operator<<(std::ostream&, nas_func&);
|
std::ostream& operator<<(std::ostream&, nas_func&);
|
||||||
|
|
|
@ -96,7 +96,7 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* vm calculation functions*/
|
/* vm calculation functions*/
|
||||||
inline bool cond(var&);
|
inline bool boolify(const var&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* vm operands */
|
/* vm operands */
|
||||||
|
@ -320,12 +320,20 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool vm::cond(var& val) {
|
inline bool vm::boolify(const var& val) {
|
||||||
if (val.is_num()) {
|
if (val.is_num()) {
|
||||||
return val.num();
|
return val.num();
|
||||||
} else if (val.is_str()) {
|
} else if (val.is_str()) {
|
||||||
const f64 num = util::str_to_num(val.str().c_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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -707,14 +715,14 @@ inline void vm::o_jmp() {
|
||||||
inline void vm::o_jt() {
|
inline void vm::o_jt() {
|
||||||
// jump true needs to reserve the result on stack
|
// jump true needs to reserve the result on stack
|
||||||
// because conditional expression in nasal has return value
|
// because conditional expression in nasal has return value
|
||||||
if (cond(ctx.top[0])) {
|
if (boolify(ctx.top[0])) {
|
||||||
ctx.pc = imm[ctx.pc]-1;
|
ctx.pc = imm[ctx.pc]-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void vm::o_jf() {
|
inline void vm::o_jf() {
|
||||||
// jump false doesn't need to reserve result
|
// 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.pc = imm[ctx.pc]-1;
|
||||||
}
|
}
|
||||||
--ctx.top;
|
--ctx.top;
|
||||||
|
|
|
@ -3,12 +3,6 @@
|
||||||
|
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define NASAL_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define NASAL_EXPORT __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue