update
This commit is contained in:
parent
c186d3b030
commit
5899c6e378
|
@ -49,7 +49,6 @@ int main()
|
||||||
std::cin>>command;
|
std::cin>>command;
|
||||||
if(command=="help")
|
if(command=="help")
|
||||||
{
|
{
|
||||||
std::cout<<">> Be careful that this program does not support unicode(unicode will be set to \'?\')"<<std::endl;
|
|
||||||
std::cout<<">> [\'file\'] input a file."<<std::endl;
|
std::cout<<">> [\'file\'] input a file."<<std::endl;
|
||||||
std::cout<<">> [cls ] clear the screen."<<std::endl;
|
std::cout<<">> [cls ] clear the screen."<<std::endl;
|
||||||
std::cout<<">> [del ] clear the resource code."<<std::endl;
|
std::cout<<">> [del ] clear the resource code."<<std::endl;
|
||||||
|
|
|
@ -10,94 +10,96 @@
|
||||||
|
|
||||||
class nasal_function
|
class nasal_function
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::list<std::map<std::string,int> > local_scope;
|
// closure_updated flag is used to mark if this function's closure is updated.
|
||||||
abstract_syntax_tree parameter_list;
|
// to avoid some unexpected errors,closure of each function must be updated before blocks popping back the last scope
|
||||||
abstract_syntax_tree function_root;
|
bool closure_updated;
|
||||||
// parent_hash_addr is used to store the address of the hash which has this nasal_function
|
std::list<std::map<std::string,int> > local_scope;
|
||||||
// because nasal_function needs this address to adjust the identifier called 'me' in local_scope
|
abstract_syntax_tree parameter_list;
|
||||||
// 'me' is the identifier which points to the hash which has this nasal_function
|
abstract_syntax_tree function_root;
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
void set_local_scope(std::list<std::map<std::string,int> >&);
|
void set_local_scope(std::list<std::map<std::string,int> >&);
|
||||||
void set_paramemter_list(abstract_syntax_tree&);
|
bool get_closure_update_state();
|
||||||
void set_statement_block(abstract_syntax_tree&);
|
void set_closure_update_state(bool);
|
||||||
std::list<std::map<std::string,int> >& get_local_scope();
|
void set_paramemter_list(abstract_syntax_tree&);
|
||||||
abstract_syntax_tree& get_parameter_list();
|
void set_statement_block(abstract_syntax_tree&);
|
||||||
abstract_syntax_tree& get_statement_block();
|
std::list<std::map<std::string,int> >& get_local_scope();
|
||||||
void deep_copy(nasal_function&);
|
abstract_syntax_tree& get_parameter_list();
|
||||||
|
abstract_syntax_tree& get_statement_block();
|
||||||
|
void deep_copy(nasal_function&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_number
|
class nasal_number
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
double nas_number;
|
double nas_number;
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
void set_number(double);
|
void set_number(double);
|
||||||
double get_number();
|
double get_number();
|
||||||
void deep_copy(nasal_number&);
|
void deep_copy(nasal_number&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_string
|
class nasal_string
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string nas_string;
|
std::string nas_string;
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
void set_string(std::string);
|
void set_string(std::string);
|
||||||
std::string get_string();
|
std::string get_string();
|
||||||
void deep_copy(nasal_string&);
|
void deep_copy(nasal_string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_vector
|
class nasal_vector
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<int> nas_array;
|
std::vector<int> nas_array;
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
void vec_push(int);
|
void vec_push(int);
|
||||||
int* get_elem_addr(int);
|
int* get_elem_addr(int);
|
||||||
int get_elem(int);
|
int get_elem(int);
|
||||||
int vec_pop();
|
int vec_pop();
|
||||||
int get_size();
|
int get_size();
|
||||||
int* get_parent_hash_member_addr(std::string);
|
int* get_parent_hash_member_addr(std::string);
|
||||||
int get_parent_hash_member(std::string);
|
int get_parent_hash_member(std::string);
|
||||||
void generate_new_hash();
|
void generate_new_hash();
|
||||||
void deep_copy(nasal_vector&);
|
void deep_copy(nasal_vector&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_hash
|
class nasal_hash
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::map<std::string,int> nas_hash;
|
std::map<std::string,int> nas_hash;
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
int* get_hash_member_addr(std::string);
|
int* get_hash_member_addr(std::string);
|
||||||
int get_hash_member(std::string);
|
int get_hash_member(std::string);
|
||||||
void hash_push(std::string,int);
|
void hash_push(std::string,int);
|
||||||
void hash_pop(std::string);
|
void hash_pop(std::string);
|
||||||
void deep_copy(nasal_hash&);
|
void deep_copy(nasal_hash&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_scalar
|
class nasal_scalar
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int type;
|
int type;
|
||||||
nasal_string var_string;
|
nasal_string var_string;
|
||||||
nasal_number var_number;
|
nasal_number var_number;
|
||||||
nasal_vector var_vector;
|
nasal_vector var_vector;
|
||||||
nasal_hash var_hash;
|
nasal_hash var_hash;
|
||||||
nasal_function var_func;
|
nasal_function var_func;
|
||||||
public:
|
public:
|
||||||
nasal_scalar();
|
nasal_scalar();
|
||||||
void set_type(int);
|
void set_type(int);
|
||||||
int get_type();
|
int get_type();
|
||||||
nasal_number& get_number();
|
nasal_number& get_number();
|
||||||
nasal_string& get_string();
|
nasal_string& get_string();
|
||||||
nasal_vector& get_vector();
|
nasal_vector& get_vector();
|
||||||
nasal_hash& get_hash();
|
nasal_hash& get_hash();
|
||||||
nasal_function& get_function();
|
nasal_function& get_function();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gc_unit
|
struct gc_unit
|
||||||
|
@ -126,208 +128,208 @@ struct memory_block
|
||||||
|
|
||||||
class memory_block_list
|
class memory_block_list
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
memory_block* head;
|
memory_block* head;
|
||||||
int mem_size;
|
int mem_size;
|
||||||
int blk_size;
|
int blk_size;
|
||||||
public:
|
public:
|
||||||
memory_block_list()
|
memory_block_list()
|
||||||
|
{
|
||||||
|
mem_size=0;
|
||||||
|
blk_size=1;
|
||||||
|
head=new memory_block;
|
||||||
|
head->next=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
~memory_block_list()
|
||||||
|
{
|
||||||
|
mem_size=0;
|
||||||
|
blk_size=0;
|
||||||
|
memory_block* ptr=head;
|
||||||
|
while(ptr)
|
||||||
{
|
{
|
||||||
mem_size=0;
|
memory_block* tmp_ptr=ptr;
|
||||||
blk_size=1;
|
ptr=ptr->next;
|
||||||
head=new memory_block;
|
delete tmp_ptr;
|
||||||
head->next=NULL;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
~memory_block_list()
|
return;
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
memory_block* ptr=head;
|
||||||
|
while(ptr)
|
||||||
{
|
{
|
||||||
mem_size=0;
|
memory_block* tmp_ptr=ptr;
|
||||||
blk_size=0;
|
ptr=ptr->next;
|
||||||
memory_block* ptr=head;
|
delete tmp_ptr;
|
||||||
while(ptr)
|
|
||||||
{
|
|
||||||
memory_block* tmp_ptr=ptr;
|
|
||||||
ptr=ptr->next;
|
|
||||||
delete tmp_ptr;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
void clear()
|
mem_size=0;
|
||||||
|
blk_size=1;
|
||||||
|
head=new memory_block;
|
||||||
|
head->next=NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gc_unit& operator[](int address)
|
||||||
|
{
|
||||||
|
int block_num=address/NAS_POOL_SIZE;
|
||||||
|
int block_plc=address%NAS_POOL_SIZE;
|
||||||
|
memory_block* ptr=head;
|
||||||
|
for(int i=0;i<block_num;++i)
|
||||||
|
ptr=ptr->next;
|
||||||
|
return ptr->space[block_plc];
|
||||||
|
}
|
||||||
|
void push_back()
|
||||||
|
{
|
||||||
|
++mem_size;
|
||||||
|
if(mem_size>blk_size*NAS_POOL_SIZE)
|
||||||
{
|
{
|
||||||
memory_block* ptr=head;
|
memory_block* ptr=head;
|
||||||
while(ptr)
|
while(ptr->next)
|
||||||
{
|
|
||||||
memory_block* tmp_ptr=ptr;
|
|
||||||
ptr=ptr->next;
|
ptr=ptr->next;
|
||||||
delete tmp_ptr;
|
ptr->next=new memory_block;
|
||||||
}
|
ptr->next->next=NULL;
|
||||||
mem_size=0;
|
++blk_size;
|
||||||
blk_size=1;
|
|
||||||
head=new memory_block;
|
|
||||||
head->next=NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gc_unit& operator[](int address)
|
|
||||||
{
|
|
||||||
int block_num=address/NAS_POOL_SIZE;
|
|
||||||
int block_plc=address%NAS_POOL_SIZE;
|
|
||||||
memory_block* ptr=head;
|
|
||||||
for(int i=0;i<block_num;++i)
|
|
||||||
ptr=ptr->next;
|
|
||||||
return ptr->space[block_plc];
|
|
||||||
}
|
|
||||||
void push_back()
|
|
||||||
{
|
|
||||||
++mem_size;
|
|
||||||
if(mem_size>blk_size*NAS_POOL_SIZE)
|
|
||||||
{
|
|
||||||
memory_block* ptr=head;
|
|
||||||
while(ptr->next)
|
|
||||||
ptr=ptr->next;
|
|
||||||
ptr->next=new memory_block;
|
|
||||||
ptr->next->next=NULL;
|
|
||||||
++blk_size;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int size()
|
|
||||||
{
|
|
||||||
return mem_size;
|
|
||||||
}
|
|
||||||
int capacity()
|
|
||||||
{
|
|
||||||
return NAS_POOL_SIZE*blk_size;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int size()
|
||||||
|
{
|
||||||
|
return mem_size;
|
||||||
|
}
|
||||||
|
int capacity()
|
||||||
|
{
|
||||||
|
return NAS_POOL_SIZE*blk_size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class gc_manager
|
class gc_manager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// free_space list is used to store space that is not in use.
|
// free_space list is used to store space that is not in use.
|
||||||
std::list<int> free_space;
|
std::list<int> free_space;
|
||||||
/*
|
/*
|
||||||
cannot use std::vector to simulate memory
|
cannot use std::vector to simulate memory
|
||||||
because if vector memory is not enough,vector will use another larger memory as it's main memory
|
because if vector memory is not enough,vector will use another larger memory as it's main memory
|
||||||
then all the things will be moved to a new space,
|
then all the things will be moved to a new space,
|
||||||
at this time if you reference a member in it,this will cause segmentation error.
|
at this time if you reference a member in it,this will cause segmentation error.
|
||||||
*/
|
*/
|
||||||
memory_block_list memory;
|
memory_block_list memory;
|
||||||
bool error_occurred;
|
bool error_occurred;
|
||||||
public:
|
public:
|
||||||
void gc_init()
|
void gc_init()
|
||||||
|
{
|
||||||
|
// this function must be called in class nasal_runtime before running any codes
|
||||||
|
memory.clear();
|
||||||
|
free_space.clear();
|
||||||
|
error_occurred=false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int gc_alloc()
|
||||||
|
{
|
||||||
|
// add a new space for a new value
|
||||||
|
// if list free_space is not empty,it will get the address at the front and give it to the new value
|
||||||
|
// if list free_space is empty,it will add new space in memory vector and give it to the new value
|
||||||
|
// by this way it can manage memory efficiently.
|
||||||
|
if(free_space.empty())
|
||||||
{
|
{
|
||||||
// this function must be called in class nasal_runtime before running any codes
|
memory.push_back();
|
||||||
memory.clear();
|
free_space.push_back(memory.size()-1);
|
||||||
free_space.clear();
|
|
||||||
error_occurred=false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
int gc_alloc()
|
int alloc_plc=free_space.front();
|
||||||
|
free_space.pop_front();
|
||||||
|
memory[alloc_plc].collected=false;
|
||||||
|
memory[alloc_plc].refcnt=1;
|
||||||
|
return alloc_plc;
|
||||||
|
}
|
||||||
|
int get_reference(int addr)
|
||||||
|
{
|
||||||
|
// get the reference counts of the scalar
|
||||||
|
return memory[addr].refcnt;
|
||||||
|
}
|
||||||
|
nasal_scalar& get_scalar(int addr)
|
||||||
|
{
|
||||||
|
// get the reference of the scalar
|
||||||
|
return memory[addr].elem;
|
||||||
|
}
|
||||||
|
bool place_check(const int addr)
|
||||||
|
{
|
||||||
|
// check if this place is in memory
|
||||||
|
// and this place is uncollected
|
||||||
|
// this function is often used when an identifier is calling a space in memory
|
||||||
|
return (0<=addr) && (addr<memory.size()) && (!memory[addr].collected);
|
||||||
|
}
|
||||||
|
bool reference_add(const int addr)
|
||||||
|
{
|
||||||
|
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
||||||
|
++memory[addr].refcnt;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// add a new space for a new value
|
std::cout<<">> [Gc] fatal error: reference unexpected memory place ";
|
||||||
// if list free_space is not empty,it will get the address at the front and give it to the new value
|
prt_hex(addr);
|
||||||
// if list free_space is empty,it will add new space in memory vector and give it to the new value
|
std::cout<<" ."<<std::endl;
|
||||||
// by this way it can manage memory efficiently.
|
return false;
|
||||||
if(free_space.empty())
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool reference_delete(const int addr)
|
||||||
|
{
|
||||||
|
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
||||||
|
{
|
||||||
|
--memory[addr].refcnt;
|
||||||
|
if(!memory[addr].refcnt)
|
||||||
{
|
{
|
||||||
memory.push_back();
|
// if refcnt is 0,then starting the destructor
|
||||||
free_space.push_back(memory.size()-1);
|
// std::cout<<">> [Gc] collected ";prt_hex(addr);std::cout<<std::endl;
|
||||||
}
|
memory[addr].collected=true;
|
||||||
int alloc_plc=free_space.front();
|
switch(memory[addr].elem.get_type())
|
||||||
free_space.pop_front();
|
|
||||||
memory[alloc_plc].collected=false;
|
|
||||||
memory[alloc_plc].refcnt=1;
|
|
||||||
return alloc_plc;
|
|
||||||
}
|
|
||||||
int get_reference(int addr)
|
|
||||||
{
|
|
||||||
// get the reference counts of the scalar
|
|
||||||
return memory[addr].refcnt;
|
|
||||||
}
|
|
||||||
nasal_scalar& get_scalar(int addr)
|
|
||||||
{
|
|
||||||
// get the reference of the scalar
|
|
||||||
return memory[addr].elem;
|
|
||||||
}
|
|
||||||
bool place_check(const int addr)
|
|
||||||
{
|
|
||||||
// check if this place is in memory
|
|
||||||
// and this place is uncollected
|
|
||||||
// this function is often used when an identifier is calling a space in memory
|
|
||||||
return (0<=addr) && (addr<memory.size()) && (!memory[addr].collected);
|
|
||||||
}
|
|
||||||
bool reference_add(const int addr)
|
|
||||||
{
|
|
||||||
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
|
||||||
++memory[addr].refcnt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout<<">> [Gc] fatal error: reference unexpected memory place ";
|
|
||||||
prt_hex(addr);
|
|
||||||
std::cout<<" ."<<std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool reference_delete(const int addr)
|
|
||||||
{
|
|
||||||
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
|
||||||
{
|
|
||||||
--memory[addr].refcnt;
|
|
||||||
if(!memory[addr].refcnt)
|
|
||||||
{
|
{
|
||||||
// if refcnt is 0,then starting the destructor
|
case scalar_number: memory[addr].elem.get_number().set_clear(); break;
|
||||||
// std::cout<<">> [Gc] collected ";prt_hex(addr);std::cout<<std::endl;
|
case scalar_string: memory[addr].elem.get_string().set_clear(); break;
|
||||||
memory[addr].collected=true;
|
case scalar_vector: memory[addr].elem.get_vector().set_clear(); break;
|
||||||
switch(memory[addr].elem.get_type())
|
case scalar_hash: memory[addr].elem.get_hash().set_clear(); break;
|
||||||
{
|
case scalar_function:memory[addr].elem.get_function().set_clear();break;
|
||||||
case scalar_number: memory[addr].elem.get_number().set_clear(); break;
|
default:break;
|
||||||
case scalar_string: memory[addr].elem.get_string().set_clear(); break;
|
|
||||||
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;
|
|
||||||
default:break;
|
|
||||||
}
|
|
||||||
memory[addr].elem.set_type(scalar_nil);
|
|
||||||
free_space.push_back(addr);
|
|
||||||
}
|
}
|
||||||
|
memory[addr].elem.set_type(scalar_nil);
|
||||||
|
free_space.push_back(addr);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout<<">> [Gc] fatal error: delete unexpected memory address: ";
|
||||||
|
prt_hex(addr);
|
||||||
|
std::cout<<" ."<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void info_print()
|
||||||
|
{
|
||||||
|
std::cout<<">> [Gc] memory size:"<<memory.size()*sizeof(gc_unit)<<" byte."<<std::endl;
|
||||||
|
std::cout<<">> [Gc] memory capacity:"<<memory.capacity()*sizeof(gc_unit)<<" byte."<<std::endl;
|
||||||
|
std::cout<<">> [Gc] memory usage: "<<std::endl;
|
||||||
|
int cnt=0;
|
||||||
|
for(int i=0;i<memory.size();++i)
|
||||||
|
if(!memory[i].collected)
|
||||||
{
|
{
|
||||||
std::cout<<">> [Gc] fatal error: delete unexpected memory address: ";
|
prt_hex(i);
|
||||||
prt_hex(addr);
|
std::cout<<"["<<memory[i].refcnt<<"]";
|
||||||
std::cout<<" ."<<std::endl;
|
// cnt is used to check if it is the right time to output in the next line
|
||||||
return false;
|
++cnt;
|
||||||
|
if(!(cnt%8))
|
||||||
|
std::cout<<std::endl;
|
||||||
|
else
|
||||||
|
std::cout<<" ";
|
||||||
}
|
}
|
||||||
return true;
|
if(cnt%8)
|
||||||
}
|
std::cout<<std::endl;
|
||||||
void info_print()
|
return;
|
||||||
{
|
}
|
||||||
std::cout<<">> [Gc] memory size:"<<memory.size()*sizeof(gc_unit)<<" byte."<<std::endl;
|
bool check_error()
|
||||||
std::cout<<">> [Gc] memory capacity:"<<memory.capacity()*sizeof(gc_unit)<<" byte."<<std::endl;
|
{
|
||||||
std::cout<<">> [Gc] memory usage: "<<std::endl;
|
return error_occurred;
|
||||||
int cnt=0;
|
}
|
||||||
for(int i=0;i<memory.size();++i)
|
|
||||||
if(!memory[i].collected)
|
|
||||||
{
|
|
||||||
prt_hex(i);
|
|
||||||
std::cout<<"["<<memory[i].refcnt<<"]";
|
|
||||||
// cnt is used to check if it is the right time to output in the next line
|
|
||||||
++cnt;
|
|
||||||
if(!(cnt%8))
|
|
||||||
std::cout<<std::endl;
|
|
||||||
else
|
|
||||||
std::cout<<" ";
|
|
||||||
}
|
|
||||||
if(cnt%8)
|
|
||||||
std::cout<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool check_error()
|
|
||||||
{
|
|
||||||
return error_occurred;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
gc_manager nasal_gc;
|
gc_manager nasal_gc;
|
||||||
// this object is used in "nasal_runtime.h"
|
// this object is used in "nasal_runtime.h"
|
||||||
|
@ -339,18 +341,31 @@ void nasal_function::set_clear()
|
||||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
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)
|
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||||
nasal_gc.reference_delete(i->second);
|
nasal_gc.reference_delete(i->second);
|
||||||
|
closure_updated=false;
|
||||||
local_scope.clear();
|
local_scope.clear();
|
||||||
function_root.set_clear();
|
function_root.set_clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_function::set_local_scope(std::list<std::map<std::string,int> >& tmp_scope)
|
void nasal_function::set_local_scope(std::list<std::map<std::string,int> >& 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_delete(i->second);
|
||||||
local_scope=tmp_scope;
|
local_scope=tmp_scope;
|
||||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
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)
|
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||||
nasal_gc.reference_add(i->second);
|
nasal_gc.reference_add(i->second);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool nasal_function::get_closure_update_state()
|
||||||
|
{
|
||||||
|
return closure_updated;
|
||||||
|
}
|
||||||
|
void nasal_function::set_closure_update_state(bool _state)
|
||||||
|
{
|
||||||
|
closure_updated=_state;
|
||||||
|
return;
|
||||||
|
}
|
||||||
void nasal_function::set_paramemter_list(abstract_syntax_tree& para_list)
|
void nasal_function::set_paramemter_list(abstract_syntax_tree& para_list)
|
||||||
{
|
{
|
||||||
parameter_list=para_list;
|
parameter_list=para_list;
|
||||||
|
|
|
@ -100,6 +100,7 @@ class nasal_runtime
|
||||||
int vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);//checked
|
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 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
|
int function_generation(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
||||||
|
void update_closure (std::list<std::map<std::string,int> >&);
|
||||||
bool check_condition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);// checked
|
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 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);
|
int assignment (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,int);
|
||||||
|
@ -1463,6 +1464,7 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
||||||
int addr=nasal_gc.gc_alloc();
|
int addr=nasal_gc.gc_alloc();
|
||||||
nasal_gc.get_scalar(addr).set_type(scalar_function);
|
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(local_scope);
|
||||||
|
nasal_gc.get_scalar(addr).get_function().set_closure_update_state(false);
|
||||||
|
|
||||||
std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();
|
std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();
|
||||||
nasal_gc.get_scalar(addr).get_function().set_paramemter_list(*i);
|
nasal_gc.get_scalar(addr).get_function().set_paramemter_list(*i);
|
||||||
|
@ -2054,6 +2056,20 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
void nasal_runtime::update_closure(std::list<std::map<std::string,int> >& local_scope)
|
||||||
|
{
|
||||||
|
// update_closure
|
||||||
|
if(!local_scope.size())
|
||||||
|
return;
|
||||||
|
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().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);
|
||||||
|
nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool nasal_runtime::check_condition(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
bool nasal_runtime::check_condition(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
{
|
{
|
||||||
bool ret=false;
|
bool ret=false;
|
||||||
|
@ -4403,11 +4419,13 @@ int nasal_runtime::block_proc(std::list<std::map<std::string,int> >& local_scope
|
||||||
if(state==__state_break || state==__state_continue || state==__state_return || state==__state_error)
|
if(state==__state_break || state==__state_continue || state==__state_return || state==__state_error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// update_closure
|
||||||
|
update_closure(local_scope);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
int nasal_runtime::func_proc(
|
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> >& 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& parameter_list, // parameter list format of nasal function
|
||||||
abstract_syntax_tree& func_root, // main runnning block 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
|
abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function
|
||||||
|
@ -4596,6 +4614,8 @@ int nasal_runtime::func_proc(
|
||||||
function_returned_addr=nasal_gc.gc_alloc();
|
function_returned_addr=nasal_gc.gc_alloc();
|
||||||
nasal_gc.get_scalar(function_returned_addr).set_type(scalar_nil);
|
nasal_gc.get_scalar(function_returned_addr).set_type(scalar_nil);
|
||||||
}
|
}
|
||||||
|
// update closure
|
||||||
|
update_closure(local_scope);
|
||||||
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
||||||
nasal_gc.reference_delete(i->second);
|
nasal_gc.reference_delete(i->second);
|
||||||
local_scope.pop_back();
|
local_scope.pop_back();
|
||||||
|
|
Loading…
Reference in New Issue