This commit is contained in:
Valk Richard Li 2020-11-09 00:26:15 +08:00
parent b9a53b3c4a
commit fd8d3acfed
5 changed files with 79 additions and 112 deletions

View File

@ -7,6 +7,7 @@ private:
int line; int line;
int type; int type;
std::string str; std::string str;
double num;
std::vector<nasal_ast> children; std::vector<nasal_ast> children;
public: public:
nasal_ast(); nasal_ast();
@ -17,10 +18,12 @@ public:
void set_line(int); void set_line(int);
void set_type(int); void set_type(int);
void set_str(std::string&); void set_str(std::string&);
void set_num(double);
void add_child(nasal_ast); void add_child(nasal_ast);
int get_line(); int get_line();
int get_type(); int get_type();
std::string get_str(); std::string get_str();
double get_num();
std::vector<nasal_ast>& get_children(); std::vector<nasal_ast>& get_children();
void print_ast(int); void print_ast(int);
}; };
@ -29,7 +32,6 @@ nasal_ast::nasal_ast()
{ {
this->line=0; this->line=0;
this->type=ast_null; this->type=ast_null;
this->str="";
return; return;
} }
@ -38,13 +40,13 @@ nasal_ast::nasal_ast(const nasal_ast& tmp)
this->line=tmp.line; this->line=tmp.line;
this->type=tmp.type; this->type=tmp.type;
this->str=tmp.str; this->str=tmp.str;
this->num=tmp.num;
this->children=tmp.children; this->children=tmp.children;
return; return;
} }
nasal_ast::~nasal_ast() nasal_ast::~nasal_ast()
{ {
this->str.clear();
this->children.clear(); this->children.clear();
return; return;
} }
@ -54,6 +56,7 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
this->line=tmp.line; this->line=tmp.line;
this->type=tmp.type; this->type=tmp.type;
this->str=tmp.str; this->str=tmp.str;
this->num=tmp.num;
this->children=tmp.children; this->children=tmp.children;
return *this; return *this;
} }
@ -61,8 +64,9 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
void nasal_ast::clear() void nasal_ast::clear()
{ {
this->line=0; this->line=0;
this->type=ast_null;
this->str=""; this->str="";
this->num=0;
this->type=ast_null;
this->children.clear(); this->children.clear();
return; return;
} }
@ -85,6 +89,12 @@ void nasal_ast::set_str(std::string& s)
return; return;
} }
void nasal_ast::set_num(double n)
{
this->num=n;
return;
}
void nasal_ast::add_child(nasal_ast ast) void nasal_ast::add_child(nasal_ast ast)
{ {
children.push_back(ast); children.push_back(ast);
@ -106,6 +116,11 @@ std::string nasal_ast::get_str()
return this->str; return this->str;
} }
double nasal_ast::get_num()
{
return this->num;
}
std::vector<nasal_ast>& nasal_ast::get_children() std::vector<nasal_ast>& nasal_ast::get_children()
{ {
return this->children; return this->children;
@ -117,8 +132,10 @@ void nasal_ast::print_ast(int depth)
for(int i=0;i<depth;++i) indentation+="| "; for(int i=0;i<depth;++i) indentation+="| ";
indentation+=ast_str(this->type); indentation+=ast_str(this->type);
std::cout<<indentation; std::cout<<indentation;
if(this->type==ast_number || this->type==ast_string || this->type==ast_identifier || this->type==ast_dynamic_id || this->type==ast_call_hash) if(this->type==ast_string || this->type==ast_identifier || this->type==ast_dynamic_id || this->type==ast_call_hash)
std::cout<<":"<<this->str; std::cout<<":"<<this->str;
else if(this->type==ast_number)
std::cout<<":"<<this->num;
std::cout<<std::endl; std::cout<<std::endl;
int child_size=this->children.size(); int child_size=this->children.size();
for(int i=0;i<child_size;++i) for(int i=0;i<child_size;++i)

View File

@ -76,6 +76,8 @@ void nasal_codegen::output_root(nasal_ast& root)
if(type==ast_number || type==ast_string || type==ast_identifier || type==ast_dynamic_id || type==ast_call_hash) if(type==ast_number || type==ast_string || type==ast_identifier || type==ast_dynamic_id || type==ast_call_hash)
{ {
std::string tmp=root.get_str(); std::string tmp=root.get_str();
if(type==ast_number)
tmp=trans_number_to_string(root.get_num());
if(std::find(string_table.begin(),string_table.end(),tmp)==string_table.end()) if(std::find(string_table.begin(),string_table.end(),tmp)==string_table.end())
{ {
string_table.push_back(tmp); string_table.push_back(tmp);
@ -164,7 +166,10 @@ void nasal_codegen::input_root(nasal_ast& root,std::ifstream& fin)
if(type==ast_number || type==ast_string || type==ast_identifier || type==ast_dynamic_id || type==ast_call_hash) if(type==ast_number || type==ast_string || type==ast_identifier || type==ast_dynamic_id || type==ast_call_hash)
{ {
std::string tmp=string_table[input_short(fin)]; std::string tmp=string_table[input_short(fin)];
root.set_str(tmp); if(type==ast_number)
root.set_num(trans_string_to_number(tmp));
else
root.set_str(tmp);
} }
for(unsigned short i=0;i<size;++i) for(unsigned short i=0;i<size;++i)
{ {

View File

@ -2,7 +2,6 @@
#define __NASAL_MISC_H__ #define __NASAL_MISC_H__
/* /*
check_numerable_string:
check if a string can be converted to a number check if a string can be converted to a number
strings like these below is correct: strings like these below is correct:
@ -15,79 +14,8 @@
'1e23' '1e23'
'1E-123' '1E-123'
'1.34E10' '1.34E10'
*/
inline bool check_hex_string(std::string str,int len)
{
for(int i=2;i<len;++i)
if(!(('0'<=str[i] && str[i]<='9') || ('a'<=str[i] && str[i]<='f') || ('A'<=str[i] && str[i]<='F')))
return false;
return true;
}
inline bool check_oct_string(std::string str,int len)
{
for(int i=2;i<len;++i)
if(str[i]<'0' || str[i]>'7')
return false;
return true;
}
inline bool check_dec_string(std::string str,int len)
{
int i=0;
// check integer part
while('0'<=str[i] && str[i]<='9' && i<len) ++i;
if(i==len) return true;
if(str[i]!='e' && str[i]!='E' && str[i]!='.') return false;
// check decimal part
if(str[i]=='.')
{
++i;
if(i==len) return false;
while('0'<=str[i] && str[i]<='9' && i<len) ++i;
}
if(i==len) return true;
if(str[i]!='e' && str[i]!='E') return false;
// check scientific notation
if(str[i]=='e' || str[i]=='E')
{
++i;
if(i==len) return false;
if(str[i]=='-' || str[i]=='+')
{
++i;
if(i==len) return false;
}
for(;i<len;++i)
if(str[i]<'0' || str[i]>'9')
return false;
}
return true;
}
bool check_numerable_string(std::string str) if this string cannot be converted to a number,it will return nan
{
int len=str.length();
if(!len) return false;
if(str[0]=='-' || str[0]=='+')
{
if(len==1) return false;
std::string tmp="";
for(int i=1;i<len;++i)
tmp+=str[i];
str=tmp;
--len;
}
if(len>2 && str[0]=='0' && str[1]=='x')
return check_hex_string(str,len);
else if(len>2 && str[0]=='0' && str[1]=='o')
return check_oct_string(str,len);
else if('0'<=str[0] && str[0]<='9')
return check_dec_string(str,len);
return false;
}
/*
trans_string_to_number:
convert string to number
*/ */
inline double hex_to_double(std::string str,int len) inline double hex_to_double(std::string str,int len)
{ {
@ -100,6 +28,8 @@ inline double hex_to_double(std::string str,int len)
ret+=num_pow*(str[i]-'a'+10); ret+=num_pow*(str[i]-'a'+10);
else if('A'<=str[i] && str[i]<='F') else if('A'<=str[i] && str[i]<='F')
ret+=num_pow*(str[i]-'A'+10); ret+=num_pow*(str[i]-'A'+10);
else
return (1/0.0)+(-1/0.0);
num_pow*=16; num_pow*=16;
} }
return ret; return ret;
@ -109,7 +39,10 @@ inline double oct_to_double(std::string str,int len)
double ret=0,num_pow=1; double ret=0,num_pow=1;
for(int i=len-1;i>1;--i) for(int i=len-1;i>1;--i)
{ {
ret+=num_pow*(str[i]-'0'); if('0'<=str[i] && str[i]<='8')
ret+=num_pow*(str[i]-'0');
else
return (1/0.0)+(-1/0.0);
num_pow*=8; num_pow*=8;
} }
return ret; return ret;
@ -124,9 +57,13 @@ inline double dec_to_double(std::string str,int len)
++i; ++i;
} }
if(i==len) return ret; if(i==len) return ret;
if(str[i]!='.' && str[i]!='e' && str[i]!='E')
return (1/0.0)+(-1/0.0);
if(str[i]=='.') if(str[i]=='.')
{ {
++i; ++i;
if(i==len)
return (1/0.0)+(-1/0.0);
double num_pow=0.1; double num_pow=0.1;
while('0'<=str[i] && str[i]<='9' && i<len) while('0'<=str[i] && str[i]<='9' && i<len)
{ {
@ -136,14 +73,27 @@ inline double dec_to_double(std::string str,int len)
} }
} }
if(i==len) return ret; if(i==len) return ret;
if(str[i]!='e' && str[i]!='E')
return (1/0.0)+(-1/0.0);
if(str[i]=='e' || str[i]=='E') if(str[i]=='e' || str[i]=='E')
{ {
++i; ++i;
bool is_negative=(str[i]=='-'); if(i==len)
if(str[i]=='-' || str[i]=='+') ++i; return (1/0.0)+(-1/0.0);
double negative=(str[i]=='-'? -1:1);
if(str[i]=='-' || str[i]=='+')
++i;
if(i==len)
return (1/0.0)+(-1/0.0);
double num_pow=0; double num_pow=0;
for(;i<len;++i) num_pow=num_pow*10+(str[i]-'0'); for(;i<len;++i)
num_pow=std::pow(10,is_negative?-num_pow:num_pow); {
if('0'<=str[i] && str[i]<='9')
num_pow=num_pow*10+(str[i]-'0');
else
return (1/0.0)+(-1/0.0);
}
num_pow=std::pow(10,negative*num_pow);
ret*=num_pow; ret*=num_pow;
} }
return ret; return ret;
@ -153,7 +103,8 @@ double trans_string_to_number(std::string str)
bool is_negative=false; bool is_negative=false;
int len=str.length(); int len=str.length();
double ret_num=0; double ret_num=0;
if(!len) return 0; if(!len)
return (1/0.0)+(-1/0.0);
if(str[0]=='-' || str[0]=='+') if(str[0]=='-' || str[0]=='+')
{ {
is_negative=(str[0]=='-'); is_negative=(str[0]=='-');
@ -162,12 +113,14 @@ double trans_string_to_number(std::string str)
tmp.push_back(str[i]); tmp.push_back(str[i]);
str=tmp; str=tmp;
--len; --len;
if(!len)
return (1/0.0)+(-1/0.0);
} }
if(len>2 && str[0]=='0' && str[1]=='x') if(len>2 && str[0]=='0' && str[1]=='x')
ret_num=hex_to_double(str,len); ret_num=hex_to_double(str,len);
else if(len>2 && str[0]=='0' && str[1]=='o') else if(len>2 && str[0]=='0' && str[1]=='o')
ret_num=oct_to_double(str,len); ret_num=oct_to_double(str,len);
else if('0'<=str[0] && str[0]<='9') else
ret_num=dec_to_double(str,len); ret_num=dec_to_double(str,len);
return is_negative?-ret_num:ret_num; return is_negative?-ret_num:ret_num;
} }

View File

@ -290,7 +290,7 @@ nasal_ast nasal_parse::number_gen()
nasal_ast node; nasal_ast node;
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
node.set_type(ast_number); node.set_type(ast_number);
node.set_str(tok_list[ptr].str); node.set_num(trans_string_to_number(tok_list[ptr].str));
return node; return node;
} }

View File

@ -24,10 +24,6 @@ private:
// if error occurred,this value will add 1 // if error occurred,this value will add 1
int error; int error;
// generate number and return gc place of this number
int number_generation(nasal_ast&);
// generate string and return gc place of this string
int string_generation(nasal_ast&);
// generate vector and return gc place of this vector // generate vector and return gc place of this vector
int vector_generation(nasal_ast&,int); int vector_generation(nasal_ast&,int);
// generate hash and return gc place of this hash // generate hash and return gc place of this hash
@ -206,20 +202,6 @@ void nasal_runtime::run()
} }
// private functions // private functions
int nasal_runtime::number_generation(nasal_ast& node)
{
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).set_type(vm_number);
nasal_vm.gc_get(new_addr).set_number(trans_string_to_number(node.get_str()));
return new_addr;
}
int nasal_runtime::string_generation(nasal_ast& node)
{
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).set_type(vm_string);
nasal_vm.gc_get(new_addr).set_string(node.get_str());
return new_addr;
}
int nasal_runtime::vector_generation(nasal_ast& node,int local_scope_addr) int nasal_runtime::vector_generation(nasal_ast& node,int local_scope_addr)
{ {
int new_addr=nasal_vm.gc_alloc(); int new_addr=nasal_vm.gc_alloc();
@ -1154,25 +1136,27 @@ int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
int mem_address=-1; int mem_address=-1;
if(node.get_type()==ast_identifier) if(node.get_type()==ast_identifier)
{ {
std::string id_name=node.get_str();
if(local_scope_addr>=0) if(local_scope_addr>=0)
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(node.get_str()); mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
if(mem_address<0) if(mem_address<0)
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(node.get_str()); mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
if(mem_address<0) if(mem_address<0)
{ {
std::cout<<">> [runtime] call_scalar_mem: cannot find value named \'"<<node.get_str()<<"\'.\n"; std::cout<<">> [runtime] call_scalar_mem: cannot find value named \'"<<id_name<<"\'.\n";
++error; ++error;
return -1; return -1;
} }
return mem_address; return mem_address;
} }
std::string id_name=node.get_children()[0].get_str();
if(local_scope_addr>=0) if(local_scope_addr>=0)
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(node.get_children()[0].get_str()); mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name);
if(mem_address<0) if(mem_address<0)
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(node.get_children()[0].get_str()); mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name);
if(mem_address<0) if(mem_address<0)
{ {
std::cout<<">> [runtime] call_scalar_mem: cannot find value named \'"<<node.get_children()[0].get_str()<<"\'.\n"; std::cout<<">> [runtime] call_scalar_mem: cannot find value named \'"<<id_name<<"\'.\n";
++error; ++error;
return -1; return -1;
} }
@ -1304,9 +1288,17 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
nasal_vm.gc_get(ret_address).set_type(vm_nil); nasal_vm.gc_get(ret_address).set_type(vm_nil);
} }
else if(calculation_type==ast_number) else if(calculation_type==ast_number)
ret_address=number_generation(node); {
ret_address=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_address).set_type(vm_number);
nasal_vm.gc_get(ret_address).set_number(node.get_num());
}
else if(calculation_type==ast_string) else if(calculation_type==ast_string)
ret_address=string_generation(node); {
ret_address=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_address).set_type(vm_string);
nasal_vm.gc_get(ret_address).set_string(node.get_str());
}
else if(calculation_type==ast_identifier) else if(calculation_type==ast_identifier)
{ {
if(local_scope_addr>=0) if(local_scope_addr>=0)