add optimizer

optimizer now does one work: calculate const number before generating bytecode
This commit is contained in:
ValKmjolnir 2022-01-22 00:41:08 +08:00
parent 630c99c39a
commit 40344455e6
5 changed files with 48 additions and 1 deletions

View File

@ -83,6 +83,7 @@ void execute(const std::string& file,const uint32_t cmd)
parse.print();
// code generator gets parser's ast and linker's import file list to generate code
optimize(parse.ast());
gen.compile(parse,linker);
if(cmd&VM_CODEINFO)
gen.print();

View File

@ -1,5 +1,5 @@
.PHONY=test
nasal:main.cpp nasal_ast.h nasal_err.h nasal_builtin.h nasal_codegen.h nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal_dbg.h nasal.h
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

View File

@ -132,6 +132,7 @@ std::string rawstr(const std::string& str)
#include "nasal_ast.h"
#include "nasal_parse.h"
#include "nasal_import.h"
#include "nasal_opt.h"
#include "nasal_gc.h"
#include "nasal_builtin.h"
#include "nasal_codegen.h"

43
nasal_opt.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef __NASAL_OPT_H__
#define __NASAL_OPT_H__
void calc_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())
{
case ast_add:res=vec[0].num()+vec[1].num();break;
case ast_sub:res=vec[0].num()-vec[1].num();break;
case ast_mult:res=vec[0].num()*vec[1].num();break;
case ast_div:res=vec[0].num()/vec[1].num();break;
case ast_less:res=vec[0].num()<vec[1].num();break;
case ast_leq:res=vec[0].num()<=vec[1].num();break;
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
return;
root.set_num(res);
root.child().clear();
root.set_type(ast_num);
}
void optimize(nasal_ast& root)
{
for(auto& i:root.child())
calc_const_num(i);
}
#endif

View File

@ -5,6 +5,7 @@ var filename=[
"nasal_ast.h",
"nasal_builtin.h",
"nasal_codegen.h",
"nasal_opt.h",
"nasal_gc.h",
"nasal_import.h",
"nasal_lexer.h",
@ -19,6 +20,7 @@ var space=[
" ",
"",
"",
" ",
" ",
" ",
" ",