change map to unordered_map

This commit is contained in:
Valk Richard Li 2021-03-01 15:54:58 +08:00
parent 79dc13f419
commit a421470715
8 changed files with 89 additions and 109 deletions

View File

@ -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. If you want to add your own built-in functions,define the function in nasal_builtin.h.
definition: Definition:
```C++ ```C++
nasal_val* builtin_chr(nasal_val*,nasal_gc&); nasal_val* builtin_chr(nasal_val*,nasal_gc&);

View File

@ -9,25 +9,27 @@ nasal_vm vm;
void help() void help()
{ {
std::cout<<">> [\"file\"] input a file name.\n"; std::cout
std::cout<<">> [help ] show help.\n"; <<">> [\"file\"] input a file name.\n"
std::cout<<">> [clear ] clear the screen.\n"; <<">> [help ] show help.\n"
std::cout<<">> [lex ] use lexer to turn code into tokens.\n"; <<">> [clear ] clear the screen.\n"
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n"; <<">> [lex ] use lexer to turn code into tokens.\n"
std::cout<<">> [code ] show byte code.\n"; <<">> [ast ] do parsing and check the abstract syntax tree.\n"
std::cout<<">> [exec ] execute program on bytecode vm.\n"; <<">> [code ] show byte code.\n"
std::cout<<">> [logo ] print logo of nasal .\n"; <<">> [exec ] execute program on bytecode vm.\n"
std::cout<<">> [exit ] quit nasal interpreter.\n"; <<">> [logo ] print logo of nasal .\n"
<<">> [exit ] quit nasal interpreter.\n";
return; return;
} }
void logo() void logo()
{ {
std::cout<<" __ _ \n"; std::cout
std::cout<<" /\\ \\ \\__ _ ___ __ _| | \n"; <<" __ _ \n"
std::cout<<" / \\/ / _` / __|/ _` | | \n"; <<" /\\ \\ \\__ _ ___ __ _| | \n"
std::cout<<" / /\\ / (_| \\__ \\ (_| | | \n"; <<" / \\/ / _` / __|/ _` | | \n"
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"; <<" / /\\ / (_| \\__ \\ (_| | | \n"
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n";
return; return;
} }

View File

@ -19,7 +19,7 @@
#include <stack> #include <stack>
#include <queue> #include <queue>
#include <vector> #include <vector>
#include <map> #include <unordered_map>
/* /*
check if a string can be converted to a number check if a string can be converted to a number

View File

@ -9,7 +9,7 @@
// } // }
// builtin function nasal_call_builtin_std_cout is wrapped up by print // builtin function nasal_call_builtin_std_cout is wrapped up by print
std::map<std::string,int> builtin_use_string_table; std::unordered_map<std::string,int> builtin_use_string_table;
// used to find values that builtin function uses // used to find values that builtin function uses
#define in_builtin_find(value_name_string) \ #define in_builtin_find(value_name_string) \
(\ (\

View File

@ -128,8 +128,8 @@ struct opcode
class nasal_codegen class nasal_codegen
{ {
private: private:
std::map<double,int> number_table; std::unordered_map<double,int> number_table;
std::map<std::string,int> string_table; std::unordered_map<std::string,int> string_table;
std::vector<double> number_result_table; std::vector<double> number_result_table;
std::vector<std::string> string_result_table; std::vector<std::string> string_result_table;
std::vector<opcode> exec_code; std::vector<opcode> exec_code;
@ -918,9 +918,9 @@ void nasal_codegen::main_progress(nasal_ast& ast)
gen(op_nop,0); gen(op_nop,0);
number_result_table.resize(number_table.size()); number_result_table.resize(number_table.size());
string_result_table.resize(string_table.size()); string_result_table.resize(string_table.size());
for(std::map<double,int>::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; number_result_table[i->second]=i->first;
for(std::map<std::string,int>::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; string_result_table[i->second]=i->first;
return; return;
} }

View File

@ -40,7 +40,7 @@ class nasal_hash
{ {
private: private:
nasal_gc& gc; nasal_gc& gc;
std::map<std::string,nasal_val*> elems; std::unordered_map<std::string,nasal_val*> elems;
public: public:
nasal_hash(nasal_gc&); nasal_hash(nasal_gc&);
~nasal_hash(); ~nasal_hash();
@ -82,7 +82,7 @@ class nasal_scop
{ {
private: private:
nasal_gc& gc; nasal_gc& gc;
std::map<int,nasal_val*> elems; std::unordered_map<int,nasal_val*> elems;
public: public:
nasal_scop(nasal_gc&); nasal_scop(nasal_gc&);
~nasal_scop(); ~nasal_scop();
@ -133,7 +133,6 @@ private:
public: public:
~nasal_gc(); ~nasal_gc();
void clear(); void clear();
void debug();
nasal_val* gc_alloc(int); nasal_val* gc_alloc(int);
void add_reference(nasal_val*); void add_reference(nasal_val*);
void del_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() nasal_hash::~nasal_hash()
{ {
for(std::map<std::string,nasal_val*>::iterator iter=elems.begin();iter!=elems.end();++iter) for(auto iter=elems.begin();iter!=elems.end();++iter)
gc.del_reference(iter->second); gc.del_reference(iter->second);
elems.clear(); elems.clear();
return; return;
} }
void nasal_hash::add_elem(std::string key,nasal_val* value_address) 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; elems[key]=value_address;
return; return;
} }
void nasal_hash::del_elem(std::string key) void nasal_hash::del_elem(std::string key)
{ {
if(elems.find(key)!=elems.end()) if(!elems.count(key))
{ {
gc.del_reference(elems[key]); gc.del_reference(elems[key]);
elems.erase(key); elems.erase(key);
@ -252,16 +251,16 @@ int nasal_hash::size()
} }
nasal_val* nasal_hash::get_special_para(std::string key) nasal_val* nasal_hash::get_special_para(std::string key)
{ {
if(elems.find(key)!=elems.end()) if(elems.count(key))
return elems[key]; return elems[key];
return NULL; return NULL;
} }
nasal_val* nasal_hash::get_value_address(std::string key) nasal_val* nasal_hash::get_value_address(std::string key)
{ {
nasal_val* ret_value_addr=NULL; nasal_val* ret_value_addr=NULL;
if(elems.find(key)!=elems.end()) if(elems.count(key))
return elems[key]; return elems[key];
else if(elems.find("parents")!=elems.end()) else if(elems.count("parents"))
{ {
nasal_val* val_addr=elems["parents"]; nasal_val* val_addr=elems["parents"];
if(val_addr->get_type()==vm_vec) 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** nasal_hash::get_mem_address(std::string key)
{ {
nasal_val** mem_addr=NULL; nasal_val** mem_addr=NULL;
if(elems.find(key)!=elems.end()) if(elems.count(key))
return &elems[key]; return &elems[key];
else if(elems.find("parents")!=elems.end()) else if(elems.count("parents"))
{ {
nasal_val* val_addr=elems["parents"]; nasal_val* val_addr=elems["parents"];
if(val_addr->get_type()==vm_vec) 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) bool nasal_hash::check_contain(std::string key)
{ {
if(elems.find(key)!=elems.end()) if(elems.count(key))
return true; return true;
if(elems.find("parents")!=elems.end()) if(elems.count("parents"))
{ {
bool result=false; bool result=false;
nasal_val* val_addr=elems["parents"]; 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_val* ret_addr=gc.gc_alloc(vm_vec);
nasal_vec& ref_vec=ret_addr->get_vector(); nasal_vec& ref_vec=ret_addr->get_vector();
for(std::map<std::string,nasal_val*>::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); nasal_val* str_addr=gc.gc_alloc(vm_str);
str_addr->set_string(iter->first); str_addr->set_string(iter->first);
@ -343,12 +342,15 @@ nasal_val* nasal_hash::get_keys()
} }
void nasal_hash::print() void nasal_hash::print()
{ {
std::cout<<"{"; std::cout<<'{';
if(!elems.size()) if(!elems.size())
std::cout<<"}";
for(std::map<std::string,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i)
{ {
std::cout<<i->first<<":"; std::cout<<'}';
return;
}
for(auto i=elems.begin();i!=elems.end();++i)
{
std::cout<<i->first<<':';
nasal_val* tmp=i->second; nasal_val* tmp=i->second;
switch(tmp->get_type()) switch(tmp->get_type())
{ {
@ -359,9 +361,9 @@ void nasal_hash::print()
case vm_hash: tmp->get_hash().print(); break; case vm_hash: tmp->get_hash().print(); break;
case vm_func: std::cout<<"func(...){...}"; break; case vm_func: std::cout<<"func(...){...}"; break;
} }
std::cout<<",}"[(++i)==elems.end()]; std::cout<<',';
--i;
} }
std::cout<<'}';
return; return;
} }
@ -437,14 +439,14 @@ nasal_scop::nasal_scop(nasal_gc& ngc):gc(ngc)
} }
nasal_scop::~nasal_scop() nasal_scop::~nasal_scop()
{ {
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i) for(auto i=elems.begin();i!=elems.end();++i)
gc.del_reference(i->second); gc.del_reference(i->second);
elems.clear(); elems.clear();
return; return;
} }
void nasal_scop::add_new_value(int key,nasal_val* value_address) 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 // if this value already exists,delete the old value and update a new value
gc.del_reference(elems[key]); 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) nasal_val* nasal_scop::get_value_address(int key)
{ {
if(elems.find(key)!=elems.end()) if(elems.count(key))
return elems[key]; return elems[key];
return NULL; return NULL;
} }
nasal_val** nasal_scop::get_mem_address(int key) nasal_val** nasal_scop::get_mem_address(int key)
{ {
if(elems.find(key)!=elems.end()) if(elems.count(key))
return &(elems[key]); return &(elems[key]);
return NULL; return NULL;
} }
void nasal_scop::set_closure(nasal_scop& tmp) void nasal_scop::set_closure(nasal_scop& tmp)
{ {
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i) for(auto i=elems.begin();i!=elems.end();++i)
gc.del_reference(i->second); gc.del_reference(i->second);
elems=tmp.elems; elems=tmp.elems;
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i) for(auto i=elems.begin();i!=elems.end();++i)
gc.add_reference(i->second); gc.add_reference(i->second);
return; return;
} }
@ -566,13 +568,10 @@ int nasal_val::get_type()
} }
double nasal_val::to_number() double nasal_val::to_number()
{ {
switch(type) if(type==vm_num)
{ return ptr.num;
case vm_nil: return 0; else if(type==vm_str)
case vm_num: return ptr.num; return trans_string_to_number(*ptr.str);
case vm_str: return trans_string_to_number(*ptr.str);
default: return std::nan("");
}
return 0; return 0;
} }
double nasal_val::get_number() double nasal_val::get_number()
@ -581,12 +580,10 @@ double nasal_val::get_number()
} }
std::string nasal_val::to_string() std::string nasal_val::to_string()
{ {
switch(type) if(type==vm_str)
{ return *ptr.str;
case vm_num:return trans_number_to_string(ptr.num); else if(type==vm_num)
case vm_str:return *ptr.str; return trans_number_to_string(ptr.num);
default:return "";
}
return ""; return "";
} }
std::string nasal_val::get_string() std::string nasal_val::get_string()
@ -623,27 +620,6 @@ nasal_gc::~nasal_gc()
memory.clear(); memory.clear();
return; return;
} }
void nasal_gc::debug()
{
int gc_mem_size=memory.size();
for(int i=0;i<gc_mem_size;++i)
if(memory[i]->ref_cnt)
{
std::cout<<">> [debug] "<<i<<": "<<memory[i]->ref_cnt<<" ";
switch(memory[i]->get_type())
{
case vm_nil:std::cout<<"nil";break;
case vm_num:std::cout<<"number "<<memory[i]->get_number();break;
case vm_str:std::cout<<"string "<<memory[i]->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() void nasal_gc::clear()
{ {
int gc_mem_size=memory.size(); int gc_mem_size=memory.size();

View File

@ -449,7 +449,7 @@ nasal_ast nasal_parse::args_gen()
if(checked_dynamic_ids && i!=node_child_size-1) 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); die(node.get_children()[i].get_line(),"dynamic identifier must be the end of argument list: "+args_format);
} }
std::map<std::string,bool> argname_table; std::unordered_map<std::string,bool> argname_table;
for(int i=0;i<node_child_size;++i) for(int i=0;i<node_child_size;++i)
{ {
std::string new_name; std::string new_name;

View File

@ -1,18 +1,18 @@
#ifndef __NASAL_VM_H__ #ifndef __NASAL_VM_H__
#define __NASAL_VM_H__ #define __NASAL_VM_H__
#define val_stack_MAX_DEPTH 8192 #define STACK_MAX_DEPTH 8192
class nasal_vm class nasal_vm
{ {
private: private:
bool main_loop_break_mark; nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0
int ptr; // program counter nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1
int me_index; // this is the index of "me" in string_table bool main_loop_break_mark; // when mark is false,break the main loop
nasal_val* global_scope_addr; int ptr; // program counter
// garbage collector and memory manager int me_index; // this is the index of "me" in string_table
nasal_gc gc; nasal_val* global_scope_addr; // global scope address,type vm_scop
// byte codes store here nasal_gc gc; // garbage collector and memory manager
std::vector<opcode> exec_code; std::vector<opcode> exec_code; // byte codes store here
// main calculation stack // main calculation stack
nasal_val** val_stack; nasal_val** val_stack;
nasal_val** val_stack_top; nasal_val** val_stack_top;
@ -26,9 +26,7 @@ private:
std::stack<int> call_stack; std::stack<int> call_stack;
// iterator stack for forindex/foreach // iterator stack for forindex/foreach
std::stack<int> counter_stack; std::stack<int> counter_stack;
// string table
std::vector<std::string> string_table; std::vector<std::string> string_table;
// number table
std::vector<double> number_table; std::vector<double> number_table;
void die(std::string); void die(std::string);
bool check_condition(nasal_val*); bool check_condition(nasal_val*);
@ -98,7 +96,7 @@ public:
nasal_vm::nasal_vm() 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; val_stack_top=val_stack;
local_scope_stack.push(NULL); local_scope_stack.push(NULL);
return; return;
@ -139,14 +137,14 @@ bool nasal_vm::check_condition(nasal_val* value_addr)
{ {
int type=value_addr->get_type(); int type=value_addr->get_type();
if(type==vm_num) if(type==vm_num)
return (value_addr->get_number()!=0); return value_addr->get_number();
else if(type==vm_str) else if(type==vm_str)
{ {
std::string str=value_addr->get_string(); std::string str=value_addr->get_string();
double number=trans_string_to_number(str); double number=trans_string_to_number(str);
if(std::isnan(number)) if(std::isnan(number))
return str.length()!=0; return str.length();
return (number!=0); return number;
} }
return false; return false;
} }
@ -172,16 +170,14 @@ void nasal_vm::opr_pushnum()
} }
void nasal_vm::opr_pushone() void nasal_vm::opr_pushone()
{ {
nasal_val* val_addr=gc.gc_alloc(vm_num); *(++val_stack_top)=one_addr;
val_addr->set_number(1); gc.add_reference(one_addr);
*(++val_stack_top)=val_addr;
return; return;
} }
void nasal_vm::opr_pushzero() void nasal_vm::opr_pushzero()
{ {
nasal_val* val_addr=gc.gc_alloc(vm_num); *(++val_stack_top)=zero_addr;
val_addr->set_number(0); gc.add_reference(zero_addr);
*(++val_stack_top)=val_addr;
return; return;
} }
void nasal_vm::opr_pushnil() void nasal_vm::opr_pushnil()
@ -691,15 +687,17 @@ void nasal_vm::opr_foreach()
void nasal_vm::opr_call() void nasal_vm::opr_call()
{ {
nasal_val* val_addr=NULL; nasal_val* val_addr=NULL;
int name_index=exec_code[ptr].index;
nasal_val* local_scope_top=local_scope_stack.top(); nasal_val* local_scope_top=local_scope_stack.top();
int name_index=exec_code[ptr].index;
if(local_scope_top) 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_addr=local_scope_top->get_closure().get_value_address(name_index);
*(++val_stack_top)=val_addr; if(val_addr)
return; {
gc.add_reference(val_addr);
*(++val_stack_top)=val_addr;
return;
}
} }
val_addr=global_scope_addr->get_closure().get_value_address(name_index); val_addr=global_scope_addr->get_closure().get_value_address(name_index);
if(val_addr) if(val_addr)
@ -1097,6 +1095,10 @@ void nasal_vm::run(std::vector<std::string>& strs,std::vector<double>& nums,std:
string_table=strs; string_table=strs;
number_table=nums; number_table=nums;
exec_code=exec; 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(); builtin_use_string_table.clear();
for(int i=0;i<string_table.size();++i) for(int i=0;i<string_table.size();++i)
{ {