update
This commit is contained in:
parent
5899c6e378
commit
a245a8503e
|
@ -229,7 +229,8 @@ enum scalar_type
|
|||
scalar_string,
|
||||
scalar_vector,
|
||||
scalar_hash,
|
||||
scalar_function
|
||||
scalar_function,
|
||||
scalar_closure
|
||||
};
|
||||
// print types that used in nasal_runtime and nasal_gc
|
||||
void print_scalar_type(const int type)
|
||||
|
@ -242,6 +243,7 @@ void print_scalar_type(const int type)
|
|||
case scalar_vector: std::cout<<"vector";break;
|
||||
case scalar_hash: std::cout<<"hash";break;
|
||||
case scalar_function: std::cout<<"function";break;
|
||||
case scalar_closure: std::cout<<"closure";break;
|
||||
default: std::cout<<"nil";break;
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -8,23 +8,35 @@
|
|||
// the identifier will get a new memory space in nasal_gc and do deep_copy()
|
||||
// and the memory space that is not used ,its ref_cnt-=1.
|
||||
|
||||
class nasal_closure
|
||||
{
|
||||
private:
|
||||
std::list<std::map<std::string,int> > closure;
|
||||
public:
|
||||
void set_clear();
|
||||
void set_local_scope(std::list<std::map<std::string,int> >&);
|
||||
std::list<std::map<std::string,int> >& get_local_scope();
|
||||
void print_closure_ids();
|
||||
};
|
||||
|
||||
class nasal_function
|
||||
{
|
||||
private:
|
||||
// closure_updated flag is used to mark if this function's closure is updated.
|
||||
// to avoid some unexpected errors,closure of each function must be updated before blocks popping back the last scope
|
||||
bool closure_updated;
|
||||
std::list<std::map<std::string,int> > local_scope;
|
||||
int closure_addr;
|
||||
abstract_syntax_tree parameter_list;
|
||||
abstract_syntax_tree function_root;
|
||||
public:
|
||||
nasal_function();
|
||||
void set_clear();
|
||||
void set_local_scope(std::list<std::map<std::string,int> >&);
|
||||
void set_local_scope(int);
|
||||
bool get_closure_update_state();
|
||||
void set_closure_update_state(bool);
|
||||
void set_paramemter_list(abstract_syntax_tree&);
|
||||
void set_statement_block(abstract_syntax_tree&);
|
||||
std::list<std::map<std::string,int> >& get_local_scope();
|
||||
int get_local_scope();
|
||||
abstract_syntax_tree& get_parameter_list();
|
||||
abstract_syntax_tree& get_statement_block();
|
||||
void deep_copy(nasal_function&);
|
||||
|
@ -91,6 +103,7 @@ private:
|
|||
nasal_vector var_vector;
|
||||
nasal_hash var_hash;
|
||||
nasal_function var_func;
|
||||
nasal_closure var_cls;
|
||||
public:
|
||||
nasal_scalar();
|
||||
void set_type(int);
|
||||
|
@ -100,6 +113,7 @@ public:
|
|||
nasal_vector& get_vector();
|
||||
nasal_hash& get_hash();
|
||||
nasal_function& get_function();
|
||||
nasal_closure& get_closure();
|
||||
};
|
||||
|
||||
struct gc_unit
|
||||
|
@ -245,6 +259,8 @@ public:
|
|||
int get_reference(int addr)
|
||||
{
|
||||
// get the reference counts of the scalar
|
||||
if(addr>=memory.size())
|
||||
return -1;
|
||||
return memory[addr].refcnt;
|
||||
}
|
||||
nasal_scalar& get_scalar(int addr)
|
||||
|
@ -289,6 +305,7 @@ public:
|
|||
case scalar_vector: memory[addr].elem.get_vector().set_clear(); break;
|
||||
case scalar_hash: memory[addr].elem.get_hash().set_clear(); break;
|
||||
case scalar_function:memory[addr].elem.get_function().set_clear();break;
|
||||
case scalar_closure: memory[addr].elem.get_closure().set_clear(); break;
|
||||
default:break;
|
||||
}
|
||||
memory[addr].elem.set_type(scalar_nil);
|
||||
|
@ -335,26 +352,65 @@ gc_manager nasal_gc;
|
|||
// this object is used in "nasal_runtime.h"
|
||||
// because there must be only one gc when running a program(one process)
|
||||
|
||||
|
||||
void nasal_function::set_clear()
|
||||
void nasal_closure::set_clear()
|
||||
{
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||
if(!closure.size())
|
||||
return;
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=closure.begin();iter!=closure.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_delete(i->second);
|
||||
closure.clear();
|
||||
return;
|
||||
}
|
||||
void nasal_closure::set_local_scope(std::list<std::map<std::string,int> >& tmp_scope)
|
||||
{
|
||||
if(closure.size())
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=closure.begin();iter!=closure.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_delete(i->second);
|
||||
closure.clear();
|
||||
closure=tmp_scope;
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=closure.begin();iter!=closure.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_add(i->second);
|
||||
return;
|
||||
}
|
||||
std::list<std::map<std::string,int> >& nasal_closure::get_local_scope()
|
||||
{
|
||||
return closure;
|
||||
}
|
||||
void nasal_closure::print_closure_ids()
|
||||
{
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=closure.begin();iter!=closure.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
{
|
||||
std::cout<<i->first<<": ";
|
||||
prt_hex(i->second);
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_function::nasal_function()
|
||||
{
|
||||
closure_updated=false;
|
||||
local_scope.clear();
|
||||
closure_addr=-1;
|
||||
return;
|
||||
}
|
||||
void nasal_function::set_clear()
|
||||
{
|
||||
closure_updated=false;
|
||||
if(closure_addr>=0)
|
||||
nasal_gc.reference_delete(closure_addr);
|
||||
closure_addr=-1;
|
||||
function_root.set_clear();
|
||||
return;
|
||||
}
|
||||
void nasal_function::set_local_scope(std::list<std::map<std::string,int> >& tmp_scope)
|
||||
void nasal_function::set_local_scope(int tmp_addr)
|
||||
{
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_delete(i->second);
|
||||
local_scope=tmp_scope;
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_add(i->second);
|
||||
if(closure_addr>=0)
|
||||
nasal_gc.reference_delete(closure_addr);
|
||||
closure_addr=tmp_addr;
|
||||
return;
|
||||
}
|
||||
bool nasal_function::get_closure_update_state()
|
||||
|
@ -376,9 +432,9 @@ void nasal_function::set_statement_block(abstract_syntax_tree& func_block)
|
|||
function_root=func_block;
|
||||
return;
|
||||
}
|
||||
std::list<std::map<std::string,int> >& nasal_function::get_local_scope()
|
||||
int nasal_function::get_local_scope()
|
||||
{
|
||||
return local_scope;
|
||||
return closure_addr;
|
||||
}
|
||||
abstract_syntax_tree& nasal_function::get_parameter_list()
|
||||
{
|
||||
|
@ -390,17 +446,10 @@ abstract_syntax_tree& nasal_function::get_statement_block()
|
|||
}
|
||||
void nasal_function::deep_copy(nasal_function& tmp)
|
||||
{
|
||||
// before deep copy nasal_functions needs to delete all values in its scope
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_delete(i->second);
|
||||
// when copying a local scope,one thing that must be noticed is that
|
||||
// each identifier in local_scope shares the same address with tmp.local_scope
|
||||
// copy all the values in tmp's scope
|
||||
local_scope=tmp.local_scope;
|
||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_add(i->second);
|
||||
if(closure_addr>=0)
|
||||
nasal_gc.reference_delete(closure_addr);
|
||||
closure_addr=tmp.closure_addr;
|
||||
nasal_gc.reference_add(closure_addr);
|
||||
// copy abstract_syntax_tree
|
||||
parameter_list=tmp.parameter_list;
|
||||
function_root=tmp.function_root;
|
||||
|
@ -624,7 +673,7 @@ nasal_scalar::nasal_scalar()
|
|||
void nasal_scalar::set_type(int tmp_type)
|
||||
{
|
||||
// scalar_function is the last enum in enum::scalar_type
|
||||
type=tmp_type>scalar_function? scalar_nil:tmp_type;
|
||||
type=tmp_type>scalar_closure? scalar_nil:tmp_type;
|
||||
return;
|
||||
}
|
||||
int nasal_scalar::get_type()
|
||||
|
@ -657,6 +706,11 @@ nasal_function& nasal_scalar::get_function()
|
|||
// get nasal_function
|
||||
return var_func;
|
||||
}
|
||||
nasal_closure& nasal_scalar::get_closure()
|
||||
{
|
||||
// get nasal_closure
|
||||
return var_cls;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ class nasal_runtime
|
|||
int vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);//checked
|
||||
int hash_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int function_generation(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
void update_closure (std::list<std::map<std::string,int> >&);
|
||||
void update_closure (std::list<std::map<std::string,int> >&,int);
|
||||
bool check_condition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int assignment (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,int);
|
||||
|
@ -109,7 +109,7 @@ class nasal_runtime
|
|||
int loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int block_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||
int func_proc (std::list<std::map<std::string,int> >&,std::list<std::map<std::string,int> >,abstract_syntax_tree&,abstract_syntax_tree&,abstract_syntax_tree&,int);// checked
|
||||
int func_proc (std::list<std::map<std::string,int> >&,std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&,abstract_syntax_tree&,int);// checked
|
||||
int inline_function (std::list<std::map<std::string,int> >&,std::string);
|
||||
public:
|
||||
nasal_runtime()
|
||||
|
@ -802,7 +802,7 @@ int nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& loca
|
|||
int tmp_addr=addr;
|
||||
addr=func_proc(
|
||||
local_scope,
|
||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||
nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_function().get_local_scope()).get_closure().get_local_scope(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||
*call_node,
|
||||
|
@ -1443,7 +1443,7 @@ int nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_
|
|||
int tmp_addr=addr;
|
||||
addr=func_proc(
|
||||
local_scope,
|
||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||
nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_function().get_local_scope()).get_closure().get_local_scope(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||
*call_node,
|
||||
|
@ -1462,8 +1462,11 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
|||
// block
|
||||
// calls...
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
int scope_addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(scope_addr).set_type(scalar_closure);
|
||||
nasal_gc.get_scalar(scope_addr).get_closure().set_local_scope(local_scope);
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_function);
|
||||
nasal_gc.get_scalar(addr).get_function().set_local_scope(local_scope);
|
||||
nasal_gc.get_scalar(addr).get_function().set_local_scope(scope_addr);
|
||||
nasal_gc.get_scalar(addr).get_function().set_closure_update_state(false);
|
||||
|
||||
std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();
|
||||
|
@ -2044,7 +2047,7 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
|||
int tmp_addr=addr;
|
||||
addr=func_proc(
|
||||
local_scope,
|
||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||
nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_function().get_local_scope()).get_closure().get_local_scope(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||
*call_node,
|
||||
|
@ -2056,7 +2059,7 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
void nasal_runtime::update_closure(std::list<std::map<std::string,int> >& local_scope)
|
||||
void nasal_runtime::update_closure(std::list<std::map<std::string,int> >& local_scope,int local_scope_addr)
|
||||
{
|
||||
// update_closure
|
||||
if(!local_scope.size())
|
||||
|
@ -2065,7 +2068,16 @@ void nasal_runtime::update_closure(std::list<std::map<std::string,int> >& local_
|
|||
if(nasal_gc.get_scalar(i->second).get_type()==scalar_function &&
|
||||
!nasal_gc.get_scalar(i->second).get_function().get_closure_update_state())
|
||||
{
|
||||
nasal_gc.get_scalar(i->second).get_function().set_local_scope(local_scope);
|
||||
nasal_gc.get_scalar(i->second).get_function().set_local_scope(local_scope_addr);
|
||||
nasal_gc.reference_add(local_scope_addr);
|
||||
nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true);
|
||||
}
|
||||
for(std::map<std::string,int>::iterator i=global_scope.begin();i!=global_scope.end();++i)
|
||||
if(nasal_gc.get_scalar(i->second).get_type()==scalar_function &&
|
||||
!nasal_gc.get_scalar(i->second).get_function().get_closure_update_state())
|
||||
{
|
||||
nasal_gc.get_scalar(i->second).get_function().set_local_scope(local_scope_addr);
|
||||
nasal_gc.reference_add(local_scope_addr);
|
||||
nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true);
|
||||
}
|
||||
return;
|
||||
|
@ -3975,7 +3987,7 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
|||
int tmp_addr=addr;
|
||||
addr=func_proc(
|
||||
local_scope,
|
||||
nasal_gc.get_scalar(addr).get_function().get_local_scope(),
|
||||
nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_function().get_local_scope()).get_closure().get_local_scope(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_parameter_list(),
|
||||
nasal_gc.get_scalar(addr).get_function().get_statement_block(),
|
||||
*iter,
|
||||
|
@ -4420,12 +4432,16 @@ int nasal_runtime::block_proc(std::list<std::map<std::string,int> >& local_scope
|
|||
break;
|
||||
}
|
||||
// update_closure
|
||||
update_closure(local_scope);
|
||||
int closure_addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(closure_addr).set_type(scalar_closure);
|
||||
nasal_gc.get_scalar(closure_addr).get_closure().set_local_scope(local_scope);
|
||||
update_closure(local_scope,closure_addr);
|
||||
nasal_gc.reference_delete(closure_addr);
|
||||
return state;
|
||||
}
|
||||
int nasal_runtime::func_proc(
|
||||
std::list<std::map<std::string,int> >& parameters_assist_scope,// scope that used to generate parameters
|
||||
std::list<std::map<std::string,int> > local_scope, // running scope,often gets the scope that calls it
|
||||
std::list<std::map<std::string,int> >& local_scope,// running scope,often gets the scope that calls it
|
||||
abstract_syntax_tree& parameter_list, // parameter list format of nasal function
|
||||
abstract_syntax_tree& func_root, // main runnning block of nasal function
|
||||
abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function
|
||||
|
@ -4615,7 +4631,11 @@ int nasal_runtime::func_proc(
|
|||
nasal_gc.get_scalar(function_returned_addr).set_type(scalar_nil);
|
||||
}
|
||||
// update closure
|
||||
update_closure(local_scope);
|
||||
int closure_addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(closure_addr).set_type(scalar_closure);
|
||||
nasal_gc.get_scalar(closure_addr).get_closure().set_local_scope(local_scope);
|
||||
update_closure(local_scope,closure_addr);
|
||||
nasal_gc.reference_delete(closure_addr);
|
||||
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
||||
nasal_gc.reference_delete(i->second);
|
||||
local_scope.pop_back();
|
||||
|
@ -4776,9 +4796,23 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
|||
int addr=this->calculation(main_local_scope,*iter);
|
||||
if(addr>=0)
|
||||
nasal_gc.reference_delete(addr);
|
||||
// new functions in global scope must set its closure_update_state to true
|
||||
// or its local scope maybe changed after running other expressions
|
||||
for(std::map<std::string,int>::iterator i=global_scope.begin();i!=global_scope.end();++i)
|
||||
if(nasal_gc.get_scalar(i->second).get_type()==scalar_function &&
|
||||
!nasal_gc.get_scalar(i->second).get_function().get_closure_update_state())
|
||||
nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true);
|
||||
}
|
||||
else if(node_type==__definition)
|
||||
{
|
||||
this->definition(main_local_scope,global_scope,*iter);
|
||||
// new functions in global scope must set its closure_update_state to true
|
||||
// or its local scope maybe changed after running other expressions
|
||||
for(std::map<std::string,int>::iterator i=global_scope.begin();i!=global_scope.end();++i)
|
||||
if(nasal_gc.get_scalar(i->second).get_type()==scalar_function &&
|
||||
!nasal_gc.get_scalar(i->second).get_function().get_closure_update_state())
|
||||
nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true);
|
||||
}
|
||||
else if(node_type==__conditional)
|
||||
state=this->conditional(main_local_scope,*iter);
|
||||
else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))
|
||||
|
|
Loading…
Reference in New Issue