update
This commit is contained in:
parent
0610c02c7a
commit
2dc9f0c560
|
@ -20,6 +20,7 @@ class nasal_function
|
|||
public:
|
||||
nasal_function();
|
||||
void set_clear();
|
||||
void set_local_scope(std::list<std::map<std::string,int> >&);
|
||||
void set_statement_block(abstract_syntax_tree&);
|
||||
void set_parent_hash_addr(int);
|
||||
std::list<std::map<std::string,int> >& get_local_scope();
|
||||
|
@ -72,6 +73,7 @@ class nasal_hash
|
|||
void set_self_addr(int);
|
||||
void set_clear();
|
||||
int get_self_addr();
|
||||
int get_hash_member(std::string);
|
||||
void hash_push(std::string,int);
|
||||
void hash_pop(std::string);
|
||||
void deep_copy(nasal_hash&);
|
||||
|
@ -99,10 +101,11 @@ class nasal_scalar
|
|||
|
||||
struct gc_unit
|
||||
{
|
||||
// collected: If gc collected this item,it'll be set to true.Otherwise it is false.
|
||||
// collected: If gc collected this item,it'll be set to true.Otherwise it is false.
|
||||
// elem: Item that this unit stores
|
||||
// refcnt: Reference counter
|
||||
bool collected;
|
||||
bool is_const;
|
||||
nasal_scalar elem;
|
||||
int refcnt;
|
||||
gc_unit()
|
||||
|
@ -150,12 +153,14 @@ class gc_manager
|
|||
}
|
||||
nasal_scalar& get_scalar(int addr)
|
||||
{
|
||||
// get the reference of the scalar
|
||||
return memory[addr].elem;
|
||||
}
|
||||
bool place_check(const int place)
|
||||
{
|
||||
// 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 (place<memory.size()) && (!memory[place].collected);
|
||||
}
|
||||
void reference_add(const int place)
|
||||
|
@ -241,6 +246,14 @@ void nasal_function::set_clear()
|
|||
parent_hash_addr=-1;
|
||||
return;
|
||||
}
|
||||
void nasal_function::set_local_scope(std::list<std::map<std::string,int> >& 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::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||
nasal_gc.reference_add(i->second);
|
||||
return;
|
||||
}
|
||||
void nasal_function::set_statement_block(abstract_syntax_tree& func_block)
|
||||
{
|
||||
function_root=func_block;
|
||||
|
@ -248,7 +261,31 @@ void nasal_function::set_statement_block(abstract_syntax_tree& func_block)
|
|||
}
|
||||
void nasal_function::set_parent_hash_addr(int addr)
|
||||
{
|
||||
// in normal cases this function is often called after this->set_local_scope(...)
|
||||
// because creating a new nasal function needs local_scope(closure) and abstract syntax tree.
|
||||
// then the nasal function will be given to an identifier.
|
||||
// after checking the identifier and making sure it is a hash,
|
||||
// call this function and set 'me' to this addr if exists.
|
||||
// if 'me' does not exist,then add a new identifeir named 'me' and give it the addr.
|
||||
// also 'me' can be changed in hash function by ways like "var me=1;"
|
||||
parent_hash_addr=addr;
|
||||
bool has_identifier_me=false;
|
||||
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)
|
||||
if(i->first=="me")
|
||||
{
|
||||
has_identifier_me=true;
|
||||
i->second=parent_hash_addr;
|
||||
}
|
||||
if(!has_identifier_me)
|
||||
{
|
||||
if(local_scope.empty())
|
||||
{
|
||||
std::map<std::string,int> new_scope;
|
||||
local_scope.push_back(new_scope);
|
||||
}
|
||||
local_scope.back()["me"]=parent_hash_addr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
std::list<std::map<std::string,int> >& nasal_function::get_local_scope()
|
||||
|
@ -265,27 +302,13 @@ void nasal_function::deep_copy(nasal_function& tmp)
|
|||
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)
|
||||
if(i->first!="me")
|
||||
nasal_gc.reference_add(i->second);
|
||||
// change the 'me' address to this function's parent_hash_addr
|
||||
if(!local_scope.empty())
|
||||
{
|
||||
std::list<std::map<std::string,int> >::iterator begin_iter=local_scope.begin();
|
||||
if(begin_iter->find("me")!=begin_iter->end())
|
||||
{
|
||||
if(parent_hash_addr>=0)
|
||||
{
|
||||
(*begin_iter)["me"]=parent_hash_addr;
|
||||
nasal_gc.reference_add(parent_hash_addr);
|
||||
}
|
||||
else
|
||||
begin_iter->erase("me");
|
||||
}
|
||||
}
|
||||
// copy abstract_syntax_tree
|
||||
function_root=tmp.function_root;
|
||||
return;
|
||||
|
@ -401,6 +424,12 @@ int nasal_hash::get_self_addr()
|
|||
{
|
||||
return self_addr;
|
||||
}
|
||||
int nasal_hash::get_hash_member(std::string member_name)
|
||||
{
|
||||
if(nas_hash.find(member_name)!=nas_hash.end())
|
||||
return nas_hash[member_name];
|
||||
return -1;
|
||||
}
|
||||
void nasal_hash::hash_push(std::string member_name,int addr)
|
||||
{
|
||||
if(nas_hash.find(member_name)==nas_hash.end())
|
||||
|
@ -467,27 +496,58 @@ void nasal_scalar::set_type(int tmp_type)
|
|||
}
|
||||
int nasal_scalar::get_type()
|
||||
{
|
||||
// get scalar type
|
||||
return type;
|
||||
}
|
||||
nasal_number& nasal_scalar::get_number()
|
||||
{
|
||||
// get nasal_number
|
||||
return var_number;
|
||||
}
|
||||
nasal_string& nasal_scalar::get_string()
|
||||
{
|
||||
// get nasal_string
|
||||
return var_string;
|
||||
}
|
||||
nasal_vector& nasal_scalar::get_vector()
|
||||
{
|
||||
// get nasal_vector
|
||||
return var_vector;
|
||||
}
|
||||
nasal_hash& nasal_scalar::get_hash()
|
||||
{
|
||||
// get nasal_hash
|
||||
return var_hash;
|
||||
}
|
||||
nasal_function& nasal_scalar::get_function()
|
||||
{
|
||||
// get nasal_function
|
||||
return var_func;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
code: var i=1;
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_number);
|
||||
nasal_gc.get_scalar(addr).set_number(1);
|
||||
|
||||
code: var i='hello';
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_string);
|
||||
nasal_gc.get_scalar(addr).set_string("hello");
|
||||
|
||||
code: var i=[];
|
||||
int addr=vector_generation();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_vector);
|
||||
|
||||
code: var i={};
|
||||
int addr=hash_generation();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_hash);
|
||||
nasal_gc.get_scalar(addr).get_hash().set_self_addr(addr);
|
||||
|
||||
code: var i=func{return 0;}
|
||||
// copy local_scope if needed
|
||||
// copy abstract_syntax_tree
|
||||
*/
|
|
@ -7,6 +7,7 @@ class nasal_runtime
|
|||
// global scope is a hash_map
|
||||
// main_local_scope is used in main block
|
||||
// when calling a loop or conditional expression
|
||||
// when adding a new identifier into scope,you need to check if this identifier is already in the scope.
|
||||
std::map<std::string,int> global_scope;
|
||||
std::list<std::map<std::string,int> > main_local_scope;
|
||||
|
||||
|
@ -17,16 +18,20 @@ class nasal_runtime
|
|||
__incorrect_head_of_func,
|
||||
__stack_overflow,
|
||||
};
|
||||
void error_interrupt (const int);
|
||||
void vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void hash_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void assignment (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void definition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
int runtime_error_exit_mark;
|
||||
void error_interrupt (const int);
|
||||
int number_generation (abstract_syntax_tree&);
|
||||
int string_generation (abstract_syntax_tree&);
|
||||
int vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
int hash_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
int function_generation(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
int call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void assignment (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void definition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
void func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||
public:
|
||||
nasal_runtime()
|
||||
{
|
||||
|
@ -49,33 +54,117 @@ void nasal_runtime::error_interrupt(const int type)
|
|||
switch (type)
|
||||
{
|
||||
case __incorrect_head_of_tree:
|
||||
std::cout<<error_head<<"the abstract syntax tree's root type is not \'__root\' ."<<std::endl;break;
|
||||
std::cout<<error_head<<"the abstract syntax tree's root type is not \'__root\'.please make sure that lib is loaded."<<std::endl;break;
|
||||
case __incorrect_head_of_func:
|
||||
std::cout<<error_head<<"called identifier is not a function ."<<std::endl;break;
|
||||
std::cout<<error_head<<"called identifier is not a function."<<std::endl;break;
|
||||
case __stack_overflow:
|
||||
std::cout<<error_head<<"stack overflow ."<<std::endl;break;
|
||||
default:break;
|
||||
std::cout<<error_head<<"stack overflow."<<std::endl;break;
|
||||
default:
|
||||
std::cout<<error_head<<"unknown error."<<std::endl;break;
|
||||
}
|
||||
runtime_error_exit_mark=type;
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
int nasal_runtime::number_generation(abstract_syntax_tree& node)
|
||||
{
|
||||
return;
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_number);
|
||||
nasal_gc.get_scalar(addr).get_number().set_number(node.get_var_number());
|
||||
return addr;
|
||||
}
|
||||
void nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
int nasal_runtime::string_generation(abstract_syntax_tree& node)
|
||||
{
|
||||
return;
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_string);
|
||||
nasal_gc.get_scalar(addr).get_string().set_string(node.get_var_string());
|
||||
return addr;
|
||||
}
|
||||
void nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
int nasal_runtime::vector_generation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
return;
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_vector);
|
||||
for(std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();i!=node.get_children().end();++i)
|
||||
{
|
||||
int var_type=i->get_node_type();
|
||||
if(var_type==__number)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(number_generation(*i));
|
||||
else if(var_type==__string)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(string_generation(*i));
|
||||
else if(var_type==__vector)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(vector_generation(local_scope,*i));
|
||||
else if(var_type==__hash)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(hash_generation(local_scope,*i));
|
||||
else if(var_type==__function)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(function_generation(local_scope,*i));
|
||||
else if(var_type==__id)
|
||||
nasal_gc.get_scalar(addr).get_vector().vec_push(call_identifier(local_scope,*i));
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
void nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
int nasal_runtime::hash_generation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
nasal_gc.get_scalar(addr).set_type(scalar_hash);
|
||||
nasal_gc.get_scalar(addr).get_hash().set_self_addr(addr);
|
||||
for(std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();i!=node.get_children().end();++i)
|
||||
{
|
||||
if(i->get_node_type()!=__hash_member)
|
||||
break;
|
||||
else
|
||||
{
|
||||
std::string member_name=i->get_children().front().get_var_string();
|
||||
int var_type=i->get_children().back().get_node_type();
|
||||
if(var_type==__number)
|
||||
;
|
||||
else if(var_type==__string)
|
||||
;
|
||||
else if(var_type==__vector)
|
||||
;
|
||||
else if(var_type==__hash)
|
||||
;
|
||||
else if(var_type==__function)
|
||||
{
|
||||
// hash's function must get a parent_hash_addr
|
||||
// this address will be given to identifier 'me'
|
||||
nasal_gc.get_scalar(addr).get_hash().hash_push(member_name,function_generation(local_scope,i->get_children().back()));
|
||||
nasal_gc.get_scalar(nasal_gc.get_scalar(addr).get_hash().get_hash_member(member_name)).get_function().set_parent_hash_addr(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
int addr=nasal_gc.gc_alloc();
|
||||
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_statement_block(node);
|
||||
return addr;
|
||||
}
|
||||
int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
int operator_type=node.get_node_type();
|
||||
if(operator_type==__add_operator)
|
||||
{
|
||||
node.get_children().front();
|
||||
node.get_children().back();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
if(local_scope.empty())
|
||||
;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
void nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||
{
|
||||
|
@ -131,21 +220,20 @@ void nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope
|
|||
else if(node_type==__hash)
|
||||
this->hash_generation(local_scope,*iter);
|
||||
else if(node_type==__function)
|
||||
{
|
||||
;
|
||||
}
|
||||
this->function_generation(local_scope,*iter);
|
||||
else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator || node_type==__link_operator ||
|
||||
node_type==__cmp_equal || node_type==__cmp_less || node_type==__cmp_more || node_type==__cmp_not_equal || node_type==__cmp_less_or_equal || node_type==__cmp_more_or_equal ||
|
||||
node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark)
|
||||
node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark ||
|
||||
node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal)
|
||||
this->calculation(local_scope,*iter);
|
||||
else if(node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal)
|
||||
this->assignment(local_scope,*iter);
|
||||
else if(node_type==__definition)
|
||||
this->definition(local_scope,*iter);
|
||||
else if(node_type==__conditional)
|
||||
this->conditional(local_scope,*iter);
|
||||
else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))
|
||||
this->loop_expr(local_scope,*iter);
|
||||
if(runtime_error_exit_mark>=0)
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -154,8 +242,13 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
|||
{
|
||||
time_t begin_time,end_time;
|
||||
begin_time=std::time(NULL);
|
||||
|
||||
// initializing global scope and nasal_gc
|
||||
// runtime_error_exit_mark is set to -1,if runtime_error_exit_mark >=0,this means an error occurred
|
||||
global_scope.clear();
|
||||
nasal_gc.gc_init();
|
||||
runtime_error_exit_mark=-1;
|
||||
|
||||
if(root.get_node_type()!=__root)
|
||||
{
|
||||
error_interrupt(__incorrect_head_of_tree);
|
||||
|
@ -174,21 +267,20 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
|||
else if(node_type==__hash)
|
||||
this->hash_generation(main_local_scope,*iter);
|
||||
else if(node_type==__function)
|
||||
{
|
||||
;
|
||||
}
|
||||
this->function_generation(main_local_scope,*iter);
|
||||
else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator || node_type==__link_operator ||
|
||||
node_type==__cmp_equal || node_type==__cmp_less || node_type==__cmp_more || node_type==__cmp_not_equal || node_type==__cmp_less_or_equal || node_type==__cmp_more_or_equal ||
|
||||
node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark)
|
||||
node_type==__and_operator || node_type==__or_operator || node_type==__ques_mark ||
|
||||
node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal)
|
||||
this->calculation(main_local_scope,*iter);
|
||||
else if(node_type==__equal || node_type==__add_equal || node_type==__sub_equal || node_type==__div_equal || node_type==__mul_equal || node_type==__link_equal)
|
||||
this->assignment(main_local_scope,*iter);
|
||||
else if(node_type==__definition)
|
||||
this->definition(main_local_scope,*iter);
|
||||
else if(node_type==__conditional)
|
||||
this->conditional(main_local_scope,*iter);
|
||||
else if((node_type==__while) || (node_type==__for) || (node_type==__foreach) || (node_type==__forindex))
|
||||
this->loop_expr(main_local_scope,*iter);
|
||||
if(runtime_error_exit_mark>=0)
|
||||
break;
|
||||
}
|
||||
|
||||
end_time=std::time(NULL);
|
||||
|
|
Loading…
Reference in New Issue