📝 improve maintainability
This commit is contained in:
parent
a11e0726bb
commit
230848a6e1
|
@ -42,6 +42,7 @@ var nas_hash::get_value(const std::string& key) {
|
||||||
} else if (!elems.count("parents")) {
|
} else if (!elems.count("parents")) {
|
||||||
return var::none();
|
return var::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = var::none();
|
auto ret = var::none();
|
||||||
auto& val = elems.at("parents");
|
auto& val = elems.at("parents");
|
||||||
if (!val.is_vec()) {
|
if (!val.is_vec()) {
|
||||||
|
@ -64,12 +65,14 @@ var* nas_hash::get_memory(const std::string& key) {
|
||||||
} else if (!elems.count("parents")) {
|
} else if (!elems.count("parents")) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
var* addr = nullptr;
|
var* addr = nullptr;
|
||||||
var& val = elems.at("parents");
|
var& val = elems.at("parents");
|
||||||
if (!val.is_vec()) {
|
if (!val.is_vec()) {
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
for(auto& i : val.vec().elems) {
|
for(auto& i : val.vec().elems) {
|
||||||
|
// recursively search key in `parents`
|
||||||
if (i.is_hash()) {
|
if (i.is_hash()) {
|
||||||
addr = i.hash().get_memory(key);
|
addr = i.hash().get_memory(key);
|
||||||
}
|
}
|
||||||
|
@ -102,8 +105,7 @@ void nas_func::clear() {
|
||||||
keys.clear();
|
keys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nas_ghost::set(
|
void nas_ghost::set(const std::string& ghost_type_name,
|
||||||
const std::string& ghost_type_name,
|
|
||||||
destructor destructor_pointer,
|
destructor destructor_pointer,
|
||||||
marker gc_marker_pointer,
|
marker gc_marker_pointer,
|
||||||
void* ghost_pointer) {
|
void* ghost_pointer) {
|
||||||
|
|
|
@ -20,13 +20,15 @@ namespace nasal {
|
||||||
class vm {
|
class vm {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* registers of vm */
|
/* vm context */
|
||||||
context ctx; // running context
|
context ctx;
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
const f64* const_number = nullptr; // constant numbers
|
const f64* const_number = nullptr;
|
||||||
const std::string* const_string = nullptr; // constant symbols and strings
|
const std::string* const_string = nullptr;
|
||||||
std::vector<u64> imm; // immediate number table
|
std::vector<u64> imm; // immediate number table
|
||||||
|
|
||||||
|
/* nasal native functions */
|
||||||
std::vector<nasal_builtin_table> native_function;
|
std::vector<nasal_builtin_table> native_function;
|
||||||
|
|
||||||
/* garbage collector */
|
/* garbage collector */
|
||||||
|
@ -77,9 +79,11 @@ protected:
|
||||||
std::string type_name_string(const var&) const;
|
std::string type_name_string(const var&) const;
|
||||||
void die(const std::string&);
|
void die(const std::string&);
|
||||||
|
|
||||||
|
protected:
|
||||||
/* vm calculation functions*/
|
/* vm calculation functions*/
|
||||||
inline bool cond(var&);
|
inline bool cond(var&);
|
||||||
|
|
||||||
|
protected:
|
||||||
/* vm operands */
|
/* vm operands */
|
||||||
inline void o_repl();
|
inline void o_repl();
|
||||||
inline void o_intl();
|
inline void o_intl();
|
||||||
|
@ -248,7 +252,8 @@ inline void vm::o_newv() {
|
||||||
vec.resize(imm[ctx.pc]);
|
vec.resize(imm[ctx.pc]);
|
||||||
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
|
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
|
||||||
ctx.top = ctx.top - imm[ctx.pc] + 1;
|
ctx.top = ctx.top - imm[ctx.pc] + 1;
|
||||||
for(u32 i = 0; i<imm[ctx.pc]; ++i) {
|
|
||||||
|
for(u64 i = 0; i<imm[ctx.pc]; ++i) {
|
||||||
vec[i] = ctx.top[i];
|
vec[i] = ctx.top[i];
|
||||||
}
|
}
|
||||||
ctx.top[0] = newv;
|
ctx.top[0] = newv;
|
||||||
|
@ -266,17 +271,22 @@ inline void vm::o_newf() {
|
||||||
|
|
||||||
/* this means you create a new function in local scope */
|
/* this means you create a new function in local scope */
|
||||||
if (ctx.localr) {
|
if (ctx.localr) {
|
||||||
|
// copy upval scope list from upper level function
|
||||||
func.upval = ctx.funcr.func().upval;
|
func.upval = ctx.funcr.func().upval;
|
||||||
// function created in the same local scope shares one closure
|
|
||||||
// so this size & stk setting has no problem
|
// function created in the same local scope shares same closure
|
||||||
var upval = (ctx.upvalr.is_nil())?
|
var upval = (ctx.upvalr.is_nil())?
|
||||||
ngc.alloc(vm_type::vm_upval):
|
ngc.alloc(vm_type::vm_upval):
|
||||||
ctx.upvalr;
|
ctx.upvalr;
|
||||||
|
// if no upval scope exists, now it's time to create one
|
||||||
|
if (ctx.upvalr.is_nil()) {
|
||||||
upval.upval().size = ctx.funcr.func().local_size;
|
upval.upval().size = ctx.funcr.func().local_size;
|
||||||
upval.upval().stack_frame_offset = ctx.localr;
|
upval.upval().stack_frame_offset = ctx.localr;
|
||||||
func.upval.push_back(upval);
|
|
||||||
ctx.upvalr = upval;
|
ctx.upvalr = upval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func.upval.push_back(upval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void vm::o_happ() {
|
inline void vm::o_happ() {
|
||||||
|
@ -679,6 +689,7 @@ inline void vm::o_callh() {
|
||||||
die("must call a hash but get "+type_name_string(val));
|
die("must call a hash but get "+type_name_string(val));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& str = const_string[imm[ctx.pc]];
|
const auto& str = const_string[imm[ctx.pc]];
|
||||||
if (val.is_hash()) {
|
if (val.is_hash()) {
|
||||||
ctx.top[0] = val.hash().get_value(str);
|
ctx.top[0] = val.hash().get_value(str);
|
||||||
|
@ -968,25 +979,31 @@ inline void vm::o_mcallv() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void vm::o_mcallh() {
|
inline void vm::o_mcallh() {
|
||||||
var hash = ctx.top[0]; // mcall hash, reserved on stack to avoid gc
|
// mcall hash, reserved on stack to avoid gc, so do not do ctx.top--
|
||||||
|
var hash = ctx.top[0];
|
||||||
if (!hash.is_hash() && !hash.is_map()) {
|
if (!hash.is_hash() && !hash.is_map()) {
|
||||||
die("must call a hash/namespace but get " + type_name_string(hash));
|
die("must call a hash/namespace but get " + type_name_string(hash));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto& str = const_string[imm[ctx.pc]];
|
|
||||||
|
const auto& key = const_string[imm[ctx.pc]];
|
||||||
|
|
||||||
|
// map is for nasal namespace type, for example `globals`
|
||||||
if (hash.is_map()) {
|
if (hash.is_map()) {
|
||||||
ctx.memr = hash.map().get_memory(str);
|
ctx.memr = hash.map().get_memory(key);
|
||||||
if (!ctx.memr) {
|
if (!ctx.memr) {
|
||||||
die("cannot find symbol \"" + str + "\"");
|
die("cannot find symbol \"" + key + "\"");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hash member
|
||||||
auto& ref = hash.hash();
|
auto& ref = hash.hash();
|
||||||
ctx.memr = ref.get_memory(str);
|
ctx.memr = ref.get_memory(key);
|
||||||
// create a new key
|
// create a new key if not exists
|
||||||
if (!ctx.memr) {
|
if (!ctx.memr) {
|
||||||
ref.elems[str] = nil;
|
ref.elems[key] = nil;
|
||||||
ctx.memr = ref.get_memory(str);
|
ctx.memr = ref.get_memory(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,7 +1041,7 @@ inline void vm::o_ret() {
|
||||||
auto size = func.func().local_size;
|
auto size = func.func().local_size;
|
||||||
upval.on_stack = false;
|
upval.on_stack = false;
|
||||||
upval.elems.resize(size);
|
upval.elems.resize(size);
|
||||||
for(u32 i = 0; i<size; ++i) {
|
for(u64 i = 0; i<size; ++i) {
|
||||||
upval.elems[i] = local[i];
|
upval.elems[i] = local[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ var student = func(n,a) {
|
||||||
get_name: func return n
|
get_name: func return n
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var s=student('valk',24);
|
var s=student('valk',24);
|
||||||
s.print_info();
|
s.print_info();
|
||||||
println(s.get_age(),' ',s.get_name());
|
println(s.get_age(),' ',s.get_name());
|
||||||
|
@ -18,6 +19,7 @@ s.set_age(20);
|
||||||
s.set_name('Sidi Liang');
|
s.set_name('Sidi Liang');
|
||||||
s.print_info();
|
s.print_info();
|
||||||
println(s.get_age(),' ',s.get_name());
|
println(s.get_age(),' ',s.get_name());
|
||||||
|
|
||||||
# flightgear nasal-console cannot use this kind of object initializing
|
# flightgear nasal-console cannot use this kind of object initializing
|
||||||
var m = func() {
|
var m = func() {
|
||||||
var (_1,_2)=(0,1);
|
var (_1,_2)=(0,1);
|
||||||
|
|
|
@ -251,3 +251,19 @@ var test_single_id_iterator = 0;
|
||||||
foreach(test_single_id_iterator; [0, 1, 2, 3]) {
|
foreach(test_single_id_iterator; [0, 1, 2, 3]) {
|
||||||
println(test_single_id_iterator);
|
println(test_single_id_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# simple closure test, make sure two functions share the same closure
|
||||||
|
var closure_tester = func() {
|
||||||
|
var b = 0;
|
||||||
|
return [
|
||||||
|
func { b += 1; },
|
||||||
|
func { return b; }
|
||||||
|
];
|
||||||
|
}();
|
||||||
|
|
||||||
|
for(var i = 1; i<=10; i += 1) {
|
||||||
|
closure_tester[0]();
|
||||||
|
if (closure_tester[1]()!=i) {
|
||||||
|
die("test failed: expect " ~ i ~ ", but get " ~ closure_tester[1]());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue