diff --git a/README.md b/README.md index f8120da..fcf580d 100644 --- a/README.md +++ b/README.md @@ -296,7 +296,7 @@ Check built-in functions in lib.nas! If you want to add your own built-in functions,define the function in nasal_builtin.h. -definition: +Definition: ```C++ nasal_val* builtin_chr(nasal_val*,nasal_gc&); diff --git a/main.cpp b/main.cpp index cba161a..fea031b 100644 --- a/main.cpp +++ b/main.cpp @@ -9,25 +9,27 @@ nasal_vm vm; void help() { - std::cout<<">> [\"file\"] input a file name.\n"; - std::cout<<">> [help ] show help.\n"; - std::cout<<">> [clear ] clear the screen.\n"; - std::cout<<">> [lex ] use lexer to turn code into tokens.\n"; - std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n"; - std::cout<<">> [code ] show byte code.\n"; - std::cout<<">> [exec ] execute program on bytecode vm.\n"; - std::cout<<">> [logo ] print logo of nasal .\n"; - std::cout<<">> [exit ] quit nasal interpreter.\n"; + std::cout + <<">> [\"file\"] input a file name.\n" + <<">> [help ] show help.\n" + <<">> [clear ] clear the screen.\n" + <<">> [lex ] use lexer to turn code into tokens.\n" + <<">> [ast ] do parsing and check the abstract syntax tree.\n" + <<">> [code ] show byte code.\n" + <<">> [exec ] execute program on bytecode vm.\n" + <<">> [logo ] print logo of nasal .\n" + <<">> [exit ] quit nasal interpreter.\n"; return; } void logo() { - std::cout<<" __ _ \n"; - std::cout<<" /\\ \\ \\__ _ ___ __ _| | \n"; - std::cout<<" / \\/ / _` / __|/ _` | | \n"; - std::cout<<" / /\\ / (_| \\__ \\ (_| | | \n"; - std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"; + std::cout + <<" __ _ \n" + <<" /\\ \\ \\__ _ ___ __ _| | \n" + <<" / \\/ / _` / __|/ _` | | \n" + <<" / /\\ / (_| \\__ \\ (_| | | \n" + <<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"; return; } diff --git a/nasal.h b/nasal.h index e29f444..ccd55c3 100644 --- a/nasal.h +++ b/nasal.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include /* check if a string can be converted to a number diff --git a/nasal_builtin.h b/nasal_builtin.h index 6b8362f..21b4c68 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -9,7 +9,7 @@ // } // builtin function nasal_call_builtin_std_cout is wrapped up by print -std::map builtin_use_string_table; +std::unordered_map builtin_use_string_table; // used to find values that builtin function uses #define in_builtin_find(value_name_string) \ (\ diff --git a/nasal_codegen.h b/nasal_codegen.h index 9837c5d..1a7553d 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -128,8 +128,8 @@ struct opcode class nasal_codegen { private: - std::map number_table; - std::map string_table; + std::unordered_map number_table; + std::unordered_map string_table; std::vector number_result_table; std::vector string_result_table; std::vector exec_code; @@ -918,9 +918,9 @@ void nasal_codegen::main_progress(nasal_ast& ast) gen(op_nop,0); number_result_table.resize(number_table.size()); string_result_table.resize(string_table.size()); - for(std::map::iterator i=number_table.begin();i!=number_table.end();++i) + for(auto i=number_table.begin();i!=number_table.end();++i) number_result_table[i->second]=i->first; - for(std::map::iterator i=string_table.begin();i!=string_table.end();++i) + for(auto i=string_table.begin();i!=string_table.end();++i) string_result_table[i->second]=i->first; return; } diff --git a/nasal_gc.h b/nasal_gc.h index 3679b05..d2f3e9f 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -40,7 +40,7 @@ class nasal_hash { private: nasal_gc& gc; - std::map elems; + std::unordered_map elems; public: nasal_hash(nasal_gc&); ~nasal_hash(); @@ -82,7 +82,7 @@ class nasal_scop { private: nasal_gc& gc; - std::map elems; + std::unordered_map elems; public: nasal_scop(nasal_gc&); ~nasal_scop(); @@ -133,7 +133,6 @@ private: public: ~nasal_gc(); void clear(); - void debug(); nasal_val* gc_alloc(int); void add_reference(nasal_val*); void del_reference(nasal_val*); @@ -226,20 +225,20 @@ nasal_hash::nasal_hash(nasal_gc& ngc):gc(ngc) } nasal_hash::~nasal_hash() { - for(std::map::iterator iter=elems.begin();iter!=elems.end();++iter) + for(auto iter=elems.begin();iter!=elems.end();++iter) gc.del_reference(iter->second); elems.clear(); return; } void nasal_hash::add_elem(std::string key,nasal_val* value_address) { - if(elems.find(key)==elems.end()) + if(!elems.count(key)) elems[key]=value_address; return; } void nasal_hash::del_elem(std::string key) { - if(elems.find(key)!=elems.end()) + if(!elems.count(key)) { gc.del_reference(elems[key]); elems.erase(key); @@ -252,16 +251,16 @@ int nasal_hash::size() } nasal_val* nasal_hash::get_special_para(std::string key) { - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return elems[key]; return NULL; } nasal_val* nasal_hash::get_value_address(std::string key) { nasal_val* ret_value_addr=NULL; - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return elems[key]; - else if(elems.find("parents")!=elems.end()) + else if(elems.count("parents")) { nasal_val* val_addr=elems["parents"]; if(val_addr->get_type()==vm_vec) @@ -283,9 +282,9 @@ nasal_val* nasal_hash::get_value_address(std::string key) nasal_val** nasal_hash::get_mem_address(std::string key) { nasal_val** mem_addr=NULL; - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return &elems[key]; - else if(elems.find("parents")!=elems.end()) + else if(elems.count("parents")) { nasal_val* val_addr=elems["parents"]; if(val_addr->get_type()==vm_vec) @@ -306,9 +305,9 @@ nasal_val** nasal_hash::get_mem_address(std::string key) } bool nasal_hash::check_contain(std::string key) { - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return true; - if(elems.find("parents")!=elems.end()) + if(elems.count("parents")) { bool result=false; nasal_val* val_addr=elems["parents"]; @@ -333,7 +332,7 @@ nasal_val* nasal_hash::get_keys() { nasal_val* ret_addr=gc.gc_alloc(vm_vec); nasal_vec& ref_vec=ret_addr->get_vector(); - for(std::map::iterator iter=elems.begin();iter!=elems.end();++iter) + for(auto iter=elems.begin();iter!=elems.end();++iter) { nasal_val* str_addr=gc.gc_alloc(vm_str); str_addr->set_string(iter->first); @@ -343,12 +342,15 @@ nasal_val* nasal_hash::get_keys() } void nasal_hash::print() { - std::cout<<"{"; + std::cout<<'{'; if(!elems.size()) - std::cout<<"}"; - for(std::map::iterator i=elems.begin();i!=elems.end();++i) { - std::cout<first<<":"; + std::cout<<'}'; + return; + } + for(auto i=elems.begin();i!=elems.end();++i) + { + std::cout<first<<':'; nasal_val* tmp=i->second; switch(tmp->get_type()) { @@ -359,9 +361,9 @@ void nasal_hash::print() case vm_hash: tmp->get_hash().print(); break; case vm_func: std::cout<<"func(...){...}"; break; } - std::cout<<",}"[(++i)==elems.end()]; - --i; + std::cout<<','; } + std::cout<<'}'; return; } @@ -437,14 +439,14 @@ nasal_scop::nasal_scop(nasal_gc& ngc):gc(ngc) } nasal_scop::~nasal_scop() { - for(std::map::iterator i=elems.begin();i!=elems.end();++i) + for(auto i=elems.begin();i!=elems.end();++i) gc.del_reference(i->second); elems.clear(); return; } void nasal_scop::add_new_value(int key,nasal_val* value_address) { - if(elems.find(key)!=elems.end()) + if(elems.count(key)) { // if this value already exists,delete the old value and update a new value gc.del_reference(elems[key]); @@ -454,22 +456,22 @@ void nasal_scop::add_new_value(int key,nasal_val* value_address) } nasal_val* nasal_scop::get_value_address(int key) { - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return elems[key]; return NULL; } nasal_val** nasal_scop::get_mem_address(int key) { - if(elems.find(key)!=elems.end()) + if(elems.count(key)) return &(elems[key]); return NULL; } void nasal_scop::set_closure(nasal_scop& tmp) { - for(std::map::iterator i=elems.begin();i!=elems.end();++i) + for(auto i=elems.begin();i!=elems.end();++i) gc.del_reference(i->second); elems=tmp.elems; - for(std::map::iterator i=elems.begin();i!=elems.end();++i) + for(auto i=elems.begin();i!=elems.end();++i) gc.add_reference(i->second); return; } @@ -566,13 +568,10 @@ int nasal_val::get_type() } double nasal_val::to_number() { - switch(type) - { - case vm_nil: return 0; - case vm_num: return ptr.num; - case vm_str: return trans_string_to_number(*ptr.str); - default: return std::nan(""); - } + if(type==vm_num) + return ptr.num; + else if(type==vm_str) + return trans_string_to_number(*ptr.str); return 0; } double nasal_val::get_number() @@ -581,12 +580,10 @@ double nasal_val::get_number() } std::string nasal_val::to_string() { - switch(type) - { - case vm_num:return trans_number_to_string(ptr.num); - case vm_str:return *ptr.str; - default:return ""; - } + if(type==vm_str) + return *ptr.str; + else if(type==vm_num) + return trans_number_to_string(ptr.num); return ""; } std::string nasal_val::get_string() @@ -623,27 +620,6 @@ nasal_gc::~nasal_gc() memory.clear(); return; } -void nasal_gc::debug() -{ - int gc_mem_size=memory.size(); - for(int i=0;iref_cnt) - { - std::cout<<">> [debug] "<ref_cnt<<" "; - switch(memory[i]->get_type()) - { - case vm_nil:std::cout<<"nil";break; - case vm_num:std::cout<<"number "<get_number();break; - case vm_str:std::cout<<"string "<get_string();break; - case vm_vec:std::cout<<"vector";break; - case vm_hash:std::cout<<"hash";break; - case vm_func:std::cout<<"function";break; - case vm_scop:std::cout<<"closure";break; - } - std::cout<<"\n"; - } - return; -} void nasal_gc::clear() { int gc_mem_size=memory.size(); diff --git a/nasal_parse.h b/nasal_parse.h index 8f5acd9..b1acf9a 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -449,7 +449,7 @@ nasal_ast nasal_parse::args_gen() if(checked_dynamic_ids && i!=node_child_size-1) die(node.get_children()[i].get_line(),"dynamic identifier must be the end of argument list: "+args_format); } - std::map argname_table; + std::unordered_map argname_table; for(int i=0;i exec_code; + nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0 + nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1 + bool main_loop_break_mark; // when mark is false,break the main loop + int ptr; // program counter + int me_index; // this is the index of "me" in string_table + nasal_val* global_scope_addr; // global scope address,type vm_scop + nasal_gc gc; // garbage collector and memory manager + std::vector exec_code; // byte codes store here // main calculation stack nasal_val** val_stack; nasal_val** val_stack_top; @@ -26,9 +26,7 @@ private: std::stack call_stack; // iterator stack for forindex/foreach std::stack counter_stack; - // string table std::vector string_table; - // number table std::vector number_table; void die(std::string); bool check_condition(nasal_val*); @@ -98,7 +96,7 @@ public: nasal_vm::nasal_vm() { - val_stack=new nasal_val*[val_stack_MAX_DEPTH]; + val_stack=new nasal_val*[STACK_MAX_DEPTH]; val_stack_top=val_stack; local_scope_stack.push(NULL); return; @@ -139,14 +137,14 @@ bool nasal_vm::check_condition(nasal_val* value_addr) { int type=value_addr->get_type(); if(type==vm_num) - return (value_addr->get_number()!=0); + return value_addr->get_number(); else if(type==vm_str) { std::string str=value_addr->get_string(); double number=trans_string_to_number(str); if(std::isnan(number)) - return str.length()!=0; - return (number!=0); + return str.length(); + return number; } return false; } @@ -172,16 +170,14 @@ void nasal_vm::opr_pushnum() } void nasal_vm::opr_pushone() { - nasal_val* val_addr=gc.gc_alloc(vm_num); - val_addr->set_number(1); - *(++val_stack_top)=val_addr; + *(++val_stack_top)=one_addr; + gc.add_reference(one_addr); return; } void nasal_vm::opr_pushzero() { - nasal_val* val_addr=gc.gc_alloc(vm_num); - val_addr->set_number(0); - *(++val_stack_top)=val_addr; + *(++val_stack_top)=zero_addr; + gc.add_reference(zero_addr); return; } void nasal_vm::opr_pushnil() @@ -691,15 +687,17 @@ void nasal_vm::opr_foreach() void nasal_vm::opr_call() { nasal_val* val_addr=NULL; - int name_index=exec_code[ptr].index; nasal_val* local_scope_top=local_scope_stack.top(); + int name_index=exec_code[ptr].index; if(local_scope_top) - val_addr=local_scope_top->get_closure().get_value_address(name_index); - if(val_addr) { - gc.add_reference(val_addr); - *(++val_stack_top)=val_addr; - return; + val_addr=local_scope_top->get_closure().get_value_address(name_index); + if(val_addr) + { + gc.add_reference(val_addr); + *(++val_stack_top)=val_addr; + return; + } } val_addr=global_scope_addr->get_closure().get_value_address(name_index); if(val_addr) @@ -1097,6 +1095,10 @@ void nasal_vm::run(std::vector& strs,std::vector& nums,std: string_table=strs; number_table=nums; exec_code=exec; + zero_addr=gc.gc_alloc(vm_num); + zero_addr->set_number(0); + one_addr=gc.gc_alloc(vm_num); + one_addr->set_number(1); builtin_use_string_table.clear(); for(int i=0;i