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

View File

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

View File

@ -290,7 +290,7 @@ nasal_ast nasal_parse::number_gen()
nasal_ast node;
node.set_line(tok_list[ptr].line);
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;
}

View File

@ -24,10 +24,6 @@ private:
// if error occurred,this value will add 1
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
int vector_generation(nasal_ast&,int);
// generate hash and return gc place of this hash
@ -206,20 +202,6 @@ void nasal_runtime::run()
}
// 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 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;
if(node.get_type()==ast_identifier)
{
std::string id_name=node.get_str();
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)
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)
{
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;
return -1;
}
return mem_address;
}
std::string id_name=node.get_children()[0].get_str();
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)
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)
{
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;
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);
}
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)
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)
{
if(local_scope_addr>=0)