change map to unordered_map
This commit is contained in:
parent
79dc13f419
commit
a421470715
|
@ -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&);
|
||||
|
|
30
main.cpp
30
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;
|
||||
}
|
||||
|
||||
|
|
2
nasal.h
2
nasal.h
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
(\
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
96
nasal_gc.h
96
nasal_gc.h
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
56
nasal_vm.h
56
nasal_vm.h
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue