This commit is contained in:
Valk Richard Li 2020-12-17 00:14:22 +08:00
parent 19ce1c5f34
commit ae16f36baa
3 changed files with 19 additions and 23 deletions

16
nasal.h
View File

@ -25,10 +25,10 @@
check if a string can be converted to a number check if a string can be converted to a number
if this string cannot be converted to a number,it will return nan if this string cannot be converted to a number,it will return nan
*/ */
inline double hex_to_double(std::string str,int len) inline double hex_to_double(std::string str)
{ {
double ret=0; double ret=0;
for(int i=2;i<len;++i) for(int i=2;str[i];++i)
{ {
ret*=16; ret*=16;
if('0'<=str[i] && str[i]<='9') if('0'<=str[i] && str[i]<='9')
@ -42,10 +42,10 @@ inline double hex_to_double(std::string str,int len)
} }
return ret; return ret;
} }
inline double oct_to_double(std::string str,int len) inline double oct_to_double(std::string str)
{ {
double ret=0; double ret=0;
for(int i=2;i<len;++i) for(int i=2;str[i];++i)
{ {
ret*=8; ret*=8;
if('0'<=str[i] && str[i]<='8') if('0'<=str[i] && str[i]<='8')
@ -106,10 +106,10 @@ double trans_string_to_number(std::string str)
is_negative=(str[0]=='-'?-1:1); is_negative=(str[0]=='-'?-1:1);
str=str.substr(1,len--); str=str.substr(1,len--);
} }
if(len>2 && str[0]=='0' && str[1]=='x') if(len>1 && str[0]=='0' && str[1]=='x')
ret_num=hex_to_double(str,len); ret_num=hex_to_double(str);
else if(len>2 && str[0]=='0' && str[1]=='o') else if(len>1 && str[0]=='0' && str[1]=='o')
ret_num=oct_to_double(str,len); ret_num=oct_to_double(str);
else else
ret_num=dec_to_double(str,len); ret_num=dec_to_double(str,len);
return is_negative*ret_num; return is_negative*ret_num;

View File

@ -968,13 +968,14 @@ void nasal_bytecode_vm::opr_foreach()
void nasal_bytecode_vm::opr_call() void nasal_bytecode_vm::opr_call()
{ {
int val_addr=-1; int val_addr=-1;
std::string symbol=string_table[exec_code[ptr].index];
if(local_scope_stack.top()>=0) if(local_scope_stack.top()>=0)
val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(string_table[exec_code[ptr].index]); val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(symbol);
if(val_addr<0) if(val_addr<0)
val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(string_table[exec_code[ptr].index]); val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(symbol);
if(val_addr<0) if(val_addr<0)
{ {
die("call: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\""); die("call: cannot find symbol named \""+symbol+"\"");
return; return;
} }
vm.add_reference(val_addr); vm.add_reference(val_addr);
@ -1281,12 +1282,13 @@ void nasal_bytecode_vm::opr_slice2()
void nasal_bytecode_vm::opr_mcall() void nasal_bytecode_vm::opr_mcall()
{ {
int* mem_addr=NULL; int* mem_addr=NULL;
std::string symbol=string_table[exec_code[ptr].index];
if(local_scope_stack.top()>=0) if(local_scope_stack.top()>=0)
mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(string_table[exec_code[ptr].index]); mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(symbol);
if(!mem_addr) if(!mem_addr)
mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(string_table[exec_code[ptr].index]); mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(symbol);
if(!mem_addr) if(!mem_addr)
die("mcall: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\""); die("mcall: cannot find symbol named \""+symbol+"\"");
pointer_stack.push(mem_addr); pointer_stack.push(mem_addr);
return; return;
} }

View File

@ -131,12 +131,10 @@ class nasal_virtual_machine
{ {
struct gc_unit struct gc_unit
{ {
bool collected;
int ref_cnt; int ref_cnt;
nasal_scalar elem; nasal_scalar elem;
gc_unit() gc_unit()
{ {
collected=true;
ref_cnt=0; ref_cnt=0;
return; return;
} }
@ -662,7 +660,6 @@ nasal_virtual_machine::~nasal_virtual_machine()
if(garbage_collector_memory[i]->ref_cnt) if(garbage_collector_memory[i]->ref_cnt)
{ {
garbage_collector_memory[i]->ref_cnt=0; garbage_collector_memory[i]->ref_cnt=0;
garbage_collector_memory[i]->collected=true;
garbage_collector_memory[i]->elem.clear(); garbage_collector_memory[i]->elem.clear();
} }
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
@ -700,7 +697,6 @@ void nasal_virtual_machine::clear()
if(garbage_collector_memory[i]->ref_cnt) if(garbage_collector_memory[i]->ref_cnt)
{ {
garbage_collector_memory[i]->ref_cnt=0; garbage_collector_memory[i]->ref_cnt=0;
garbage_collector_memory[i]->collected=true;
garbage_collector_memory[i]->elem.clear(); garbage_collector_memory[i]->elem.clear();
} }
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
@ -724,7 +720,6 @@ int nasal_virtual_machine::gc_alloc(int val_type)
} }
int ret=garbage_collector_free_space.front(); int ret=garbage_collector_free_space.front();
gc_unit& unit_ref=*garbage_collector_memory[ret]; gc_unit& unit_ref=*garbage_collector_memory[ret];
unit_ref.collected=false;
unit_ref.ref_cnt=1; unit_ref.ref_cnt=1;
unit_ref.elem.set_type(val_type,*this); unit_ref.elem.set_type(val_type,*this);
garbage_collector_free_space.pop(); garbage_collector_free_space.pop();
@ -732,25 +727,24 @@ int nasal_virtual_machine::gc_alloc(int val_type)
} }
nasal_scalar& nasal_virtual_machine::gc_get(int value_address) nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
{ {
if(0<=value_address && !garbage_collector_memory[value_address]->collected) if(0<=value_address)
return garbage_collector_memory[value_address]->elem; return garbage_collector_memory[value_address]->elem;
return error_returned_value; return error_returned_value;
} }
void nasal_virtual_machine::add_reference(int value_address) void nasal_virtual_machine::add_reference(int value_address)
{ {
if(0<=value_address && !garbage_collector_memory[value_address]->collected) if(0<=value_address)
++garbage_collector_memory[value_address]->ref_cnt; ++garbage_collector_memory[value_address]->ref_cnt;
return; return;
} }
void nasal_virtual_machine::del_reference(int value_address) void nasal_virtual_machine::del_reference(int value_address)
{ {
if(0<=value_address && !garbage_collector_memory[value_address]->collected) if(0<=value_address)
--garbage_collector_memory[value_address]->ref_cnt; --garbage_collector_memory[value_address]->ref_cnt;
else else
return; return;
if(!garbage_collector_memory[value_address]->ref_cnt) if(!garbage_collector_memory[value_address]->ref_cnt)
{ {
garbage_collector_memory[value_address]->collected=true;
garbage_collector_memory[value_address]->elem.clear(); garbage_collector_memory[value_address]->elem.clear();
garbage_collector_free_space.push(value_address); garbage_collector_free_space.push(value_address);
} }