diff --git a/version2.0/main.cpp b/version2.0/main.cpp index be9770c..ccb8f23 100644 --- a/version2.0/main.cpp +++ b/version2.0/main.cpp @@ -3,6 +3,9 @@ resource_file resource; nasal_lexer lexer; nasal_parse parser; +abstract_syntax_tree libroot; +abstract_syntax_tree root; + nasal_symbol_table symtable; std::string command; @@ -10,13 +13,13 @@ std::string command; int main() { #ifdef _WIN32 - std::cout<<">>[system] Windows system."<> [system] Windows system."<>[system] Linux system."<> [system] Linux system."<>[system] MacOS system."<> [system] MacOS system."<> Nasal interpreter ver 2.0 ."<> Code: https://github.com/ValKmjolnir/Nasal-Interpreter"<> [del ] clear the resource code."<> [lib ] add lib file."<> [rs ] print resource code."<> [total ] print resource code with lib code."<> [lex ] turn code into tokens."<> [par ] turn tokens into abstract syntax tree."<> [ast ] check the abstract syntax tree."<>[Delete] complete."<> [Delete] complete."<>[Lib] loaded."<> [Lib] loaded."<> [Lib-error] lib files have parse error(s),stop."<> [Lib-error] lib files have lexer error(s),stop."<>[Lexer] error occurred,stop."<> [Lexer] error occurred,stop."<>[Lexer] error occurred,stop."<> [Lexer] error occurred,stop."<>[Parse] error occurred,stop."<> [Parse] error occurred,stop."<>[Lexer] error occurred,stop."<> [Lexer] error occurred,stop."<>[Symbol] error occurred,stop."<> [Symbol] error occurred,stop."<>[Parse] error occurred,stop."<> [Parse] error occurred,stop."<>[Lexer] error occurred,stop."<> [Lexer] error occurred,stop."<>[Symbol] error occurred,stop."<> [Symbol] error occurred,stop."<>[Parse] error occurred,stop."<> [Parse] error occurred,stop."<>[Lexer] error occurred,stop."<> [Lexer] error occurred,stop."< libsource; std::list resource; - std::list totalcode; public: /* resource_file(); @@ -61,27 +72,21 @@ class resource_file void input_file(std::string); void load_lib_file(); std::list& get_source(); - void print_resource(bool); + void print_resource(); */ resource_file() { - libsource.clear(); resource.clear(); - totalcode.clear(); return; } ~resource_file() { - libsource.clear(); resource.clear(); - totalcode.clear(); return; } void delete_all_source() { - libsource.clear(); resource.clear(); - totalcode.clear(); return; } void input_file(std::string filename) @@ -90,7 +95,7 @@ class resource_file std::ifstream fin(filename,std::ios::binary); if(fin.fail()) { - std::cout<<">>[Resource] cannot open file \'"<> [Resource] cannot open file \'"<> [Resource] fatal error: lack \'"<& get_source() { - totalcode.clear(); - for(std::list::iterator i=libsource.begin();i!=libsource.end();++i) - totalcode.push_back(*i); - for(std::list::iterator i=resource.begin();i!=resource.end();++i) - totalcode.push_back(*i); - return totalcode; + return resource; } - void print_resource(bool withlib) + void print_resource() { - std::list tmp; - if(withlib) - for(std::list::iterator i=libsource.begin();i!=libsource.end();++i) - tmp.push_back(*i); - for(std::list::iterator i=resource.begin();i!=resource.end();++i) - tmp.push_back(*i); - int line=1; std::cout<::iterator i=tmp.begin();i!=tmp.end();++i) + for(std::list::iterator i=resource.begin();i!=resource.end();++i) { if(32<=*i) std::cout<<*i; @@ -282,7 +290,7 @@ class nasal_lexer if(!check_numerable_string(token_str)) { ++error; - std::cout<<">>[Lexer-error] line "<> [Lexer-error] line "<>[Lexer-error] line "<> [Lexer-error] line "<>[Lexer-error] line "<> [Lexer-error] line "<>[Pre-lexer] complete scanning. "<> [Pre-lexer] complete scanning. "<>[Lexer-error] line "<str<<"\'."<> [Lexer-error] line "<str<<"\'."<>[Detail-lexer] complete generating. "<> [Detail-lexer] complete generating. "<>[Parse] output root address: "<<(&root)<<" ."<>[Parse] complete generation. "<> [Parse] complete generation. "<get_token(); if(this_token.type==__semi) + { + abstract_syntax_tree null_node; + null_node.set_node_type(__null_type); + loop_main_node.add_children(null_node); this->push_token(); + } else { if(this_token.type==__var) @@ -1443,7 +1447,7 @@ abstract_syntax_tree nasal_parse::loop_expr() this->push_token(); // cannot use calculation() here // because for-loop's first statement must be definition or call_identifier - loop_main_node.add_children(scalar_generate()); + loop_main_node.add_children(calculation()); } } this->get_token(); @@ -1454,7 +1458,12 @@ abstract_syntax_tree nasal_parse::loop_expr() } this->get_token(); if(this_token.type==__semi) + { + abstract_syntax_tree null_node; + null_node.set_node_type(__null_type); + loop_main_node.add_children(null_node); this->push_token(); + } else { this->push_token(); @@ -1468,7 +1477,12 @@ abstract_syntax_tree nasal_parse::loop_expr() } this->get_token(); if(this_token.type==__right_curve) + { + abstract_syntax_tree null_node; + null_node.set_node_type(__null_type); + loop_main_node.add_children(null_node); this->push_token(); + } else { this->push_token(); diff --git a/version2.0/nasal_scalar.h b/version2.0/nasal_scalar.h new file mode 100644 index 0000000..ab9c967 --- /dev/null +++ b/version2.0/nasal_scalar.h @@ -0,0 +1,70 @@ +#ifndef __NASAL_SCALAR_H__ +#define __NASAL_SCALAR_H__ + +class nasal_scalar +{ + private: + int type; + std::string var_string; + double var_number; + std::vector var_array; + std::map var_hash; + public: + nasal_scalar() + { + type=scalar_nil; + var_string=""; + var_number=0; + var_array.clear(); + var_hash.clear(); + return; + } + nasal_scalar(const nasal_scalar& tmp) + { + type=tmp.type; + var_string=tmp.var_string; + var_number=tmp.var_number; + var_array=tmp.var_array; + var_hash=tmp.var_hash; + return; + } + nasal_scalar& operator=(const nasal_scalar& tmp) + { + type=tmp.type; + var_string=tmp.var_string; + var_number=tmp.var_number; + var_array=tmp.var_array; + var_hash=tmp.var_hash; + return *this; + } + void set_clear() + { + type=scalar_nil; + var_string.clear(); + var_number=0; + var_array.clear(); + var_hash.clear(); + return; + } + void set_type(const int tmp_type) + { + // scalar_function is the last enum in enum::scalar_type + type=tmp_type>scalar_function? scalar_nil:tmp_type; + return; + } + void set_number(const double tmp_number) + { + var_number=tmp_number; + return; + } + void set_string(const std::string& tmp_str) + { + var_string=tmp_str; + return; + } + int get_type() {return type;} + double get_number() {return var_number;} + std::string get_string(){return var_string;} +}; + +#endif diff --git a/version2.0/nasal_symbol_table.h b/version2.0/nasal_symbol_table.h index d5dac94..a30611e 100644 --- a/version2.0/nasal_symbol_table.h +++ b/version2.0/nasal_symbol_table.h @@ -33,6 +33,8 @@ class nasal_symbol_table { private: int error; + int global_number; + int local_number; std::list global_symbol_dictionary;// used to save symbols appeared in global scope std::list local_symbol_dictionary; // used to save symbols appeared in local scopes std::list global_scope; // global scope @@ -43,6 +45,7 @@ class nasal_symbol_table void local_list_del_scope(); void local_scope_add_symbol(symbol_table_unit); int search_symbol_id(symbol_table_unit); + bool search_scope(symbol_table_unit); public: nasal_symbol_table(); ~nasal_symbol_table(); @@ -55,6 +58,8 @@ class nasal_symbol_table nasal_symbol_table::nasal_symbol_table() { error=0; + global_number=0; + local_number=0; global_symbol_dictionary.clear(); global_scope.clear(); local_symbol_dictionary.clear(); @@ -65,6 +70,8 @@ nasal_symbol_table::nasal_symbol_table() nasal_symbol_table::~nasal_symbol_table() { error=0; + global_number=0; + local_number=0; global_symbol_dictionary.clear(); global_scope.clear(); local_symbol_dictionary.clear(); @@ -75,6 +82,8 @@ nasal_symbol_table::~nasal_symbol_table() void nasal_symbol_table::set_scope_clear() { error=0; + global_number=0; + local_number=0; global_symbol_dictionary.clear(); global_scope.clear(); local_symbol_dictionary.clear(); @@ -86,12 +95,12 @@ void nasal_symbol_table::print_symbol_table() { if(!global_symbol_dictionary.empty()) { - std::cout<<">>[Symbol] global scope:"<> [Symbol] global scope:"<::iterator i=global_symbol_dictionary.begin();i!=global_symbol_dictionary.end();++i) std::cout<<" line "<symbol_line<<": "<symbol_name<<"|"<symbol_number<>[Symbol] empty global symbol list."<> [Symbol] empty global symbol list."<>[Symbol] local scope:"<symbol_line<<": "<symbol_name<<"|"<symbol_number<>[Symbol] empty local symbol list."<> [Symbol] empty local symbol list."<::iterator i=global_scope.begin();i!=global_scope.end();++i) - { - // this conditional expression is used to avoid wrong use of this function - // repeat symbol will get the same number if(i->symbol_name==tmp.symbol_name) return; - symbol_number_gen=i->symbol_number; - } - tmp.symbol_number=symbol_number_gen+1; + ++global_number; + tmp.symbol_number=global_number; global_scope.push_back(tmp); global_symbol_dictionary.push_back(tmp); return; @@ -132,10 +138,13 @@ void nasal_symbol_table::local_list_del_scope() if(local_list.empty()) { ++error; - std::cout<<">>[Symbol-error] fatal error: empty block_scope_list."<> [Symbol-error] fatal error: empty block_scope_list."< >::iterator i= local_list.begin();i!=local_list.end();++i) - if(!i->empty()) + // if in the last scope there is a sym which symbol_name is the same as tmp.symbol_name + // then the symbol will get the same number + std::list >::iterator last_scope=local_list.end();--last_scope; + for(std::list >::iterator i=local_list.begin();i!=local_list.end();++i) for(std::list::iterator j=i->begin();j!=i->end();++j) - { - // this conditional expression is used to avoid wrong use of this function - // repeat symbol will get the same number - ++i; - if(i==local_list.end()) - { - --i; - if(j->symbol_name==tmp.symbol_name) - return; - } - else - --i; - symbol_number_gen=j->symbol_number; - } - tmp.symbol_number=symbol_number_gen+1; + if((i==last_scope) && (j->symbol_name==tmp.symbol_name)) + return; + ++local_number; + tmp.symbol_number=local_number; local_list.back().push_back(tmp); local_symbol_dictionary.push_back(tmp); } else { ++error; - std::cout<<">>[Symbol-error] fatal error: empty block_scope_list."<> [Symbol-error] fatal error: empty block_scope_list."< >::iterator i=local_list.begin();i!=local_list.end();++i) - for(std::list::iterator j=i->begin();j!=i->end();++j) - if(j->symbol_name==tmp.symbol_name) - ret_number=j->symbol_number; - if(ret_number==-1) - for(std::list::iterator i=global_scope.begin();i!=global_scope.end();++i) - if(i->symbol_name==tmp.symbol_name) - ret_number=i->symbol_number; - if(ret_number==-1) - { - ++error; - std::cout<<">>[Symbol-error] line "< >::iterator i=local_list.begin();i!=local_list.end();++i) + for(std::list::iterator j=i->begin();j!=i->end();++j) + if(j->symbol_name==tmp.symbol_name) + return j->symbol_number; + // global scope + for(std::list::iterator i=global_scope.begin();i!=global_scope.end();++i) + if(i->symbol_name==tmp.symbol_name) + return i->symbol_number; + // error + ++error; + std::cout<<">> [Symbol-error] line "< >::iterator i=local_list.begin();i!=local_list.end();++i) + for(std::list::iterator j=i->begin();j!=i->end();++j) + if(j->symbol_name==tmp.symbol_name) + return false; + for(std::list::iterator i=global_scope.begin();i!=global_scope.end();++i) + if(i->symbol_name==tmp.symbol_name) + return true; + return true; } int nasal_symbol_table::get_error() { + // god knows why i wrote this sh*t. return error; } @@ -206,6 +216,7 @@ void nasal_symbol_table::symbol_table_main_generate(abstract_syntax_tree& root) this->set_scope_clear(); for(std::list::iterator i=root.get_children().begin();i!=root.get_children().end();++i) { + // only definition will call this->global_scope_add_symbol(symbol_table_unit) if(i->get_node_type()==__definition) { symbol_table_unit tmp; @@ -213,19 +224,21 @@ void nasal_symbol_table::symbol_table_main_generate(abstract_syntax_tree& root) tmp.symbol_name=i->get_children().front().get_var_name(); this->global_scope_add_symbol(tmp); i->get_children().front().set_symbol_number(this->search_symbol_id(tmp)); - i->get_children().front().set_var_scope(true); + i->get_children().front().set_var_scope(this->search_scope(tmp)); this->symbol_table_block_generate(i->get_children().back()); } + // when in main_generate loop,local scope is totally empty else this->symbol_table_block_generate(*i); } - std::cout<<">>[Symbol] symbol table generating complete. "<> [Symbol] symbol table generating complete. "<local_list_add_scope(); if(node.get_children().front().get_node_type()==__parameters) @@ -238,7 +251,7 @@ void nasal_symbol_table::symbol_table_block_generate(abstract_syntax_tree& node) tmp.symbol_name=i->get_var_name(); this->local_scope_add_symbol(tmp); i->set_symbol_number(this->search_symbol_id(tmp)); - i->set_var_scope(false); + i->set_var_scope(this->search_scope(tmp)); } else { @@ -247,14 +260,14 @@ void nasal_symbol_table::symbol_table_block_generate(abstract_syntax_tree& node) tmp.symbol_name=i->get_children().front().get_var_name(); this->local_scope_add_symbol(tmp); i->get_children().front().set_symbol_number(this->search_symbol_id(tmp)); - i->get_children().front().set_var_scope(false); + i->get_children().front().set_var_scope(this->search_scope(tmp)); this->symbol_table_block_generate(i->get_children().back()); } } this->symbol_table_block_generate(node.get_children().back()); this->local_list_del_scope(); } - else if(node.get_node_type()==__conditional) + else if(node_type==__conditional) { for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) { @@ -265,7 +278,32 @@ void nasal_symbol_table::symbol_table_block_generate(abstract_syntax_tree& node) this->local_list_del_scope(); } } - else if(node.get_node_type()==__normal_statement_block) + else if(node_type==__while) + { + for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) + this->symbol_table_block_generate(*i); + } + else if(node_type==__for || node_type==__foreach || node_type==__forindex) + { + this->local_list_add_scope(); + for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) + { + if(i->get_node_type()==__definition) + { + symbol_table_unit tmp; + tmp.symbol_line=i->get_children().front().get_node_line(); + tmp.symbol_name=i->get_children().front().get_var_name(); + this->local_scope_add_symbol(tmp); + i->get_children().front().set_symbol_number(this->search_symbol_id(tmp)); + i->get_children().front().set_var_scope(this->search_scope(tmp)); + this->symbol_table_block_generate(i->get_children().back()); + } + else + this->symbol_table_block_generate(*i); + } + this->local_list_del_scope(); + } + else if(node_type==__normal_statement_block) { for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) { @@ -276,22 +314,29 @@ void nasal_symbol_table::symbol_table_block_generate(abstract_syntax_tree& node) tmp.symbol_name=i->get_children().front().get_var_name(); this->local_scope_add_symbol(tmp); i->get_children().front().set_symbol_number(this->search_symbol_id(tmp)); - i->get_children().front().set_var_scope(false); + i->get_children().front().set_var_scope(this->search_scope(tmp)); this->symbol_table_block_generate(i->get_children().back()); } else this->symbol_table_block_generate(*i); } } - else if(node.get_node_type()==__id) + else if(node_type==__id) { symbol_table_unit tmp; tmp.symbol_line=node.get_node_line(); tmp.symbol_name=node.get_var_name(); int id_symbol_number=this->search_symbol_id(tmp); node.set_symbol_number(id_symbol_number); + // if this id does not exist in scopes + // then search_scope will not be called + if(id_symbol_number>0) + node.set_var_scope(this->search_scope(tmp)); + if(!node.get_children().empty()) + for(std::list::iterator i=node.get_children().begin();i!=node.get_children().end();++i) + this->symbol_table_block_generate(*i); } - else if(node.get_node_type()==__hash) + else if(node_type==__hash) { this->local_list_add_scope(); symbol_table_unit me; @@ -310,7 +355,7 @@ void nasal_symbol_table::symbol_table_block_generate(abstract_syntax_tree& node) tmp.symbol_name=i->get_children().front().get_var_string(); this->local_scope_add_symbol(tmp); i->get_children().front().set_symbol_number(this->search_symbol_id(tmp)); - i->get_children().front().set_var_scope(false); + i->get_children().front().set_var_scope(this->search_scope(tmp)); this->symbol_table_block_generate(i->get_children().back()); } else