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

View File

@ -28,10 +28,12 @@ void help()
<<" -l, --lex | view token info.\n"
<<" -a, --ast | view abstract syntax tree.\n"
<<" -c, --code | view bytecode.\n"
<<" -e, --exec | execute.\n"
<<" -t, --time | execute and get the running time.\n"
<<" -o, --opcnt | execute and count used operands.\n"
<<" -d, --detail | execute and get detail crash info.\n"
<<" -op, --optimize| use optimizer(beta).\n"
<<" | if want to use -op and run, please use -op -e/-t/-o/-d.\n"
<<" -dbg, --debug | debug mode (this will ignore -t -o -d).\n"
<<"file:\n"
<<" input file name to execute script file.\n";
@ -139,6 +141,8 @@ int main(int argc,const char* argv[])
cmd|=VM_ASTINFO;
else if(s=="--code" || s=="-c")
cmd|=VM_CODEINFO;
else if(s=="--exec" || s=="-e")
cmd|=VM_EXEC;
else if(s=="--opcnt" || s=="-o")
cmd|=VM_OPCALLNUM|VM_EXEC;
else if(s=="--time" || s=="-t")

View File

@ -2,33 +2,33 @@
nasal:main.cpp nasal_ast.h nasal_err.h nasal_builtin.h nasal_opt.h nasal_codegen.h nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal_dbg.h nasal.h
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
test:nasal
./nasal test/ascii-art.nas
./nasal -c test/bf.nas
./nasal -c test/bfconvertor.nas
./nasal test/bfs.nas
./nasal -t test/bigloop.nas
./nasal test/bp.nas
./nasal test/calc.nas
./nasal test/choice.nas
./nasal test/class.nas
./nasal -c test/exception.nas
./nasal -t test/fib.nas
./nasal test/filesystem.nas
./nasal test/hexdump.nas
./nasal test/json.nas
./nasal test/leetcode1319.nas
./nasal test/lexer.nas
./nasal test/life.nas
./nasal -t test/loop.nas
./nasal -c test/mandel.nas
./nasal -t test/mandelbrot.nas
./nasal -c test/module_test.nas
./nasal test/nasal_test.nas
./nasal -t test/pi.nas
./nasal -t test/prime.nas
./nasal -t test/quick_sort.nas
./nasal test/scalar.nas
./nasal test/trait.nas
./nasal -t test/turingmachine.nas
./nasal -t test/ycombinator.nas
./nasal -op -e test/ascii-art.nas
./nasal -op -c test/bf.nas
./nasal -op -c test/bfconvertor.nas
./nasal -op -e test/bfs.nas
./nasal -op -t test/bigloop.nas
./nasal -op -e test/bp.nas
./nasal -op -e test/calc.nas
./nasal -op -e test/choice.nas
./nasal -op -e test/class.nas
./nasal -op -c test/exception.nas
./nasal -op -t test/fib.nas
./nasal -op -e test/filesystem.nas
./nasal -op -e test/hexdump.nas
./nasal -op -e test/json.nas
./nasal -op -e test/leetcode1319.nas
./nasal -op -e test/lexer.nas
./nasal -op -e test/life.nas
./nasal -op -t test/loop.nas
./nasal -op -c test/mandel.nas
./nasal -op -t test/mandelbrot.nas
./nasal -op -c test/module_test.nas
./nasal -op -e test/nasal_test.nas
./nasal -op -t test/pi.nas
./nasal -op -t test/prime.nas
./nasal -op -t test/quick_sort.nas
./nasal -op -e test/scalar.nas
./nasal -op -e test/trait.nas
./nasal -op -t test/turingmachine.nas
./nasal -op -t test/ycombinator.nas

View File

@ -3,7 +3,7 @@
enum ast_node
{
ast_null=0,
ast_null=0, // null node
ast_root, // mark the root node of ast
ast_block, // expression block
ast_file, // used to store which file the sub-tree is on, only used in main block

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