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.
definition:
Definition:
```C++
nasal_val* builtin_chr(nasal_val*,nasal_gc&);

View File

@ -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;
}

View File

@ -19,7 +19,7 @@
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
/*
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
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
#define in_builtin_find(value_name_string) \
(\

View File

@ -128,8 +128,8 @@ struct opcode
class nasal_codegen
{
private:
std::map<double,int> number_table;
std::map<std::string,int> string_table;
std::unordered_map<double,int> number_table;
std::unordered_map<std::string,int> string_table;
std::vector<double> number_result_table;
std::vector<std::string> string_result_table;
std::vector<opcode> 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<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;
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;
return;
}

View File

@ -40,7 +40,7 @@ class nasal_hash
{
private:
nasal_gc& gc;
std::map<std::string,nasal_val*> elems;
std::unordered_map<std::string,nasal_val*> elems;
public:
nasal_hash(nasal_gc&);
~nasal_hash();
@ -82,7 +82,7 @@ class nasal_scop
{
private:
nasal_gc& gc;
std::map<int,nasal_val*> elems;
std::unordered_map<int,nasal_val*> 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<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);
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<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);
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<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;
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<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);
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<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);
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);
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;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()
{
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)
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)
{
std::string new_name;

View File

@ -1,18 +1,18 @@
#ifndef __NASAL_VM_H__
#define __NASAL_VM_H__
#define val_stack_MAX_DEPTH 8192
#define STACK_MAX_DEPTH 8192
class nasal_vm
{
private:
bool main_loop_break_mark;
int ptr; // program counter
int me_index; // this is the index of "me" in string_table
nasal_val* global_scope_addr;
// garbage collector and memory manager
nasal_gc gc;
// byte codes store here
std::vector<opcode> 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<opcode> 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<int> call_stack;
// iterator stack for forindex/foreach
std::stack<int> counter_stack;
// string table
std::vector<std::string> string_table;
// number table
std::vector<double> 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<std::string>& strs,std::vector<double>& 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<string_table.size();++i)
{