update
This commit is contained in:
parent
9eb72f8754
commit
7c026b62b7
|
@ -13,6 +13,8 @@ private:
|
||||||
std::vector<opcode> exec_code;
|
std::vector<opcode> exec_code;
|
||||||
// main calculation stack
|
// main calculation stack
|
||||||
std::stack<int> value_stack;
|
std::stack<int> value_stack;
|
||||||
|
// stack for mem_call
|
||||||
|
std::stack<int*> pointer_stack;
|
||||||
// local scope for function block
|
// local scope for function block
|
||||||
std::stack<int> local_scope_stack;
|
std::stack<int> local_scope_stack;
|
||||||
// slice stack for vec[val,val,val:val]
|
// slice stack for vec[val,val,val:val]
|
||||||
|
@ -104,6 +106,7 @@ void nasal_bytecode_vm::clear()
|
||||||
vm.clear();
|
vm.clear();
|
||||||
global_scope_addr=-1;
|
global_scope_addr=-1;
|
||||||
while(!value_stack.empty())value_stack.pop();
|
while(!value_stack.empty())value_stack.pop();
|
||||||
|
while(!pointer_stack.empty())pointer_stack.pop();
|
||||||
while(!local_scope_stack.empty())local_scope_stack.pop();
|
while(!local_scope_stack.empty())local_scope_stack.pop();
|
||||||
local_scope_stack.push(-1);
|
local_scope_stack.push(-1);
|
||||||
while(!slice_stack.empty())slice_stack.pop();
|
while(!slice_stack.empty())slice_stack.pop();
|
||||||
|
@ -116,15 +119,7 @@ void nasal_bytecode_vm::clear()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::die(std::string str)
|
void nasal_bytecode_vm::die(std::string str)
|
||||||
{
|
{
|
||||||
std::string numinfo="";
|
printf(">> [vm] 0x%.8x: %s\n",ptr,str.data());
|
||||||
int num=ptr;
|
|
||||||
for(int i=0;i<8;++i)
|
|
||||||
{
|
|
||||||
int tmp=num&0x0f;
|
|
||||||
numinfo=(char)(tmp>9? 'a'+tmp-10:'0'+tmp)+numinfo;
|
|
||||||
num>>=4;
|
|
||||||
}
|
|
||||||
std::cout<<">> [vm] 0x"<<numinfo<<": "<<str<<'\n';
|
|
||||||
main_loop_break_mark=false;
|
main_loop_break_mark=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -450,11 +445,11 @@ void nasal_bytecode_vm::opr_lnk()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_addeq()
|
void nasal_bytecode_vm::opr_addeq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr2=value_stack.top();
|
int val_addr2=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int val_addr1=vm.mem_get(mem_addr);
|
int val_addr1=*mem_addr;
|
||||||
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
||||||
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
||||||
int a_ref_type=a_ref.get_type();
|
int a_ref_type=a_ref.get_type();
|
||||||
|
@ -474,17 +469,18 @@ void nasal_bytecode_vm::opr_addeq()
|
||||||
vm.gc_get(new_value_address).set_number(a_num+b_num);
|
vm.gc_get(new_value_address).set_number(a_num+b_num);
|
||||||
vm.add_reference(new_value_address);
|
vm.add_reference(new_value_address);
|
||||||
value_stack.push(new_value_address);
|
value_stack.push(new_value_address);
|
||||||
vm.mem_change(mem_addr,new_value_address);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_value_address;
|
||||||
vm.del_reference(val_addr2);
|
vm.del_reference(val_addr2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_subeq()
|
void nasal_bytecode_vm::opr_subeq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr2=value_stack.top();
|
int val_addr2=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int val_addr1=vm.mem_get(mem_addr);
|
int val_addr1=*mem_addr;
|
||||||
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
||||||
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
||||||
int a_ref_type=a_ref.get_type();
|
int a_ref_type=a_ref.get_type();
|
||||||
|
@ -504,17 +500,18 @@ void nasal_bytecode_vm::opr_subeq()
|
||||||
vm.gc_get(new_value_address).set_number(a_num-b_num);
|
vm.gc_get(new_value_address).set_number(a_num-b_num);
|
||||||
vm.add_reference(new_value_address);
|
vm.add_reference(new_value_address);
|
||||||
value_stack.push(new_value_address);
|
value_stack.push(new_value_address);
|
||||||
vm.mem_change(mem_addr,new_value_address);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_value_address;
|
||||||
vm.del_reference(val_addr2);
|
vm.del_reference(val_addr2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_muleq()
|
void nasal_bytecode_vm::opr_muleq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr2=value_stack.top();
|
int val_addr2=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int val_addr1=vm.mem_get(mem_addr);
|
int val_addr1=*mem_addr;
|
||||||
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
||||||
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
||||||
int a_ref_type=a_ref.get_type();
|
int a_ref_type=a_ref.get_type();
|
||||||
|
@ -534,17 +531,18 @@ void nasal_bytecode_vm::opr_muleq()
|
||||||
vm.gc_get(new_value_address).set_number(a_num*b_num);
|
vm.gc_get(new_value_address).set_number(a_num*b_num);
|
||||||
vm.add_reference(new_value_address);
|
vm.add_reference(new_value_address);
|
||||||
value_stack.push(new_value_address);
|
value_stack.push(new_value_address);
|
||||||
vm.mem_change(mem_addr,new_value_address);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_value_address;
|
||||||
vm.del_reference(val_addr2);
|
vm.del_reference(val_addr2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_diveq()
|
void nasal_bytecode_vm::opr_diveq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr2=value_stack.top();
|
int val_addr2=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int val_addr1=vm.mem_get(mem_addr);
|
int val_addr1=*mem_addr;
|
||||||
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
||||||
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
||||||
int a_ref_type=a_ref.get_type();
|
int a_ref_type=a_ref.get_type();
|
||||||
|
@ -564,17 +562,18 @@ void nasal_bytecode_vm::opr_diveq()
|
||||||
vm.gc_get(new_value_address).set_number(a_num/b_num);
|
vm.gc_get(new_value_address).set_number(a_num/b_num);
|
||||||
vm.add_reference(new_value_address);
|
vm.add_reference(new_value_address);
|
||||||
value_stack.push(new_value_address);
|
value_stack.push(new_value_address);
|
||||||
vm.mem_change(mem_addr,new_value_address);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_value_address;
|
||||||
vm.del_reference(val_addr2);
|
vm.del_reference(val_addr2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_lnkeq()
|
void nasal_bytecode_vm::opr_lnkeq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr2=value_stack.top();
|
int val_addr2=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int val_addr1=vm.mem_get(mem_addr);
|
int val_addr1=*mem_addr;
|
||||||
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
nasal_scalar& a_ref=vm.gc_get(val_addr1);
|
||||||
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
nasal_scalar& b_ref=vm.gc_get(val_addr2);
|
||||||
int a_ref_type=a_ref.get_type();
|
int a_ref_type=a_ref.get_type();
|
||||||
|
@ -590,17 +589,19 @@ void nasal_bytecode_vm::opr_lnkeq()
|
||||||
vm.gc_get(new_value_address).set_string(a_str+b_str);
|
vm.gc_get(new_value_address).set_string(a_str+b_str);
|
||||||
vm.add_reference(new_value_address);
|
vm.add_reference(new_value_address);
|
||||||
value_stack.push(new_value_address);
|
value_stack.push(new_value_address);
|
||||||
vm.mem_change(mem_addr,new_value_address);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_value_address;
|
||||||
vm.del_reference(val_addr2);
|
vm.del_reference(val_addr2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_meq()
|
void nasal_bytecode_vm::opr_meq()
|
||||||
{
|
{
|
||||||
int mem_addr=value_stack.top();
|
int* mem_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int val_addr=value_stack.top();
|
int val_addr=value_stack.top();
|
||||||
vm.add_reference(val_addr);
|
vm.add_reference(val_addr);
|
||||||
vm.mem_change(mem_addr,val_addr);
|
vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=val_addr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_eq()
|
void nasal_bytecode_vm::opr_eq()
|
||||||
|
@ -1284,23 +1285,23 @@ void nasal_bytecode_vm::opr_slice2()
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_mcall()
|
void nasal_bytecode_vm::opr_mcall()
|
||||||
{
|
{
|
||||||
int mem_addr=-1;
|
int* mem_addr=NULL;
|
||||||
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(string_table[exec_code[ptr].index]);
|
||||||
if(mem_addr<0)
|
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(string_table[exec_code[ptr].index]);
|
||||||
if(mem_addr<0)
|
if(!mem_addr)
|
||||||
die("mcall: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\"");
|
die("mcall: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\"");
|
||||||
value_stack.push(mem_addr);
|
pointer_stack.push(mem_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_mcallv()
|
void nasal_bytecode_vm::opr_mcallv()
|
||||||
{
|
{
|
||||||
int val_addr=value_stack.top();
|
int val_addr=value_stack.top();
|
||||||
value_stack.pop();
|
value_stack.pop();
|
||||||
int vec_addr=vm.mem_get(value_stack.top());
|
int* vec_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
int type=vm.gc_get(vec_addr).get_type();
|
int type=vm.gc_get(*vec_addr).get_type();
|
||||||
if(type==vm_string)
|
if(type==vm_string)
|
||||||
{
|
{
|
||||||
die("mcallv: cannot get memory space in a string");
|
die("mcallv: cannot get memory space in a string");
|
||||||
|
@ -1315,13 +1316,13 @@ void nasal_bytecode_vm::opr_mcallv()
|
||||||
case vm_string:num=(int)trans_string_to_number(vm.gc_get(val_addr).get_string());break;
|
case vm_string:num=(int)trans_string_to_number(vm.gc_get(val_addr).get_string());break;
|
||||||
default:die("mcallv: error value type");break;
|
default:die("mcallv: error value type");break;
|
||||||
}
|
}
|
||||||
int res=vm.gc_get(vec_addr).get_vector().get_mem_address(num);
|
int* res=vm.gc_get(*vec_addr).get_vector().get_mem_address(num);
|
||||||
if(res<0)
|
if(!res)
|
||||||
{
|
{
|
||||||
die("mcallv: index out of range");
|
die("mcallv: index out of range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value_stack.push(res);
|
pointer_stack.push(res);
|
||||||
}
|
}
|
||||||
else if(type==vm_hash)
|
else if(type==vm_hash)
|
||||||
{
|
{
|
||||||
|
@ -1330,34 +1331,38 @@ void nasal_bytecode_vm::opr_mcallv()
|
||||||
die("mcallv: must use string as the key");
|
die("mcallv: must use string as the key");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int res=vm.gc_get(vec_addr).get_hash().get_mem_address(vm.gc_get(val_addr).get_string());
|
nasal_hash& ref=vm.gc_get(*vec_addr).get_hash();
|
||||||
if(res<0)
|
std::string str=vm.gc_get(val_addr).get_string();
|
||||||
|
int* res=ref.get_mem_address(str);
|
||||||
|
if(!res)
|
||||||
{
|
{
|
||||||
die("mcallv: cannot find member \""+vm.gc_get(val_addr).get_string()+"\" of this hash");
|
ref.add_elem(str,vm.gc_alloc(vm_nil));
|
||||||
return;
|
res=ref.get_mem_address(str);
|
||||||
}
|
}
|
||||||
value_stack.push(res);
|
pointer_stack.push(res);
|
||||||
}
|
}
|
||||||
vm.del_reference(val_addr);
|
vm.del_reference(val_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_mcallh()
|
void nasal_bytecode_vm::opr_mcallh()
|
||||||
{
|
{
|
||||||
int mem_addr=-1;
|
int* mem_addr=NULL;
|
||||||
int hash_addr=vm.mem_get(value_stack.top());
|
int* hash_addr=pointer_stack.top();
|
||||||
value_stack.pop();
|
pointer_stack.pop();
|
||||||
if(vm.gc_get(hash_addr).get_type()!=vm_hash)
|
if(vm.gc_get(*hash_addr).get_type()!=vm_hash)
|
||||||
{
|
{
|
||||||
die("mcallh: must call a hash");
|
die("mcallh: must call a hash");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mem_addr=vm.gc_get(hash_addr).get_hash().get_mem_address(string_table[exec_code[ptr].index]);
|
nasal_hash& ref=vm.gc_get(*hash_addr).get_hash();
|
||||||
if(mem_addr<0)
|
std::string str=string_table[exec_code[ptr].index];
|
||||||
|
mem_addr=ref.get_mem_address(str);
|
||||||
|
if(!mem_addr)
|
||||||
{
|
{
|
||||||
die("mcallh: cannot get memory space in this hash");
|
ref.add_elem(str,vm.gc_alloc(vm_nil));
|
||||||
return;
|
mem_addr=ref.get_mem_address(str);
|
||||||
}
|
}
|
||||||
value_stack.push(mem_addr);
|
pointer_stack.push(mem_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_return()
|
void nasal_bytecode_vm::opr_return()
|
||||||
|
|
143
nasal_gc.h
143
nasal_gc.h
|
@ -35,7 +35,7 @@ public:
|
||||||
int del_elem();
|
int del_elem();
|
||||||
int size();
|
int size();
|
||||||
int get_value_address(int);
|
int get_value_address(int);
|
||||||
int get_mem_address(int);
|
int* get_mem_address(int);
|
||||||
void print();
|
void print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public:
|
||||||
int size();
|
int size();
|
||||||
int get_special_para(std::string);
|
int get_special_para(std::string);
|
||||||
int get_value_address(std::string);
|
int get_value_address(std::string);
|
||||||
int get_mem_address(std::string);
|
int* get_mem_address(std::string);
|
||||||
bool check_contain(std::string);
|
bool check_contain(std::string);
|
||||||
int get_keys();
|
int get_keys();
|
||||||
void print();
|
void print();
|
||||||
|
@ -62,7 +62,6 @@ public:
|
||||||
class nasal_function
|
class nasal_function
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// this int points to the space in nasal_vm::garbage_collector_memory
|
|
||||||
nasal_virtual_machine& vm;
|
nasal_virtual_machine& vm;
|
||||||
int entry;
|
int entry;
|
||||||
int closure_addr;
|
int closure_addr;
|
||||||
|
@ -103,7 +102,7 @@ public:
|
||||||
void del_scope();
|
void del_scope();
|
||||||
void add_new_value(std::string,int);
|
void add_new_value(std::string,int);
|
||||||
int get_value_address(std::string);
|
int get_value_address(std::string);
|
||||||
int get_mem_address(std::string);
|
int* get_mem_address(std::string);
|
||||||
void set_closure(nasal_closure&);
|
void set_closure(nasal_closure&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,8 +145,6 @@ private:
|
||||||
nasal_scalar error_returned_value;
|
nasal_scalar error_returned_value;
|
||||||
std::queue<int> garbage_collector_free_space;
|
std::queue<int> garbage_collector_free_space;
|
||||||
std::vector<gc_unit*> garbage_collector_memory;
|
std::vector<gc_unit*> garbage_collector_memory;
|
||||||
std::queue<int> memory_manager_free_space;
|
|
||||||
std::vector<int> memory_manager_memory;
|
|
||||||
public:
|
public:
|
||||||
nasal_virtual_machine();
|
nasal_virtual_machine();
|
||||||
~nasal_virtual_machine();
|
~nasal_virtual_machine();
|
||||||
|
@ -157,10 +154,6 @@ public:
|
||||||
nasal_scalar& gc_get(int); // get scalar that stored in gc
|
nasal_scalar& gc_get(int); // get scalar that stored in gc
|
||||||
void add_reference(int);
|
void add_reference(int);
|
||||||
void del_reference(int);
|
void del_reference(int);
|
||||||
int mem_alloc(int); // memory gives a new space
|
|
||||||
void mem_free(int); // give space back to memory
|
|
||||||
void mem_change(int,int); // change value in memory space
|
|
||||||
int mem_get(int); // get value in memory space
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*functions of nasal_vector*/
|
/*functions of nasal_vector*/
|
||||||
|
@ -172,14 +165,13 @@ nasal_vector::~nasal_vector()
|
||||||
{
|
{
|
||||||
int size=elems.size();
|
int size=elems.size();
|
||||||
for(int i=0;i<size;++i)
|
for(int i=0;i<size;++i)
|
||||||
vm.mem_free(elems[i]);
|
vm.del_reference(elems[i]);
|
||||||
elems.clear();
|
elems.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_vector::add_elem(int value_address)
|
void nasal_vector::add_elem(int value_address)
|
||||||
{
|
{
|
||||||
int memory_address=vm.mem_alloc(value_address);
|
elems.push_back(value_address);
|
||||||
elems.push_back(memory_address);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int nasal_vector::del_elem()
|
int nasal_vector::del_elem()
|
||||||
|
@ -187,9 +179,7 @@ int nasal_vector::del_elem()
|
||||||
// pop back
|
// pop back
|
||||||
if(!elems.size())
|
if(!elems.size())
|
||||||
return -1;
|
return -1;
|
||||||
int ret=vm.mem_get(elems.back());
|
int ret=elems.back();
|
||||||
vm.add_reference(ret);
|
|
||||||
vm.mem_free(elems.back());
|
|
||||||
elems.pop_back();
|
elems.pop_back();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -207,9 +197,9 @@ int nasal_vector::get_value_address(int index)
|
||||||
std::cout<<">> [runtime] nasal_vector::get_value_address: index out of range: "<<index<<"\n";
|
std::cout<<">> [runtime] nasal_vector::get_value_address: index out of range: "<<index<<"\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return vm.mem_get(elems[(index+vec_size)%vec_size]);
|
return elems[(index+vec_size)%vec_size];
|
||||||
}
|
}
|
||||||
int nasal_vector::get_mem_address(int index)
|
int* nasal_vector::get_mem_address(int index)
|
||||||
{
|
{
|
||||||
int vec_size=elems.size();
|
int vec_size=elems.size();
|
||||||
int left_range=-vec_size;
|
int left_range=-vec_size;
|
||||||
|
@ -217,9 +207,9 @@ int nasal_vector::get_mem_address(int index)
|
||||||
if(index<left_range || index>right_range)
|
if(index<left_range || index>right_range)
|
||||||
{
|
{
|
||||||
std::cout<<">> [runtime] nasal_vector::get_mem_address: index out of range: "<<index<<"\n";
|
std::cout<<">> [runtime] nasal_vector::get_mem_address: index out of range: "<<index<<"\n";
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
return elems[(index+vec_size)%vec_size];
|
return &elems[(index+vec_size)%vec_size];
|
||||||
}
|
}
|
||||||
void nasal_vector::print()
|
void nasal_vector::print()
|
||||||
{
|
{
|
||||||
|
@ -229,7 +219,7 @@ void nasal_vector::print()
|
||||||
std::cout<<"]";
|
std::cout<<"]";
|
||||||
for(int i=0;i<size;++i)
|
for(int i=0;i<size;++i)
|
||||||
{
|
{
|
||||||
nasal_scalar& tmp=vm.gc_get(vm.mem_get(elems[i]));
|
nasal_scalar& tmp=vm.gc_get(elems[i]);
|
||||||
switch(tmp.get_type())
|
switch(tmp.get_type())
|
||||||
{
|
{
|
||||||
case vm_nil:std::cout<<"nil";break;
|
case vm_nil:std::cout<<"nil";break;
|
||||||
|
@ -252,24 +242,21 @@ nasal_hash::nasal_hash(nasal_virtual_machine& nvm):vm(nvm)
|
||||||
nasal_hash::~nasal_hash()
|
nasal_hash::~nasal_hash()
|
||||||
{
|
{
|
||||||
for(std::map<std::string,int>::iterator iter=elems.begin();iter!=elems.end();++iter)
|
for(std::map<std::string,int>::iterator iter=elems.begin();iter!=elems.end();++iter)
|
||||||
vm.mem_free(iter->second);
|
vm.del_reference(iter->second);
|
||||||
elems.clear();
|
elems.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_hash::add_elem(std::string key,int value_address)
|
void nasal_hash::add_elem(std::string key,int value_address)
|
||||||
{
|
{
|
||||||
if(elems.find(key)==elems.end())
|
if(elems.find(key)==elems.end())
|
||||||
{
|
elems[key]=value_address;
|
||||||
int memory_address=vm.mem_alloc(value_address);
|
|
||||||
elems[key]=memory_address;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_hash::del_elem(std::string key)
|
void nasal_hash::del_elem(std::string key)
|
||||||
{
|
{
|
||||||
if(elems.find(key)!=elems.end())
|
if(elems.find(key)!=elems.end())
|
||||||
{
|
{
|
||||||
vm.mem_free(elems[key]);
|
vm.del_reference(elems[key]);
|
||||||
elems.erase(key);
|
elems.erase(key);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -281,18 +268,17 @@ int nasal_hash::size()
|
||||||
int nasal_hash::get_special_para(std::string key)
|
int nasal_hash::get_special_para(std::string key)
|
||||||
{
|
{
|
||||||
if(elems.find(key)!=elems.end())
|
if(elems.find(key)!=elems.end())
|
||||||
return vm.mem_get(elems[key]);
|
return elems[key];
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int nasal_hash::get_value_address(std::string key)
|
int nasal_hash::get_value_address(std::string key)
|
||||||
{
|
{
|
||||||
int ret_value_addr=-1;
|
int ret_value_addr=-1;
|
||||||
if(elems.find(key)!=elems.end())
|
if(elems.find(key)!=elems.end())
|
||||||
return vm.mem_get(elems[key]);
|
return elems[key];
|
||||||
else if(elems.find("parents")!=elems.end())
|
else if(elems.find("parents")!=elems.end())
|
||||||
{
|
{
|
||||||
int mem_addr=elems["parents"];
|
int val_addr=elems["parents"];
|
||||||
int val_addr=vm.mem_get(mem_addr);
|
|
||||||
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
||||||
{
|
{
|
||||||
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
||||||
|
@ -309,15 +295,14 @@ int nasal_hash::get_value_address(std::string key)
|
||||||
}
|
}
|
||||||
return ret_value_addr;
|
return ret_value_addr;
|
||||||
}
|
}
|
||||||
int nasal_hash::get_mem_address(std::string key)
|
int* nasal_hash::get_mem_address(std::string key)
|
||||||
{
|
{
|
||||||
int ret_mem_addr=-1;
|
int* mem_addr=NULL;
|
||||||
if(elems.find(key)!=elems.end())
|
if(elems.find(key)!=elems.end())
|
||||||
return elems[key];
|
return &elems[key];
|
||||||
else if(elems.find("parents")!=elems.end())
|
else if(elems.find("parents")!=elems.end())
|
||||||
{
|
{
|
||||||
int mem_addr=elems["parents"];
|
int val_addr=elems["parents"];
|
||||||
int val_addr=vm.mem_get(mem_addr);
|
|
||||||
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
||||||
{
|
{
|
||||||
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
||||||
|
@ -326,13 +311,13 @@ int nasal_hash::get_mem_address(std::string key)
|
||||||
{
|
{
|
||||||
int tmp_val_addr=vec_ref.get_value_address(i);
|
int tmp_val_addr=vec_ref.get_value_address(i);
|
||||||
if(vm.gc_get(tmp_val_addr).get_type()==vm_hash)
|
if(vm.gc_get(tmp_val_addr).get_type()==vm_hash)
|
||||||
ret_mem_addr=vm.gc_get(tmp_val_addr).get_hash().get_mem_address(key);
|
mem_addr=vm.gc_get(tmp_val_addr).get_hash().get_mem_address(key);
|
||||||
if(ret_mem_addr>=0)
|
if(mem_addr>0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret_mem_addr;
|
return mem_addr;
|
||||||
}
|
}
|
||||||
bool nasal_hash::check_contain(std::string key)
|
bool nasal_hash::check_contain(std::string key)
|
||||||
{
|
{
|
||||||
|
@ -341,8 +326,7 @@ bool nasal_hash::check_contain(std::string key)
|
||||||
if(elems.find("parents")!=elems.end())
|
if(elems.find("parents")!=elems.end())
|
||||||
{
|
{
|
||||||
bool result=false;
|
bool result=false;
|
||||||
int mem_addr=elems["parents"];
|
int val_addr=elems["parents"];
|
||||||
int val_addr=vm.mem_get(mem_addr);
|
|
||||||
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
if(vm.gc_get(val_addr).get_type()==vm_vector)
|
||||||
{
|
{
|
||||||
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector();
|
||||||
|
@ -380,7 +364,7 @@ void nasal_hash::print()
|
||||||
for(std::map<std::string,int>::iterator i=elems.begin();i!=elems.end();++i)
|
for(std::map<std::string,int>::iterator i=elems.begin();i!=elems.end();++i)
|
||||||
{
|
{
|
||||||
std::cout<<i->first<<":";
|
std::cout<<i->first<<":";
|
||||||
nasal_scalar& tmp=vm.gc_get(vm.mem_get(i->second));
|
nasal_scalar& tmp=vm.gc_get(i->second);
|
||||||
switch(tmp.get_type())
|
switch(tmp.get_type())
|
||||||
{
|
{
|
||||||
case vm_nil:std::cout<<"nil";break;
|
case vm_nil:std::cout<<"nil";break;
|
||||||
|
@ -491,7 +475,7 @@ nasal_closure::~nasal_closure()
|
||||||
{
|
{
|
||||||
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||||
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
||||||
vm.mem_free(j->second);
|
vm.del_reference(j->second);
|
||||||
elems.clear();
|
elems.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -505,20 +489,19 @@ void nasal_closure::del_scope()
|
||||||
{
|
{
|
||||||
std::map<std::string,int>& last_scope=elems.back();
|
std::map<std::string,int>& last_scope=elems.back();
|
||||||
for(std::map<std::string,int>::iterator i=last_scope.begin();i!=last_scope.end();++i)
|
for(std::map<std::string,int>::iterator i=last_scope.begin();i!=last_scope.end();++i)
|
||||||
vm.mem_free(i->second);
|
vm.del_reference(i->second);
|
||||||
elems.pop_back();
|
elems.pop_back();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_closure::add_new_value(std::string key,int value_address)
|
void nasal_closure::add_new_value(std::string key,int value_address)
|
||||||
{
|
{
|
||||||
int new_mem_address=vm.mem_alloc(value_address);
|
|
||||||
if(elems.back().find(key)!=elems.back().end())
|
if(elems.back().find(key)!=elems.back().end())
|
||||||
{
|
{
|
||||||
// if this value already exists,delete the old value and update a new value
|
// if this value already exists,delete the old value and update a new value
|
||||||
int old_mem_address=elems.back()[key];
|
int old_val_address=elems.back()[key];
|
||||||
vm.mem_free(old_mem_address);
|
vm.del_reference(old_val_address);
|
||||||
}
|
}
|
||||||
elems.back()[key]=new_mem_address;
|
elems.back()[key]=value_address;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int nasal_closure::get_value_address(std::string key)
|
int nasal_closure::get_value_address(std::string key)
|
||||||
|
@ -526,22 +509,22 @@ int nasal_closure::get_value_address(std::string key)
|
||||||
int ret_address=-1;
|
int ret_address=-1;
|
||||||
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||||
if(i->find(key)!=i->end())
|
if(i->find(key)!=i->end())
|
||||||
ret_address=vm.mem_get((*i)[key]);
|
ret_address=(*i)[key];
|
||||||
return ret_address;
|
return ret_address;
|
||||||
}
|
}
|
||||||
int nasal_closure::get_mem_address(std::string key)
|
int* nasal_closure::get_mem_address(std::string key)
|
||||||
{
|
{
|
||||||
int ret_address=-1;
|
int* ret_address=NULL;
|
||||||
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||||
if(i->find(key)!=i->end())
|
if(i->find(key)!=i->end())
|
||||||
ret_address=(*i)[key];
|
ret_address=&((*i)[key]);
|
||||||
return ret_address;
|
return ret_address;
|
||||||
}
|
}
|
||||||
void nasal_closure::set_closure(nasal_closure& tmp)
|
void nasal_closure::set_closure(nasal_closure& tmp)
|
||||||
{
|
{
|
||||||
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
for(std::list<std::map<std::string,int> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||||
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
||||||
vm.mem_free(j->second);
|
vm.del_reference(j->second);
|
||||||
elems.clear();
|
elems.clear();
|
||||||
for(std::list<std::map<std::string,int> >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i)
|
for(std::list<std::map<std::string,int> >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i)
|
||||||
{
|
{
|
||||||
|
@ -549,10 +532,9 @@ void nasal_closure::set_closure(nasal_closure& tmp)
|
||||||
elems.push_back(new_scope);
|
elems.push_back(new_scope);
|
||||||
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
for(std::map<std::string,int>::iterator j=i->begin();j!=i->end();++j)
|
||||||
{
|
{
|
||||||
int value_addr=vm.mem_get(j->second);
|
int value_addr=j->second;
|
||||||
int new_mem_addr=vm.mem_alloc(value_addr);
|
|
||||||
vm.add_reference(value_addr);
|
vm.add_reference(value_addr);
|
||||||
elems.back()[j->first]=new_mem_addr;
|
elems.back()[j->first]=value_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -687,10 +669,7 @@ nasal_virtual_machine::~nasal_virtual_machine()
|
||||||
delete garbage_collector_memory[i];
|
delete garbage_collector_memory[i];
|
||||||
while(!garbage_collector_free_space.empty())
|
while(!garbage_collector_free_space.empty())
|
||||||
garbage_collector_free_space.pop();
|
garbage_collector_free_space.pop();
|
||||||
while(!memory_manager_free_space.empty())
|
|
||||||
memory_manager_free_space.pop();
|
|
||||||
garbage_collector_memory.clear();
|
garbage_collector_memory.clear();
|
||||||
memory_manager_memory.clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_virtual_machine::debug()
|
void nasal_virtual_machine::debug()
|
||||||
|
@ -728,10 +707,7 @@ void nasal_virtual_machine::clear()
|
||||||
delete garbage_collector_memory[i];
|
delete garbage_collector_memory[i];
|
||||||
while(!garbage_collector_free_space.empty())
|
while(!garbage_collector_free_space.empty())
|
||||||
garbage_collector_free_space.pop();
|
garbage_collector_free_space.pop();
|
||||||
while(!memory_manager_free_space.empty())
|
|
||||||
memory_manager_free_space.pop();
|
|
||||||
garbage_collector_memory.clear();
|
garbage_collector_memory.clear();
|
||||||
memory_manager_memory.clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int nasal_virtual_machine::gc_alloc(int val_type)
|
int nasal_virtual_machine::gc_alloc(int val_type)
|
||||||
|
@ -780,48 +756,5 @@ void nasal_virtual_machine::del_reference(int value_address)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int nasal_virtual_machine::mem_alloc(int value_address)
|
|
||||||
{
|
|
||||||
if(memory_manager_free_space.empty())
|
|
||||||
{
|
|
||||||
int mem_size=memory_manager_memory.size();
|
|
||||||
memory_manager_memory.resize(mem_size+256);
|
|
||||||
for(int i=mem_size;i<mem_size+256;++i)
|
|
||||||
memory_manager_free_space.push(i);
|
|
||||||
}
|
|
||||||
int ret=memory_manager_free_space.front();
|
|
||||||
memory_manager_memory[ret]=value_address;
|
|
||||||
memory_manager_free_space.pop();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void nasal_virtual_machine::mem_free(int memory_address)
|
|
||||||
{
|
|
||||||
// mem_free has helped scalar to delete the reference
|
|
||||||
// so don't need to delete reference again
|
|
||||||
if(0<=memory_address)
|
|
||||||
{
|
|
||||||
this->del_reference(memory_manager_memory[memory_address]);
|
|
||||||
memory_manager_free_space.push(memory_address);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void nasal_virtual_machine::mem_change(int memory_address,int value_address)
|
|
||||||
{
|
|
||||||
// this progress is used to change a memory space's value address
|
|
||||||
// be careful! this process doesn't check if this mem_space is in use.
|
|
||||||
if(0<=memory_address)
|
|
||||||
{
|
|
||||||
this->del_reference(memory_manager_memory[memory_address]);
|
|
||||||
memory_manager_memory[memory_address]=value_address;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int nasal_virtual_machine::mem_get(int memory_address)
|
|
||||||
{
|
|
||||||
// be careful! this process doesn't check if this mem_space is in use.
|
|
||||||
if(0<=memory_address)
|
|
||||||
return memory_manager_memory[memory_address];
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -180,6 +180,15 @@ void nasal_parse::die(int line,std::string info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
std::cout<<">> [parse] line "<<line<<": "<<info<<".\n";
|
std::cout<<">> [parse] line "<<line<<": "<<info<<".\n";
|
||||||
|
while(ptr<tok_list_size)// panic
|
||||||
|
{
|
||||||
|
if(tok_list[ptr].type==tok_semi)
|
||||||
|
{
|
||||||
|
--ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,6 +606,7 @@ nasal_ast nasal_parse::calculation()
|
||||||
// trinocular calculation
|
// trinocular calculation
|
||||||
nasal_ast tmp(tok_list[ptr].line,ast_trinocular);
|
nasal_ast tmp(tok_list[ptr].line,ast_trinocular);
|
||||||
tmp.add_child(node);
|
tmp.add_child(node);
|
||||||
|
++ptr;
|
||||||
tmp.add_child(calculation());
|
tmp.add_child(calculation());
|
||||||
++ptr;
|
++ptr;
|
||||||
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
|
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
|
||||||
|
|
134
nasal_runtime.h
134
nasal_runtime.h
|
@ -56,9 +56,9 @@ private:
|
||||||
int call_function(nasal_ast&,int,int,int);
|
int call_function(nasal_ast&,int,int,int);
|
||||||
int call_builtin_function(std::string,int);
|
int call_builtin_function(std::string,int);
|
||||||
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
|
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
|
||||||
int call_scalar_mem(nasal_ast&,int);
|
int* call_scalar_mem(nasal_ast&,int);
|
||||||
int call_vector_mem(nasal_ast&,int,int);
|
int* call_vector_mem(nasal_ast&,int*,int);
|
||||||
int call_hash_mem(nasal_ast&,int,int);
|
int* call_hash_mem(nasal_ast&,int*,int);
|
||||||
// calculate scalars
|
// calculate scalars
|
||||||
int nasal_scalar_add(int,int);
|
int nasal_scalar_add(int,int);
|
||||||
int nasal_scalar_sub(int,int);
|
int nasal_scalar_sub(int,int);
|
||||||
|
@ -337,7 +337,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr)
|
||||||
return rt_error;
|
return rt_error;
|
||||||
}
|
}
|
||||||
// begin loop progress
|
// begin loop progress
|
||||||
int mem_addr=-1;
|
int* mem_addr=NULL;
|
||||||
if(iter_node.get_type()==ast_new_iter)
|
if(iter_node.get_type()==ast_new_iter)
|
||||||
{
|
{
|
||||||
int new_value_addr=nasal_vm.gc_alloc(vm_nil);
|
int new_value_addr=nasal_vm.gc_alloc(vm_nil);
|
||||||
|
@ -347,7 +347,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mem_addr=call_scalar_mem(iter_node,local_scope_addr);
|
mem_addr=call_scalar_mem(iter_node,local_scope_addr);
|
||||||
if(mem_addr<0)
|
if(!mem_addr)
|
||||||
{
|
{
|
||||||
die(iter_node.get_line(),"get null iterator");
|
die(iter_node.get_line(),"get null iterator");
|
||||||
return rt_error;
|
return rt_error;
|
||||||
|
@ -361,13 +361,15 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int new_iter_val_addr=nasal_vm.gc_alloc(vm_number);
|
int new_iter_val_addr=nasal_vm.gc_alloc(vm_number);
|
||||||
nasal_vm.gc_get(new_iter_val_addr).set_number((double)i);
|
nasal_vm.gc_get(new_iter_val_addr).set_number((double)i);
|
||||||
nasal_vm.mem_change(mem_addr,new_iter_val_addr);
|
nasal_vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=new_iter_val_addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int value_addr=ref_vector.get_value_address(i);
|
int value_addr=ref_vector.get_value_address(i);
|
||||||
nasal_vm.add_reference(value_addr);
|
nasal_vm.add_reference(value_addr);
|
||||||
nasal_vm.mem_change(mem_addr,value_addr);
|
nasal_vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=value_addr;
|
||||||
}
|
}
|
||||||
ret_state=block_progress(run_block_node,local_scope_addr);
|
ret_state=block_progress(run_block_node,local_scope_addr);
|
||||||
if(ret_state==rt_break || ret_state==rt_return || error)
|
if(ret_state==rt_break || ret_state==rt_return || error)
|
||||||
|
@ -923,37 +925,37 @@ int nasal_runtime::call_builtin_function(std::string val_name,int local_scope_ad
|
||||||
}
|
}
|
||||||
return ret_value_addr;
|
return ret_value_addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
|
int* nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int mem_address=-1;
|
int* mem_address=NULL;
|
||||||
if(node.get_type()==ast_identifier)
|
if(node.get_type()==ast_identifier)
|
||||||
{
|
{
|
||||||
std::string id_name=node.get_str();
|
std::string id_name=node.get_str();
|
||||||
if(local_scope_addr>=0)
|
if(local_scope_addr>=0)
|
||||||
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
|
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
|
||||||
if(mem_address<0)
|
if(!mem_address)
|
||||||
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
|
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
|
||||||
if(mem_address<0)
|
if(!mem_address)
|
||||||
{
|
{
|
||||||
die(node.get_line(),"cannot find \""+id_name+"\"");
|
die(node.get_line(),"cannot find \""+id_name+"\"");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
return mem_address;
|
return mem_address;
|
||||||
}
|
}
|
||||||
std::string id_name=node.get_children()[0].get_str();
|
std::string id_name=node.get_children()[0].get_str();
|
||||||
if(local_scope_addr>=0)
|
if(local_scope_addr>=0)
|
||||||
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
|
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
|
||||||
if(mem_address<0)
|
if(!mem_address)
|
||||||
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
|
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
|
||||||
if(mem_address<0)
|
if(!mem_address)
|
||||||
{
|
{
|
||||||
die(node.get_children()[0].get_line(),"cannot find \""+id_name+"\"");
|
die(node.get_children()[0].get_line(),"cannot find \""+id_name+"\"");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
int call_expr_size=node.get_children().size();
|
int call_expr_size=node.get_children().size();
|
||||||
for(int i=1;i<call_expr_size;++i)
|
for(int i=1;i<call_expr_size;++i)
|
||||||
{
|
{
|
||||||
int tmp_mem_addr=-1;
|
int* tmp_mem_addr=NULL;
|
||||||
nasal_ast& call_expr=node.get_children()[i];
|
nasal_ast& call_expr=node.get_children()[i];
|
||||||
switch(call_expr.get_type())
|
switch(call_expr.get_type())
|
||||||
{
|
{
|
||||||
|
@ -961,7 +963,7 @@ int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
|
||||||
case ast_call_hash: tmp_mem_addr=call_hash_mem(call_expr,mem_address,local_scope_addr);break;
|
case ast_call_hash: tmp_mem_addr=call_hash_mem(call_expr,mem_address,local_scope_addr);break;
|
||||||
}
|
}
|
||||||
mem_address=tmp_mem_addr;
|
mem_address=tmp_mem_addr;
|
||||||
if(mem_address<0)
|
if(!mem_address)
|
||||||
{
|
{
|
||||||
die(call_expr.get_line(),"incorrect memory space");
|
die(call_expr.get_line(),"incorrect memory space");
|
||||||
break;
|
break;
|
||||||
|
@ -969,15 +971,15 @@ int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
|
||||||
}
|
}
|
||||||
return mem_address;
|
return mem_address;
|
||||||
}
|
}
|
||||||
int nasal_runtime::call_vector_mem(nasal_ast& node,int base_mem_addr,int local_scope_addr)
|
int* nasal_runtime::call_vector_mem(nasal_ast& node,int* base_mem_addr,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int return_mem_addr=-1;
|
int* return_mem_addr=NULL;
|
||||||
int base_value_addr=nasal_vm.mem_get(base_mem_addr);
|
int base_value_addr=*base_mem_addr;
|
||||||
int base_value_type=nasal_vm.gc_get(base_value_addr).get_type();
|
int base_value_type=nasal_vm.gc_get(base_value_addr).get_type();
|
||||||
if(base_value_type!=vm_vector && base_value_type!=vm_hash)
|
if(base_value_type!=vm_vector && base_value_type!=vm_hash)
|
||||||
{
|
{
|
||||||
die(node.get_line(),"incorrect value type,must be vector/hash");
|
die(node.get_line(),"incorrect value type,must be vector/hash");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(base_value_type==vm_vector)
|
if(base_value_type==vm_vector)
|
||||||
{
|
{
|
||||||
|
@ -988,7 +990,7 @@ int nasal_runtime::call_vector_mem(nasal_ast& node,int base_mem_addr,int local_s
|
||||||
if(index_value_type!=vm_number && index_value_type!=vm_string)
|
if(index_value_type!=vm_number && index_value_type!=vm_string)
|
||||||
{
|
{
|
||||||
die(tmp.get_line(),"index is not a number/numerable string");
|
die(tmp.get_line(),"index is not a number/numerable string");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
int index_num=0;
|
int index_num=0;
|
||||||
if(index_value_type==vm_string)
|
if(index_value_type==vm_string)
|
||||||
|
@ -1001,6 +1003,8 @@ int nasal_runtime::call_vector_mem(nasal_ast& node,int base_mem_addr,int local_s
|
||||||
index_num=(int)nasal_vm.gc_get(index_value_addr).get_number();
|
index_num=(int)nasal_vm.gc_get(index_value_addr).get_number();
|
||||||
nasal_vm.del_reference(index_value_addr);
|
nasal_vm.del_reference(index_value_addr);
|
||||||
return_mem_addr=reference_value.get_mem_address(index_num);
|
return_mem_addr=reference_value.get_mem_address(index_num);
|
||||||
|
if(!return_mem_addr)
|
||||||
|
die(tmp.get_line(),"incorrect memory space");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1009,25 +1013,31 @@ int nasal_runtime::call_vector_mem(nasal_ast& node,int base_mem_addr,int local_s
|
||||||
if(str_addr<0 || nasal_vm.gc_get(str_addr).get_type()!=vm_string)
|
if(str_addr<0 || nasal_vm.gc_get(str_addr).get_type()!=vm_string)
|
||||||
{
|
{
|
||||||
die(tmp.get_line(),"must use string as the key");
|
die(tmp.get_line(),"must use string as the key");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::string str=nasal_vm.gc_get(str_addr).get_string();
|
std::string str=nasal_vm.gc_get(str_addr).get_string();
|
||||||
return_mem_addr=nasal_vm.gc_get(base_value_addr).get_hash().get_mem_address(str);
|
return_mem_addr=nasal_vm.gc_get(base_value_addr).get_hash().get_mem_address(str);
|
||||||
|
if(!return_mem_addr)
|
||||||
|
{
|
||||||
|
nasal_hash& ref=nasal_vm.gc_get(base_value_addr).get_hash();
|
||||||
|
ref.add_elem(str,nasal_vm.gc_alloc(vm_nil));
|
||||||
|
return_mem_addr=ref.get_mem_address(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return return_mem_addr;
|
return return_mem_addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::call_hash_mem(nasal_ast& node,int base_mem_addr,int local_scope_addr)
|
int* nasal_runtime::call_hash_mem(nasal_ast& node,int* base_mem_addr,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int base_value_addr=nasal_vm.mem_get(base_mem_addr);
|
int base_value_addr=*base_mem_addr;
|
||||||
int value_type=nasal_vm.gc_get(base_value_addr).get_type();
|
int value_type=nasal_vm.gc_get(base_value_addr).get_type();
|
||||||
if(value_type!=vm_hash)
|
if(value_type!=vm_hash)
|
||||||
{
|
{
|
||||||
die(node.get_line(),"called a value that is not a hash");
|
die(node.get_line(),"called a value that is not a hash");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
nasal_hash& ref=nasal_vm.gc_get(base_value_addr).get_hash();
|
nasal_hash& ref=nasal_vm.gc_get(base_value_addr).get_hash();
|
||||||
int ret_mem_addr=ref.get_mem_address(node.get_str());
|
int* ret_mem_addr=ref.get_mem_address(node.get_str());
|
||||||
if(ret_mem_addr<0)
|
if(!ret_mem_addr)
|
||||||
{
|
{
|
||||||
ref.add_elem(node.get_str(),nasal_vm.gc_alloc(vm_nil));
|
ref.add_elem(node.get_str(),nasal_vm.gc_alloc(vm_nil));
|
||||||
ret_mem_addr=ref.get_mem_address(node.get_str());
|
ret_mem_addr=ref.get_mem_address(node.get_str());
|
||||||
|
@ -1693,64 +1703,76 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_equal)
|
else if(calculation_type==ast_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
|
if(!scalar_mem_space) return -1;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,new_scalar_gc_addr);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(*scalar_mem_space);
|
||||||
|
*scalar_mem_space=new_scalar_gc_addr;
|
||||||
nasal_vm.add_reference(new_scalar_gc_addr);// this reference is reserved for ret_address
|
nasal_vm.add_reference(new_scalar_gc_addr);// this reference is reserved for ret_address
|
||||||
ret_address=new_scalar_gc_addr;
|
ret_address=new_scalar_gc_addr;
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_add_equal)
|
else if(calculation_type==ast_add_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
int scalar_val_space=nasal_vm.mem_get(scalar_mem_space);
|
if(!scalar_mem_space) return -1;
|
||||||
|
int scalar_val_space=*scalar_mem_space;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
int result_val_address=nasal_scalar_add(scalar_val_space,new_scalar_gc_addr);
|
int result_val_address=nasal_scalar_add(scalar_val_space,new_scalar_gc_addr);
|
||||||
nasal_vm.del_reference(new_scalar_gc_addr);
|
nasal_vm.del_reference(new_scalar_gc_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,result_val_address);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(scalar_val_space);
|
||||||
|
*scalar_mem_space=result_val_address;
|
||||||
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
||||||
ret_address=result_val_address;
|
ret_address=result_val_address;
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_sub_equal)
|
else if(calculation_type==ast_sub_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
int scalar_val_space=nasal_vm.mem_get(scalar_mem_space);
|
if(!scalar_mem_space) return -1;
|
||||||
|
int scalar_val_space=*scalar_mem_space;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
int result_val_address=nasal_scalar_sub(scalar_val_space,new_scalar_gc_addr);
|
int result_val_address=nasal_scalar_sub(scalar_val_space,new_scalar_gc_addr);
|
||||||
nasal_vm.del_reference(new_scalar_gc_addr);
|
nasal_vm.del_reference(new_scalar_gc_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,result_val_address);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(scalar_val_space);
|
||||||
|
*scalar_mem_space=result_val_address;
|
||||||
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
||||||
ret_address=result_val_address;
|
ret_address=result_val_address;
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_div_equal)
|
else if(calculation_type==ast_div_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
int scalar_val_space=nasal_vm.mem_get(scalar_mem_space);
|
if(!scalar_mem_space) return -1;
|
||||||
|
int scalar_val_space=*scalar_mem_space;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
int result_val_address=nasal_scalar_div(scalar_val_space,new_scalar_gc_addr);
|
int result_val_address=nasal_scalar_div(scalar_val_space,new_scalar_gc_addr);
|
||||||
nasal_vm.del_reference(new_scalar_gc_addr);
|
nasal_vm.del_reference(new_scalar_gc_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,result_val_address);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(scalar_val_space);
|
||||||
|
*scalar_mem_space=result_val_address;
|
||||||
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
||||||
ret_address=result_val_address;
|
ret_address=result_val_address;
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_mult_equal)
|
else if(calculation_type==ast_mult_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
int scalar_val_space=nasal_vm.mem_get(scalar_mem_space);
|
if(!scalar_mem_space) return -1;
|
||||||
|
int scalar_val_space=*scalar_mem_space;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
int result_val_address=nasal_scalar_mult(scalar_val_space,new_scalar_gc_addr);
|
int result_val_address=nasal_scalar_mult(scalar_val_space,new_scalar_gc_addr);
|
||||||
nasal_vm.del_reference(new_scalar_gc_addr);
|
nasal_vm.del_reference(new_scalar_gc_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,result_val_address);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(scalar_val_space);
|
||||||
|
*scalar_mem_space=result_val_address;
|
||||||
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
||||||
ret_address=result_val_address;
|
ret_address=result_val_address;
|
||||||
}
|
}
|
||||||
else if(calculation_type==ast_link_equal)
|
else if(calculation_type==ast_link_equal)
|
||||||
{
|
{
|
||||||
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
|
||||||
int scalar_val_space=nasal_vm.mem_get(scalar_mem_space);
|
if(!scalar_mem_space) return -1;
|
||||||
|
int scalar_val_space=*scalar_mem_space;
|
||||||
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
|
||||||
int result_val_address=nasal_scalar_link(scalar_val_space,new_scalar_gc_addr);
|
int result_val_address=nasal_scalar_link(scalar_val_space,new_scalar_gc_addr);
|
||||||
nasal_vm.del_reference(new_scalar_gc_addr);
|
nasal_vm.del_reference(new_scalar_gc_addr);
|
||||||
nasal_vm.mem_change(scalar_mem_space,result_val_address);// this progress will delete the reference to old gc_addr in scalar_mem_space
|
nasal_vm.del_reference(scalar_val_space);
|
||||||
|
*scalar_mem_space=result_val_address;
|
||||||
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address
|
||||||
ret_address=result_val_address;
|
ret_address=result_val_address;
|
||||||
}
|
}
|
||||||
|
@ -1818,13 +1840,7 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
nasal_ast& multi_call_node=node.get_children()[0];
|
nasal_ast& multi_call_node=node.get_children()[0];
|
||||||
nasal_ast& value_node=node.get_children()[1];
|
nasal_ast& value_node=node.get_children()[1];
|
||||||
std::vector<int> mem_table;
|
|
||||||
int id_size=multi_call_node.get_children().size();
|
int id_size=multi_call_node.get_children().size();
|
||||||
for(int i=0;i<id_size;++i)
|
|
||||||
{
|
|
||||||
nasal_ast& tmp_node=multi_call_node.get_children()[i];
|
|
||||||
mem_table.push_back(call_scalar_mem(tmp_node,local_scope_addr));
|
|
||||||
}
|
|
||||||
if(value_node.get_type()==ast_multi_scalar)
|
if(value_node.get_type()==ast_multi_scalar)
|
||||||
{
|
{
|
||||||
// there's no need to check value_size==id_size
|
// there's no need to check value_size==id_size
|
||||||
|
@ -1833,7 +1849,13 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr)
|
||||||
for(int i=0;i<id_size;++i)
|
for(int i=0;i<id_size;++i)
|
||||||
value_table.push_back(calculation(value_node.get_children()[i],local_scope_addr));
|
value_table.push_back(calculation(value_node.get_children()[i],local_scope_addr));
|
||||||
for(int i=0;i<id_size;++i)
|
for(int i=0;i<id_size;++i)
|
||||||
nasal_vm.mem_change(mem_table[i],value_table[i]);
|
{
|
||||||
|
nasal_ast& tmp_node=multi_call_node.get_children()[i];
|
||||||
|
int* mem_addr=call_scalar_mem(tmp_node,local_scope_addr);
|
||||||
|
if(!mem_addr) return;
|
||||||
|
nasal_vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=value_table[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1859,7 +1881,13 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr)
|
||||||
value_table.push_back(tmp_addr);
|
value_table.push_back(tmp_addr);
|
||||||
}
|
}
|
||||||
for(int i=0;i<id_size;++i)
|
for(int i=0;i<id_size;++i)
|
||||||
nasal_vm.mem_change(mem_table[i],value_table[i]);
|
{
|
||||||
|
nasal_ast& tmp_node=multi_call_node.get_children()[i];
|
||||||
|
int* mem_addr=call_scalar_mem(tmp_node,local_scope_addr);
|
||||||
|
if(!mem_addr) return;
|
||||||
|
nasal_vm.del_reference(*mem_addr);
|
||||||
|
*mem_addr=value_table[i];
|
||||||
|
}
|
||||||
nasal_vm.del_reference(value_addr);
|
nasal_vm.del_reference(value_addr);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue