This commit is contained in:
Valk Richard Li 2020-09-12 00:02:53 -07:00 committed by GitHub
parent b5ff32710e
commit 5e18b2dcfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 36 deletions

View File

@ -5,7 +5,7 @@ int nasal_runtime::builtin_print(int local_scope_addr)
{
int vector_value_addr=-1;
if(local_scope_addr>=0)
vector_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("dyn");
vector_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("elements");
if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_print: cannot find values or wrong value type."<<std::endl;
@ -34,5 +34,102 @@ int nasal_runtime::builtin_print(int local_scope_addr)
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
int nasal_runtime::builtin_append(int local_scope_addr)
{
int vector_value_addr=-1;
if(local_scope_addr>=0)
vector_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("vector");
if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_append: cannot find values or wrong value type."<<std::endl;
++error;
return -1;
}
int elem_value_addr=-1;
if(local_scope_addr>=0)
elem_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("elements");
if(elem_value_addr<0 || nasal_vm.gc_get(elem_value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_append: cannot find values or wrong value type."<<std::endl;
++error;
return -1;
}
nasal_vector& ref_vector=nasal_vm.gc_get(vector_value_addr).get_vector();
nasal_vector& ref_elements=nasal_vm.gc_get(elem_value_addr).get_vector();
int size=ref_elements.size();
for(int i=0;i<size;++i)
{
int value_address=ref_elements.get_value_address(i);
nasal_vm.add_reference(value_address);
ref_vector.add_elem(value_address);
}
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
int nasal_runtime::builtin_setsize(int local_scope_addr)
{
int vector_value_addr=-1;
if(local_scope_addr>=0)
vector_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("vector");
if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_setsize: cannot find values or wrong value type."<<std::endl;
++error;
return -1;
}
int size_value_addr=-1;
if(local_scope_addr>=0)
size_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("size");
if(size_value_addr<0)
{
std::cout<<">> [runtime] builtin_setsize: cannot find values or wrong value type."<<std::endl;
++error;
return -1;
}
int type=nasal_vm.gc_get(size_value_addr).get_type();
if(type!=vm_number && type!=vm_string)
{
std::cout<<">> [runtime] builtin_setsize: size is not a number."<<std::endl;
++error;
return -1;
}
int number;
if(type==vm_number)
number=(int)nasal_vm.gc_get(size_value_addr).get_number();
else
{
std::string str=nasal_vm.gc_get(size_value_addr).get_string();
if(check_numerable_string(str))
number=(int)trans_string_to_number(str);
else
{
std::cout<<">> [runtime] builtin_setsize: size is not a numerable string."<<std::endl;
++error;
return -1;
}
}
if(number<0)
{
std::cout<<">> [runtime] builtin_setsize: size must be greater than -1."<<std::endl;
++error;
return -1;
}
nasal_vector& ref_vector=nasal_vm.gc_get(vector_value_addr).get_vector();
int vec_size=ref_vector.size();
if(number<vec_size)
for(int i=number;i<vec_size;++i)
ref_vector.del_elem(number);
else if(number>vec_size)
for(int i=vec_size;i<number;++i)
{
int new_val_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_val_addr).set_type(vm_nil);
ref_vector.add_elem(new_val_addr);
}
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
#endif

View File

@ -181,8 +181,10 @@ nasal_vector::~nasal_vector()
elems.clear();
return;
}
void nasal_vector::add_elem(int memory_address)
void nasal_vector::add_elem(int value_address)
{
int memory_address=nasal_vm.mem_alloc();
nasal_vm.mem_init(memory_address,value_address);
elems.push_back(memory_address);
return;
}
@ -253,10 +255,14 @@ nasal_hash::~nasal_hash()
elems.clear();
return;
}
void nasal_hash::add_elem(std::string key,int memory_address)
void nasal_hash::add_elem(std::string key,int value_address)
{
if(elems.find(key)==elems.end())
{
int memory_address=nasal_vm.mem_alloc();
nasal_vm.mem_init(memory_address,value_address);
elems[key]=memory_address;
}
else
std::cout<<">> [vm] nasal_hash::add_elem: "<<key<<" already exists."<<std::endl;
return;

View File

@ -75,6 +75,8 @@ private:
// builtin_func defined here
int builtin_print(int);
int builtin_append(int);
int builtin_setsize(int);
public:
nasal_runtime();
~nasal_runtime();
@ -145,11 +147,7 @@ int nasal_runtime::vector_generation(nasal_ast& node,int local_scope_addr)
int node_children_size=node.get_children().size();
for(int i=0;i<node_children_size;++i)
{
int new_memory_space=nasal_vm.mem_alloc();
ref_of_this_vector.add_elem(new_memory_space);
nasal_vm.mem_init(new_memory_space,calculation(node.get_children()[i],local_scope_addr));
}
ref_of_this_vector.add_elem(calculation(node.get_children()[i],local_scope_addr));
return new_addr;
}
int nasal_runtime::hash_generation(nasal_ast& node,int local_scope_addr)
@ -157,15 +155,12 @@ int nasal_runtime::hash_generation(nasal_ast& node,int local_scope_addr)
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).set_type(vm_hash);
nasal_hash& ref_of_this_hash=nasal_vm.gc_get(new_addr).get_hash();
int node_children_size=node.get_children().size();
for(int i=0;i<node_children_size;++i)
{
int new_memory_space=nasal_vm.mem_alloc();
std::string hash_member_name=node.get_children()[i].get_children()[0].get_str();
ref_of_this_hash.add_elem(hash_member_name,new_memory_space);
nasal_ast& ref_of_hash_member_value=node.get_children()[i].get_children()[1];
nasal_vm.mem_init(new_memory_space,calculation(ref_of_hash_member_value,local_scope_addr));
std::string hash_member_name=node.get_children()[i].get_children()[0].get_str();
ref_of_this_hash.add_elem(hash_member_name,calculation(ref_of_hash_member_value,local_scope_addr));
}
return new_addr;
}
@ -204,10 +199,10 @@ int nasal_runtime::main_progress()
case ast_conditional:ret_state=conditional_progress(root.get_children()[i],-1,false);break;
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
ret_state=loop_progress(root.get_children()[i],-1,false);break;
case ast_number:case ast_string:case ast_function:break;
case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(root.get_children()[i],-1));break;
@ -258,10 +253,10 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
case ast_conditional:ret_state=conditional_progress(tmp_node,local_scope_addr,allow_return);break;
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
ret_state=loop_progress(tmp_node,local_scope_addr,allow_return);break;
case ast_number:case ast_string:case ast_function:break;
case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(tmp_node,local_scope_addr));break;
@ -306,10 +301,10 @@ int nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
case ast_null:break;
case ast_definition:definition(node,local_scope_addr);break;
case ast_multi_assign:multi_assignment(node,local_scope_addr);break;
case ast_number:case ast_string:case ast_function:break;
case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
@ -327,10 +322,10 @@ int nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
case ast_null:break;
case ast_definition:definition(node,local_scope_addr);break;
case ast_multi_assign:multi_assignment(node,local_scope_addr);break;
case ast_number:case ast_string:case ast_function:break;
case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
@ -760,17 +755,13 @@ int nasal_runtime::call_vector(nasal_ast& node,int base_value_addr,int local_sco
if(value_type==vm_vector || value_type==vm_hash)
{
nasal_vm.add_reference(value_addr);
int new_mem_addr=nasal_vm.mem_alloc();
nasal_vm.mem_init(new_mem_addr,value_addr);
return_vector.add_elem(new_mem_addr);
return_vector.add_elem(value_addr);
}
else
{
int tmp_value_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(tmp_value_addr).deepcopy(nasal_vm.gc_get(value_addr));
int new_mem_addr=nasal_vm.mem_alloc();
nasal_vm.mem_init(new_mem_addr,tmp_value_addr);
return_vector.add_elem(new_mem_addr);
return_vector.add_elem(tmp_value_addr);
}
}
}
@ -1030,11 +1021,7 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_
nasal_vm.gc_get(vector_value_addr).set_type(vm_vector);
nasal_vector& ref_vec=nasal_vm.gc_get(vector_value_addr).get_vector();
for(int j=i;j<size;++j)
{
int new_mem=nasal_vm.mem_alloc();
nasal_vm.mem_init(new_mem,args[j]);
ref_vec.add_elem(new_mem);
}
ref_vec.add_elem(args[j]);
run_closure.add_new_value(tmp_node.get_str(),vector_value_addr);
break;
}
@ -1101,8 +1088,8 @@ int nasal_runtime::call_builtin_function(nasal_ast& node,int local_scope_addr)
switch(builtin_num)
{
case 0:ret_value_addr=builtin_print(local_scope_addr);break;
case 1:break;
case 2:break;
case 1:ret_value_addr=builtin_append(local_scope_addr);break;
case 2:ret_value_addr=builtin_setsize(local_scope_addr);break;
}
return ret_value_addr;
}
@ -1413,8 +1400,6 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
{
int scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr);
int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr);
int type=nasal_vm.gc_get(new_scalar_gc_addr).get_type();
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.add_reference(new_scalar_gc_addr);// this reference is reserved for ret_address
ret_address=new_scalar_gc_addr;