diff --git a/main.cpp b/main.cpp index 3a8f2c6..0ce9866 100644 --- a/main.cpp +++ b/main.cpp @@ -16,8 +16,6 @@ void help() std::cout<<">> [lex ] use lexer to turn code into tokens.\n"; std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n"; std::cout<<">> [run ] run abstract syntax tree.\n"; - std::cout<<">> [exec ] generate byte code.\n"; - std::cout<<">> [erun ] run byte code.\n"; std::cout<<">> [logo ] print logo of nasal .\n"; std::cout<<">> [exit ] quit nasal interpreter.\n"; return; @@ -107,51 +105,6 @@ void runtime_start() return; } -void codegen_start() -{ - lexer.openfile(inputfile); - lexer.scanner(); - if(lexer.get_error()) - { - die("lexer",inputfile); - return; - } - parse.set_toklist(lexer.get_token_list()); - parse.main_process(); - if(parse.get_error()) - { - die("parse",inputfile); - return; - } - import.link(parse.get_root()); - if(import.get_error()) - { - die("import",inputfile); - return; - } - runtime.set_root(import.get_root()); - code_generator.output_exec(inputfile+".naexec",import.get_root()); - if(code_generator.get_error()) - { - die("code",inputfile); - return; - } - return; -} - -void execution_start() -{ - code_generator.load_exec(inputfile,import.get_root()); - if(code_generator.get_error()) - { - die("code",inputfile); - return; - } - runtime.set_root(import.get_root()); - runtime.run(); - return; -} - int main() { std::string command; @@ -201,10 +154,6 @@ int main() ast_print(); else if(command=="run") runtime_start(); - else if(command=="exec") - codegen_start(); - else if(command=="erun") - execution_start(); else if(command=="logo") logo(); else if(command=="exit") diff --git a/nasal_codegen.h b/nasal_codegen.h index afbf254..4ef4d1f 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -26,7 +26,8 @@ enum op_code struct opcode { unsigned char op; - int index; + unsigned int index; + opcode(){op=op_nop;index=0;} }; // unfinished @@ -35,223 +36,186 @@ struct opcode class nasal_codegen { private: - std::vector file_header; - std::vector output_file; - std::vector string_table; + std::map number_table; + std::map string_table; + std::vector exec_code; int error; - void init(); - void output_int(unsigned int,std::vector&); - void output_short(unsigned short,std::vector&); - void output_root(nasal_ast&); - unsigned int input_int(std::ifstream&); - unsigned short input_short(std::ifstream&); - void input_root(nasal_ast&,std::ifstream&); + void nil_gen(); + void number_gen(nasal_ast&); + void string_gen(nasal_ast&); + void vector_gen(nasal_ast&); + void hash_gen(nasal_ast&); + void function_gen(nasal_ast&); + void definition_gen(nasal_ast&); + void multi_assignment_gen(nasal_ast&); + void conditional_gen(nasal_ast&); + void loop_gen(nasal_ast&); + void calculation_gen(nasal_ast&); public: nasal_codegen(); - int get_error(); - void output_exec(std::string,nasal_ast&); - void load_exec(std::string,nasal_ast&); + void main_progress(nasal_ast&); }; nasal_codegen::nasal_codegen() { error=0; + number_table.clear(); string_table.clear(); return; } -int nasal_codegen::get_error() +void nasal_codegen::nil_gen() { - return error; -} - -void nasal_codegen::init() -{ - error=0; - string_table.clear(); - file_header.clear(); - output_file.clear(); + opcode op; + op.op=op_pushnil; + exec_code.push_back(op); return; } -void nasal_codegen::output_int(unsigned int num,std::vector& vec) +void nasal_codegen::number_gen(nasal_ast& ast) { - unsigned int tmp=0xff000000; - unsigned int offset=24; - for(int i=0;i<4;++i) + int size=number_table.size(); + double num=ast.get_num(); + opcode op; + if(number_table.find(num)==number_table.end()) + number_table[num]=size; + if(num==1) + op.op=op_pushone; + else if(num==0) + op.op=op_pushzero; + else { - vec.push_back((unsigned char)((tmp&num)>>offset)); - offset-=8; - tmp>>=8; + op.op=op_pushnum; + op.index=number_table[num]; } + exec_code.push_back(op); return; } -void nasal_codegen::output_short(unsigned short num,std::vector& vec) +void nasal_codegen::string_gen(nasal_ast& ast) { - vec.push_back((unsigned char)((num&0xff00)>>8)); - vec.push_back((unsigned char)(num&0x00ff)); + int size=string_table.size(); + std::string str=ast.get_str(); + opcode op; + if(string_table.find(str)==string_table.end()) + string_table[str]=size; + op.op=op_pushstr; + op.index=string_table[str]; + exec_code.push_back(op); return; } -void nasal_codegen::output_root(nasal_ast& root) +void nasal_codegen::vector_gen(nasal_ast& ast) { - unsigned char type=(unsigned char)root.get_type(); - output_file.push_back(type); - std::vector& ref_vec=root.get_children(); - unsigned short root_children_size=ref_vec.size(); - output_short(root_children_size,output_file); - 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); - output_short(string_table.size()-1,output_file); - } - else - { - for(int i=0;iinit(); - - // put header input file_header - unsigned char header[4]={0x40,0x56,0x4b,0x21}; - for(int i=0;i<4;++i) - file_header.push_back(header[i]); - - // main progress,put codes into output_file - output_root(root); - - // put string table into file_header - output_short(string_table.size(),file_header); - for(int i=0;i> [code] cannot generate file \""<> [code] cannot open file\""<> [code] \""<=1) - std::cout<<">> [runtime] process exited after "<> [runtime] process exited after "<