This commit is contained in:
Valk Richard Li 2020-09-06 02:09:46 -07:00 committed by GitHub
parent b7b0306bbc
commit b0bc5a33a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 126 additions and 20 deletions

View File

@ -117,13 +117,8 @@ void nasal_ast::print_ast(int depth)
for(int i=0;i<depth;++i) indentation+="| ";
indentation+=ast_str(this->type);
std::cout<<indentation;
switch(this->type)
{
case ast_number: std::cout<<":"<<this->str;break;
case ast_string: std::cout<<":"<<this->str;break;
case ast_identifier:std::cout<<":"<<this->str;break;
case ast_call_hash: std::cout<<":"<<this->str;break;
}
if(this->type==ast_number || this->type==ast_string || this->type==ast_identifier || this->type==ast_dynamic_id || this->type==ast_call_hash)
std::cout<<":"<<this->str;
std::cout<<std::endl;
int child_size=this->children.size();
for(int i=0;i<child_size;++i)

View File

@ -47,16 +47,21 @@ class nasal_function
{
private:
// this int points to the space in nasal_vm::garbage_collector_memory
bool is_builtin;
int closure_addr;
nasal_ast argument_list;
nasal_ast function_expr;
public:
nasal_function();
~nasal_function();
void set_builtin_func();
bool check_builtin();
void set_closure_addr(int);
int get_closure_addr();
void set_arguments(nasal_ast&);
nasal_ast& get_arguments();
void set_run_block(nasal_ast&);
nasal_ast& get_run_block();
void deepcopy(nasal_function&);
};
@ -267,19 +272,53 @@ void nasal_hash::del_elem(std::string key)
}
int nasal_hash::get_value_address(std::string key)
{
int ret_value_addr=-1;
if(elems.find(key)!=elems.end())
return nasal_vm.mem_get(elems[key]);
else
std::cout<<">> [vm] nasal_hash:get_value_address: "<<key<<" does not exist."<<std::endl;
return -1;
else if(elems.find("parents")!=elems.end())
{
int mem_addr=elems["parents"];
int val_addr=nasal_vm.mem_get(mem_addr);
if(nasal_vm.gc_get(val_addr).get_type()==vm_vector)
{
nasal_vector& vec_ref=nasal_vm.gc_get(val_addr).get_vector();
int size=vec_ref.size();
for(int i=0;i<size;++i)
{
int tmp_val_addr=vec_ref.get_value_address(i);
if(nasal_vm.gc_get(tmp_val_addr).get_type()==vm_hash)
ret_value_addr=nasal_vm.gc_get(tmp_val_addr).get_hash().get_value_address(key);
if(ret_value_addr>=0)
break;
}
}
}
return ret_value_addr;
}
int nasal_hash::get_mem_address(std::string key)
{
int ret_mem_addr=-1;
if(elems.find(key)!=elems.end())
return elems[key];
else
std::cout<<">> [vm] nasal_hash:get_mem_address: "<<key<<" does not exist."<<std::endl;
return -1;
else if(elems.find("parents")!=elems.end())
{
int mem_addr=elems["parents"];
int val_addr=nasal_vm.mem_get(mem_addr);
if(nasal_vm.gc_get(val_addr).get_type()==vm_vector)
{
nasal_vector& vec_ref=nasal_vm.gc_get(val_addr).get_vector();
int size=vec_ref.size();
for(int i=0;i<size;++i)
{
int tmp_val_addr=vec_ref.get_value_address(i);
if(nasal_vm.gc_get(tmp_val_addr).get_type()==vm_hash)
ret_mem_addr=nasal_vm.gc_get(tmp_val_addr).get_hash().get_mem_address(key);
if(ret_mem_addr>=0)
break;
}
}
}
return ret_mem_addr;
}
void nasal_hash::deepcopy(nasal_hash& tmp)
{
@ -298,6 +337,7 @@ void nasal_hash::deepcopy(nasal_hash& tmp)
/*functions of nasal_function*/
nasal_function::nasal_function()
{
is_builtin=false;
closure_addr=-1;
argument_list.clear();
function_expr.clear();
@ -311,6 +351,15 @@ nasal_function::~nasal_function()
function_expr.clear();
return;
}
void nasal_function::set_builtin_func()
{
is_builtin=true;
return;
}
bool nasal_function::check_builtin()
{
return is_builtin;
}
void nasal_function::set_closure_addr(int value_address)
{
closure_addr=value_address;
@ -325,11 +374,19 @@ void nasal_function::set_arguments(nasal_ast& node)
argument_list=node;
return;
}
nasal_ast& nasal_function::get_arguments()
{
return argument_list;
}
void nasal_function::set_run_block(nasal_ast& node)
{
function_expr=node;
return;
}
nasal_ast& nasal_function::get_run_block()
{
return function_expr;
}
void nasal_function::deepcopy(nasal_function& tmp)
{
this->closure_addr=nasal_vm.gc_alloc();

View File

@ -347,6 +347,7 @@ nasal_ast nasal_parse::hash_member_gen()
if(ptr>=tok_list_size || (tok_list[ptr].type!=tok_identifier && tok_list[ptr].type!=tok_string))
{
error_info(error_line,lack_identifier);
++error;
return node;
}
node.set_line(tok_list[ptr].line);

View File

@ -51,7 +51,7 @@ private:
int call_scalar(nasal_ast&,int);
int call_vector(nasal_ast&,int,int);
int call_hash(nasal_ast&,int,int);
int call_function(nasal_ast&,int,int);
int call_function(nasal_ast&,int,int,int);
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
int call_scalar_mem(nasal_ast&,int);
int call_vector_mem(nasal_ast&,int,int);
@ -173,9 +173,16 @@ int nasal_runtime::function_generation(nasal_ast& node,int local_scope_addr)
ref_of_this_function.set_run_block(node.get_children()[1]);
if(local_scope_addr>=0)
{
// codes here make closure
nasal_vm.add_reference(local_scope_addr);
ref_of_this_function.set_closure_addr(local_scope_addr);
}
else
{
int new_closure_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_closure_addr).set_type(vm_closure);
ref_of_this_function.set_closure_addr(new_closure_addr);
}
return new_addr;
}
int nasal_runtime::main_progress()
@ -229,6 +236,9 @@ int nasal_runtime::main_progress()
case ast_continue:
ret_state=rt_continue;
break;
case ast_return:
ret_state=rt_return;
break;
}
switch(ret_state)
{
@ -240,6 +250,10 @@ int nasal_runtime::main_progress()
std::cout<<">> [runtime] main_progress: cannot use continue in main progress."<<std::endl;
++error;
break;
case rt_return:
std::cout<<">> [runtime] main_progress: cannot use return in main progress."<<std::endl;
++error;
break;
case rt_error:
std::cout<<">> [runtime] main_progress: error occurred when executing main progress."<<std::endl;
++error;
@ -312,13 +326,17 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr)
case ast_continue:
ret_state=rt_continue;
break;
case ast_return:
ret_state=rt_return;
function_returned_address=calculation(root.get_children()[i].get_children()[0],local_scope_addr);
break;
}
if(ret_state==rt_error)
{
std::cout<<">> [runtime] block_progress: error occurred when executing sub-progress."<<std::endl;
++error;
}
if(error)
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
break;
}
nasal_vm.del_reference(local_scope_addr);
@ -354,15 +372,25 @@ int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr)
}
nasal_vm.add_reference(value_address);
int call_expr_size=node.get_children().size();
int last_call_hash_addr=-1;
for(int i=1;i<call_expr_size;++i)
{
int tmp_value_addr=-1;
nasal_ast& call_expr=node.get_children()[i];
switch(call_expr.get_type())
{
case ast_call_vec:tmp_value_addr=call_vector(call_expr,value_address,local_scope_addr);break;
case ast_call_hash:tmp_value_addr=call_hash(call_expr,value_address,local_scope_addr);break;
case ast_call_func:tmp_value_addr=call_function(call_expr,value_address,local_scope_addr);break;
case ast_call_vec:
tmp_value_addr=call_vector(call_expr,value_address,local_scope_addr);
last_call_hash_addr=-1;
break;
case ast_call_hash:
tmp_value_addr=call_hash(call_expr,value_address,local_scope_addr);
last_call_hash_addr=value_address;
break;
case ast_call_func:
tmp_value_addr=call_function(call_expr,value_address,last_call_hash_addr,local_scope_addr);
last_call_hash_addr=-1;
break;
}
nasal_vm.del_reference(value_address);
value_address=tmp_value_addr;
@ -636,16 +664,41 @@ int nasal_runtime::call_hash(nasal_ast& node,int base_value_addr,int local_scope
nasal_vm.add_reference(ret_value_addr);
return ret_value_addr;
}
int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int local_scope_addr)
int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_call_hash_addr,int local_scope_addr)
{
int ret_value_addr=-1;
int value_type=nasal_vm.gc_get(base_value_addr).get_type();
if(value_type!=vm_function)
{
std::cout<<">> [runtime] call_function: incorrect value type,expected a function."<<std::endl;
return -1;
}
nasal_function& reference_of_func=nasal_vm.gc_get(base_value_addr).get_func();
int run_closure_addr=reference_of_func.get_closure_addr();
nasal_closure& run_closure=nasal_vm.gc_get(run_closure_addr).get_closure();
run_closure.add_scope();
nasal_vm.add_reference(last_call_hash_addr);
run_closure.add_new_value("me",last_call_hash_addr);
// unfinished
return -1;
nasal_ast& argument_format=reference_of_func.get_arguments();
if(!node.get_children().size())
{
;
}
else if(node.get_children()[0].get_type()==ast_hashmember)
{
;
}
else
{
;
}
int ret_state=block_progress(reference_of_func.get_run_block(),run_closure_addr); //?
run_closure.del_scope();
ret_value_addr=function_returned_address;
function_returned_address=-1;
return ret_value_addr;
}
int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
{