Add for-loop

This commit is contained in:
Valk Richard Li 2019-11-20 23:31:07 +08:00 committed by GitHub
parent 504b9fe140
commit f7f6eb9ea3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 181 additions and 30 deletions

View File

@ -427,6 +427,8 @@ bool abstract_syntax_tree::condition_check()
std::cout<<">>[Runtime-error] line "<<line<<":[SIGSEGV] too deep recursion(check)."<<std::endl; std::cout<<">>[Runtime-error] line "<<line<<":[SIGSEGV] too deep recursion(check)."<<std::endl;
return false; return false;
} }
if(type==__null_node) // this is set for "for(;;)"
return true;
bool ret=false; bool ret=false;
var temp=calculation(); var temp=calculation();
if(temp.get_type()==__var_number) if(temp.get_type()==__var_number)
@ -682,7 +684,7 @@ void abstract_syntax_tree::run_root()
var new_var; var new_var;
std::list<abstract_syntax_tree>::iterator j=i->children.begin(); std::list<abstract_syntax_tree>::iterator j=i->children.begin();
std::string _name=j->name; std::string _name=j->name;
if(!scope.search_var(_name)) if(!scope.check_redefine(_name))
{ {
++j; ++j;
if(j!=i->children.end()) if(j!=i->children.end())
@ -705,7 +707,7 @@ void abstract_syntax_tree::run_root()
; ;
else if(i->type==__id) else if(i->type==__id)
i->call_identifier(); i->call_identifier();
else if(i->type==__while) else if(i->type==__while || i->type==__for)
{ {
scope.add_new_block_scope(); scope.add_new_block_scope();
int ret_type=i->run_loop(); int ret_type=i->run_loop();
@ -751,21 +753,77 @@ int abstract_syntax_tree::run_loop()
return 0; return 0;
} }
int ret=0; int ret=0;
if(type==__while)
abstract_syntax_tree condition=children.front();
abstract_syntax_tree blk=children.back();
while(condition.condition_check())
{ {
int type=blk.run_block(); abstract_syntax_tree condition=children.front();
if(type==__break) abstract_syntax_tree blk=children.back();
break; while(condition.condition_check())
else if(type==__return)
{ {
ret=__return; int type=blk.run_block();
break; if(type==__break)
break;
else if(type==__return)
{
ret=__return;
break;
}
if(exit_type!=__process_exited_successfully)
break;
} }
if(exit_type!=__process_exited_successfully) }
break; else if(type==__for)
{
std::list<abstract_syntax_tree>::iterator iter=children.begin();
abstract_syntax_tree def=*iter;
++iter;
abstract_syntax_tree condition=*iter;
++iter;
abstract_syntax_tree var_changement=*iter;
abstract_syntax_tree blk=children.back();
scope.add_new_local_scope();
if(def.type==__definition)
{
var new_var;
std::list<abstract_syntax_tree>::iterator j=def.children.begin();
std::string _name=j->name;
if(!scope.check_redefine(_name))
{
++j;
if(j!=def.children.end())
new_var=j->calculation();
new_var.set_name(_name);
scope.add_new_var(new_var);
}
else
{
std::cout<<">>[Runtime-error] line "<<line<<": redeclaration of \'"<<_name<<"\'."<<std::endl;
exit_type=__redeclaration;
}
}
else if(def.type==__equal || def.type==__add_equal || def.type==__sub_equal || def.type==__mul_equal || def.type==__div_equal || def.type==__link_equal)
def.assignment();
else if(def.type==__id)
def.call_identifier();
while(condition.condition_check())
{
int type=blk.run_block();
if(type==__break)
break;
else if(type==__return)
{
ret=__return;
break;
}
if(exit_type!=__process_exited_successfully)
break;
if(var_changement.type==__equal || var_changement.type==__add_equal || var_changement.type==__sub_equal || var_changement.type==__mul_equal || var_changement.type==__div_equal || var_changement.type==__link_equal)
var_changement.assignment();
else if(var_changement.type==__id)
var_changement.call_identifier();
}
scope.pop_last_local_scope();
} }
--recursion_depth; --recursion_depth;
return ret; return ret;
@ -919,7 +977,7 @@ int abstract_syntax_tree::run_block()
var new_var; var new_var;
std::list<abstract_syntax_tree>::iterator j=i->children.begin(); std::list<abstract_syntax_tree>::iterator j=i->children.begin();
std::string _name=j->name; std::string _name=j->name;
if(!scope.search_var(_name)) if(!scope.check_redefine(_name))
{ {
++j; ++j;
if(j!=i->children.end()) if(j!=i->children.end())
@ -941,7 +999,7 @@ int abstract_syntax_tree::run_block()
i->assignment(); i->assignment();
else if(i->type==__add_operator || i->type==__sub_operator || i->type==__mul_operator || i->type==__div_operator || i->type==__link_operator || i->type==__or_operator || i->type==__and_operator || i->type==__nor_operator) else if(i->type==__add_operator || i->type==__sub_operator || i->type==__mul_operator || i->type==__div_operator || i->type==__link_operator || i->type==__or_operator || i->type==__and_operator || i->type==__nor_operator)
i->calculation(); i->calculation();
else if(i->type==__while) else if(i->type==__while || i->type==__for)
{ {
int type=i->run_loop(); int type=i->run_loop();
if(type) if(type)

View File

@ -265,29 +265,102 @@ abstract_syntax_tree balloon_parse::choose()
abstract_syntax_tree balloon_parse::loop() abstract_syntax_tree balloon_parse::loop()
{ {
abstract_syntax_tree new_node; abstract_syntax_tree new_node;
new_node.set_type(__while);
get_token(); get_token();
if(this_token.type!=__while) if(this_token.type!=__while && this_token.type!=__for)
{ {
++error; ++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": must use \'while\' when generating a loop."<<std::endl; std::cout<<">>[Parse-error] line "<<this_token.line<<": must use \'while\' or \'for\' when generating a loop."<<std::endl;
return new_node; return new_node;
} }
new_node.set_type(this_token.type);
new_node.set_line(this_token.line); new_node.set_line(this_token.line);
get_token(); if(this_token.type==__while)
if(this_token.type!=__left_curve)
{ {
++error; get_token();
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \'(\'."<<std::endl; if(this_token.type!=__left_curve)
return new_node; {
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \'(\'."<<std::endl;
return new_node;
}
new_node.add_child(scalar());
get_token();
if(this_token.type!=__right_curve)
{
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \')\'."<<std::endl;
return new_node;
}
} }
new_node.add_child(scalar()); else if(this_token.type==__for)
get_token();
if(this_token.type!=__right_curve)
{ {
++error; get_token();
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \')\'."<<std::endl; if(this_token.type!=__left_curve)
return new_node; {
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \'(\'."<<std::endl;
return new_node;
}
abstract_syntax_tree nullnode;
nullnode.set_type(__null_node);
nullnode.set_line(this_token.line);
get_token();
if(this_token.type!=__semi)
{
if(this_token.type==__var)
{
parse.push(this_token);
new_node.add_child(definition());
}
else if(this_token.type==__id)
{
parse.push(this_token);
new_node.add_child(call_identifier());
}
else
{
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": must use definition or assignment or nothing here."<<std::endl;
return new_node;
}
}
else
{
parse.push(this_token);
new_node.add_child(nullnode);
}
check_semi();
get_token();
if(this_token.type!=__semi)
{
parse.push(this_token);
new_node.add_child(scalar());
}
else
{
parse.push(this_token);
new_node.add_child(nullnode);
}
check_semi();
get_token();
if(this_token.type!=__semi)
{
parse.push(this_token);
new_node.add_child(scalar());
}
else
{
parse.push(this_token);
new_node.add_child(nullnode);
}
get_token();
if(this_token.type!=__right_curve)
{
++error;
std::cout<<">>[Parse-error] line "<<this_token.line<<": expect a \')\'."<<std::endl;
return new_node;
}
} }
new_node.add_child(block()); new_node.add_child(block());
return new_node; return new_node;

View File

@ -21,6 +21,26 @@ class balloon_scope
scope_list.clear(); scope_list.clear();
return; return;
} }
bool check_redefine(std::string name)
{
if(!scope_list.empty() && !scope_list.back().empty())
{
std::list<std::list<var> >::iterator i=scope_list.back().end();
--i;
for(std::list<var>::iterator j=i->begin();j!=i->end();++j)
if(j->get_name()==name)
return true;
return false;
}
if(!global.empty())
{
for(std::list<var>::iterator i=global.begin();i!=global.end();++i)
if(i->get_name()==name)
return true;
return false;
}
return false;
}
bool search_var(std::string name) bool search_var(std::string name)
{ {
if(!scope_list.empty() && !scope_list.back().empty()) if(!scope_list.empty() && !scope_list.back().empty())