diff --git a/version2.0/main.cpp b/version2.0/main.cpp index f651301..8983f1e 100644 --- a/version2.0/main.cpp +++ b/version2.0/main.cpp @@ -5,8 +5,7 @@ nasal_lexer lexer; nasal_parse parser; abstract_syntax_tree libroot; abstract_syntax_tree root; - -nasal_symbol_table symtable; +abstract_syntax_tree linker; std::string command; @@ -40,7 +39,6 @@ int main() std::cout<<">> [lex ] turn code into tokens."<> [par ] turn tokens into abstract syntax tree."<> [ast ] check the abstract syntax tree."<> [sym ] generate symbol table and print the information of it."<> [run ] run code."<> [info ] print lexer,parser and ast on screen."<> [exit ] quit nasal interpreter."<> [Delete] complete."<> [Lib] loaded."<> [Lib-error] lib files have parse error(s),stop."<> [Lib] lib files have parse error(s),stop."<> [Lib-error] lib files have lexer error(s),stop."<> [Lib] lib files have lexer error(s),stop."<> [Parse] error occurred,stop."<> [Lexer] error occurred,stop."<> [Symbol] error occurred,stop."<> [Parse] error occurred,stop."<> [Symbol] error occurred,stop."<> [Parse] error occurred,stop."< #include #include +#include +#include -#include "numeral_misc.h" +#include "nasal_misc.h" #include "nasal_enum.h" -#include "abstract_syntax_tree.h" +#include "nasal_ast.h" #include "nasal_lexer.h" #include "nasal_parse.h" -#include "nasal_symbol_table.h" +#include "nasal_scalar.h" +#include "nasal_gc.h" +#include "nasal_sym.h" +#include "nasal_runtime.h" -#endif +#endif \ No newline at end of file diff --git a/version2.0/nasal_ast.h b/version2.0/nasal_ast.h new file mode 100644 index 0000000..7ed6026 --- /dev/null +++ b/version2.0/nasal_ast.h @@ -0,0 +1,223 @@ +#ifndef __NASAL_AST_H__ +#define __NASAL_AST_H__ + +class abstract_syntax_tree +{ + private: + // basic elements + int line; + int node_type; + std::list children; + + // is this node is a number|string|identifier node + // then the three elements below is of great use + // var_name is set for __id + double var_number; + std::string var_string; + std::string var_name; + public: + /* basic */ + abstract_syntax_tree(); + abstract_syntax_tree(const abstract_syntax_tree&); + ~abstract_syntax_tree(); + abstract_syntax_tree& operator=(const abstract_syntax_tree&); + + /* main functions */ + // print + void print_tree(); + void print_tree_block(const int); + + // set + void set_clear(); + void set_node_line(const int); + void set_node_type(const int); + void set_var_number(std::string); + void set_var_string(std::string); + void set_var_name(std::string); + void add_children(abstract_syntax_tree); + + // get + int get_node_line(); + int get_node_type(); + double get_var_number(); + std::string get_var_string(); + std::string get_var_name(); + std::list& get_children(); + + // merge + void merge_children(abstract_syntax_tree&); +}; + +abstract_syntax_tree::abstract_syntax_tree() +{ + node_type=__null_type; + line=0; + var_number=0; + var_string=""; + var_name=""; + children.clear(); + return; +} + +abstract_syntax_tree::abstract_syntax_tree(const abstract_syntax_tree& tmp) +{ + node_type=tmp.node_type; + line=tmp.line; + var_number=tmp.var_number; + var_string=tmp.var_string; + var_name=tmp.var_name; + children=tmp.children; + return; +} + +abstract_syntax_tree::~abstract_syntax_tree() +{ + node_type=__null_type; + line=0; + var_number=0; + var_string.clear(); + var_name.clear(); + children.clear(); + return; +} + +abstract_syntax_tree& abstract_syntax_tree::operator=(const abstract_syntax_tree& tmp) +{ + node_type=tmp.node_type; + line=tmp.line; + var_number=tmp.var_number; + var_string=tmp.var_string; + var_name=tmp.var_name; + children.clear(); + children=tmp.children; + return *this; +} + +void abstract_syntax_tree::print_tree() +{ + std::cout<<">> [Abstract-syntax-tree] get tree root: "<<(this)<<""<::iterator i=children.begin();i!=children.end();++i) + i->print_tree_block(n+1); + } + return; +} + +void abstract_syntax_tree::set_clear() +{ + node_type=__null_type; + line=0; + var_number=0; + var_string=""; + var_name=""; + children.clear(); + return; +} + +void abstract_syntax_tree::set_node_type(const int __node_type) +{ + node_type=__node_type; + return; +} + +void abstract_syntax_tree::set_node_line(const int __line) +{ + if(__line>=0) + line=__line; + else + { + std::cout<<">> [Abstract-syntax-tree-warning] incorrect line under 0: "<<__line<<"."<& abstract_syntax_tree::get_children() +{ + return children; +} + +void abstract_syntax_tree::merge_children(abstract_syntax_tree& tmp) +{ + for(std::list::iterator i=tmp.children.begin();i!=tmp.children.end();++i) + this->children.push_back(*i); + return; +} + +#endif \ No newline at end of file diff --git a/version2.0/nasal_gc.h b/version2.0/nasal_gc.h new file mode 100644 index 0000000..cea2723 --- /dev/null +++ b/version2.0/nasal_gc.h @@ -0,0 +1,143 @@ +#ifndef __NASAL_GC_H__ +#define __NASAL_GC_H__ + +struct gc_unit +{ + // 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; + nasal_scalar elem; + int refcnt; + gc_unit() + { + collected=true; + //elem=0; + refcnt=0; + return; + } + gc_unit(const gc_unit& tmp) + { + collected=tmp.collected; + //elem=tmp.elem; + refcnt=tmp.refcnt; + return; + } +}; + +class gc_manager +{ + private: + // free_space list is used to store space that is not in use. + std::list free_space; + std::vector memory; + public: + gc_manager() + { + memory.clear(); + free_space.clear(); + return; + } + ~gc_manager() + { + memory.clear(); + free_space.clear(); + return; + } + void gc_init() + { + // this function must be called in class nasal_runtime + // before running any codes + std::vector tmp_vec; + memory.clear(); + memory.swap(tmp_vec); + // clear the memory capacity by using tmp_vec.~vector() + free_space.clear(); + return; + } + void gc_scanner() + { + int memory_size=memory.size(); + for(int i=0;i> [Gc] collected "; + prt_hex(i); + std::cout<<"."<> [Gc] fatal error: unexpected memory place "; + prt_hex(place); + std::cout<<" ."<> [Gc] fatal error: unexpected memory place "; + prt_hex(place); + std::cout<<" ."<> [Gc] memory size:"<> [Gc] memory capacity:"<> [Gc] memory usage: "<1 && str[0]=='-') + { + // in lexer this statements are useless + // because lexer judge a number that begins with 0~9 (or 0x for hex & 0o for oct) + std::string temp=""; + int str_len=str.length(); + for(int i=1;i2 && str[0]=='0' && str[1]=='x') + { + int str_len=str.length(); + for(int i=2;i2 && str[0]=='0' && str[1]=='o') + { + int str_len=str.length(); + for(int i=2;i1) || (str[0]=='.') || (!float_dot_cnt && str[0]=='0')) + return false; + return true; + } + return false; +} + +double trans_string_to_number(std::string str) +{ + bool is_negative=false; + if(str.length()>1 && str[0]=='-') + { + // in parse this statements are useless + // because lexer recognizes a number that begins with a '0'~'9' char + std::string temp=""; + int str_len=str.length(); + for(int i=1;i1;--i) + { + if('0'<=str[i] && str[i]<='9') + hex_number+=bit_pow*(str[i]-'0'); + else if('a'<=str[i] && str[i]<='f') + hex_number+=bit_pow*(10+str[i]-'a'); + else + hex_number+=bit_pow*(10+str[i]-'A'); + bit_pow<<=4; + } + trans_str_number=(double)hex_number; + } + else if(str[0]=='0' && str[1]=='o') + { + long long int oct_number=0,bit_pow=1; + for(int i=str.length()-1;i>1;--i) + { + oct_number+=bit_pow*(str[i]-'0'); + bit_pow<<=3; + } + trans_str_number=(double)oct_number; + } + else + { + int float_dot_place=str.length(); + int str_len=str.length(); + double pow; + for(int i=0;i=0;--i) + { + trans_str_number+=pow*(double(str[i]-'0')); + pow*=10; + } + } + if(is_negative) + trans_str_number*=-1; + return trans_str_number; +} + +std::string trans_number_to_string(double number) +{ + std::string trans_num_string=""; + if(number<0) + { + trans_num_string+='-'; + number*=-1; + } + double integer_bit=1; + while(number>=integer_bit) + integer_bit*=10; + integer_bit/=10; + while(integer_bit!=0.1) + { + trans_num_string+=(char)('0'+(int(number/integer_bit))); + number-=(double)(int(number/integer_bit))*integer_bit; + integer_bit/=10; + } + if(number!=0) + trans_num_string+='.'; + while(number!=0) + { + trans_num_string+=(char)('0'+int(number*10)); + number*=10; + number-=(double)(int(number)); + } + return trans_num_string; +} + +void prt_hex(const int ptr) +{ + // transform int to hex and print it (std::cout) + char hex[9]; + hex[8]=0; + int tmp_plc=ptr; + for(int j=7;j>=0;--j) + { + int tmp=(tmp_plc & 0x0000000f); + hex[j]=tmp<10? (char)('0'+tmp):(char)('a'+tmp-10); + tmp_plc>>=4; + } + std::cout<<"0x"< local_scope; + abstract_syntax_tree function_root; + public: + nasal_function() + { + local_scope.clear(); + function_root.set_clear(); + return; + } + ~nasal_function() + { + local_scope.clear(); + function_root.set_clear(); + return; + } +}; + class nasal_scalar { private: int type; std::string var_string; double var_number; - std::vector var_array; - std::map var_hash; + std::vector var_array; + std::map var_hash; + nasal_function var_func; public: nasal_scalar() { @@ -62,6 +83,19 @@ class nasal_scalar var_string=tmp_str; return; } + void vector_add_new_member(const int addr) + { + var_array.push_back(addr); + return; + } + void hash_add_new_member(const std::string member_name,const int addr) + { + if(var_hash.find(member_name)!=var_hash.end()) + std::cout<<">> [Runtime] "< sym_map; + public: + sym_hash_map() + { + sym_map.clear(); + return; + } + sym_hash_map(const sym_hash_map& tmp) + { + sym_map=tmp.sym_map; + for(std::map::iterator i=sym_map.begin();i!=sym_map.end();++i) + nasal_gc.reference_add(i->second); + return; + } + ~sym_hash_map() + { + for(std::map::iterator i=sym_map.begin();i!=sym_map.end();++i) + nasal_gc.reference_delete(i->second); + sym_map.clear(); + return; + } + void set_clear() + { + sym_map.clear(); + return; + } + void add_new_symbol(std::string __sym_name) + { + if(sym_map.find(__sym_name)==sym_map.end()) + sym_map[__sym_name]=nasal_gc.gc_alloc(); + else + std::cout<<">> [Runtime] "<<__sym_name<<" exists."<