add constant string calculation in optimizer

This commit is contained in:
ValKmjolnir
2022-02-01 21:20:36 +08:00
parent eaa54035ff
commit bf780514e6
5 changed files with 71 additions and 48 deletions
+35 -16
View File
@@ -1,22 +1,17 @@
#ifndef __NASAL_OPT_H__
#define __NASAL_OPT_H__
void calc_const_num(nasal_ast& root)
void const_str(nasal_ast& root)
{
auto& vec=root.child();
root.set_str(vec[0].str()+vec[1].str());
root.child().clear();
root.set_type(ast_str);
}
void const_num(nasal_ast& root)
{
auto& vec=root.child();
for(auto& i:vec)
calc_const_num(i);
if(root.type()!=ast_add &&
root.type()!=ast_sub &&
root.type()!=ast_mult &&
root.type()!=ast_div &&
root.type()!=ast_less &&
root.type()!=ast_leq &&
root.type()!=ast_grt &&
root.type()!=ast_geq)
return;
if(vec.size()!=2 || vec[0].type()!=ast_num || vec[1].type()!=ast_num)
return;
double res;
switch(root.type())
{
@@ -29,15 +24,39 @@ void calc_const_num(nasal_ast& root)
case ast_grt: res=vec[0].num()>vec[1].num(); break;
case ast_geq: res=vec[0].num()>=vec[1].num();break;
}
if(std::isinf(res) || std::isnan(res)) // inf and nan will cause number hashmap error in codegen
// inf and nan will cause number hashmap error in codegen
if(std::isinf(res) || std::isnan(res))
return;
root.set_num(res);
root.child().clear();
root.set_type(ast_num);
}
void calc_const(nasal_ast& root)
{
auto& vec=root.child();
for(auto& i:vec)
calc_const(i);
if(vec.size()!=2)
return;
if(root.type()!=ast_add &&
root.type()!=ast_sub &&
root.type()!=ast_mult &&
root.type()!=ast_div &&
root.type()!=ast_link &&
root.type()!=ast_less &&
root.type()!=ast_leq &&
root.type()!=ast_grt &&
root.type()!=ast_geq)
return;
if(root.type()==ast_link && vec[0].type()==ast_str && vec[1].type()==ast_str)
const_str(root);
else if(root.type()!=ast_link && vec[0].type()==ast_num && vec[1].type()==ast_num)
const_num(root);
}
void optimize(nasal_ast& root)
{
for(auto& i:root.child())
calc_const_num(i);
calc_const(i);
}
#endif