From 630c99c39a9d3510db98e409307224831a0d3d74 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 16 Jan 2022 22:48:00 +0800 Subject: [PATCH] optimize codes --- nasal_ast.h | 118 ++++++++++++++++++++++------------------- nasal_builtin.h | 4 +- nasal_codegen.h | 72 +++---------------------- nasal_dbg.h | 2 +- nasal_err.h | 17 +++--- nasal_gc.h | 5 +- nasal_lexer.h | 12 ++--- nasal_parse.h | 8 +-- test/calc.nas | 52 +++++++++++------- test/turingmachine.nas | 6 +-- 10 files changed, 128 insertions(+), 168 deletions(-) diff --git a/nasal_ast.h b/nasal_ast.h index ed5530c..720d0a2 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -4,63 +4,63 @@ enum ast_node { ast_null=0, - ast_root, // mark the root node of ast - ast_block, // expression block - ast_file, // used to store which file the sub-tree is on - ast_nil, // nil keyword - ast_num, // number, basic value type - ast_str, // string, basic value type - ast_id, // identifier - ast_func, // func keyword - ast_hash, // hash, basic value type - ast_vec, // vector, basic value type - ast_hashmember,// elements in hashmap - ast_call, // mark a sub-tree of calling an identifier - ast_callh, // id.name - ast_callv, // id[index] - ast_callf, // id() - ast_subvec, // id[index:index] - ast_args, // mark a sub-tree of function parameters - ast_default, // default parameter - ast_dynamic, // dynamic parameter - ast_and, // and keyword - ast_or, // or keyword - ast_equal, // = - ast_addeq, // += - ast_subeq, // -= - ast_multeq, // *= - ast_diveq, // /= - ast_lnkeq, // ~= - ast_cmpeq, // == - ast_neq, // != - ast_less, // < - ast_leq, // <= - ast_grt, // > - ast_geq, // >= - ast_add, // + - ast_sub, // - - ast_mult, // * - ast_div, // / - ast_link, // ~ - ast_neg, // - - ast_not, // ~ - ast_trino, // ?: - ast_for, // for keyword - ast_forindex,// forindex keyword - ast_foreach, // foreach keyword - ast_while, // while - ast_new_iter,// iterator, used in forindex/foreach - ast_conditional,// mark a sub-tree of conditional expression - ast_if, // if keyword - ast_elsif, // elsif keyword - ast_else, // else keyword - ast_multi_id,// multi identifiers sub-tree + 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 + ast_nil, // nil keyword + ast_num, // number, basic value type + ast_str, // string, basic value type + ast_id, // identifier + ast_func, // func keyword + ast_hash, // hash, basic value type + ast_vec, // vector, basic value type + ast_hashmember, // elements in hashmap + ast_call, // mark a sub-tree of calling an identifier + ast_callh, // id.name + ast_callv, // id[index] + ast_callf, // id() + ast_subvec, // id[index:index] + ast_args, // mark a sub-tree of function parameters + ast_default, // default parameter + ast_dynamic, // dynamic parameter + ast_and, // and keyword + ast_or, // or keyword + ast_equal, // = + ast_addeq, // += + ast_subeq, // -= + ast_multeq, // *= + ast_diveq, // /= + ast_lnkeq, // ~= + ast_cmpeq, // == + ast_neq, // != + ast_less, // < + ast_leq, // <= + ast_grt, // > + ast_geq, // >= + ast_add, // + + ast_sub, // - + ast_mult, // * + ast_div, // / + ast_link, // ~ + ast_neg, // - + ast_not, // ~ + ast_trino, // ?: + ast_for, // for keyword + ast_forindex, // forindex keyword + ast_foreach, // foreach keyword + ast_while, // while + ast_new_iter, // iterator, used in forindex/foreach + ast_conditional, // mark a sub-tree of conditional expression + ast_if, // if keyword + ast_elsif, // elsif keyword + ast_else, // else keyword + ast_multi_id, // multi identifiers sub-tree ast_multi_scalar,// multi value sub-tree - ast_def, // definition + ast_def, // definition ast_multi_assign,// multi assignment sub-tree - ast_continue,// continue keyword - ast_break, // break keyword - ast_ret // return keyword + ast_continue, // continue keyword, only used in loop + ast_break, // break keyword, only used in loop + ast_ret // return keyword, only used in function block }; const char* ast_name[]= @@ -228,10 +228,18 @@ void nasal_ast::print(int depth,bool last=false) if(last && depth) intentation.back()=" "; else if(!last && depth) +#ifdef _WIN32 + intentation.back()="| "; +#else intentation.back()="│ "; +#endif for(uint32_t i=0;i<_child.size();++i) { +#ifdef _WIN32 + intentation.push_back(i==_child.size()-1?"`-":"|-"); +#else intentation.push_back(i==_child.size()-1?"└─":"├─"); +#endif _child[i].print(depth+1,i==_child.size()-1); intentation.pop_back(); } diff --git a/nasal_builtin.h b/nasal_builtin.h index ab2e711..bf7313e 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -87,7 +87,7 @@ nas_native(builtin_platform); nasal_ref builtin_err(const char* func_name,std::string info) { - std::cout<<"[vm] "<& local,nasal_gc& gc) nasal_ref str=local[1]; if(str.type!=vm_str) return builtin_err("die","\"str\" must be string"); - std::cout<<"[vm] error: "<<*str.str()<<'\n'; + std::cerr<<"[vm] error: "<<*str.str()<<'\n'; return nasal_ref(vm_none); } nasal_ref builtin_type(std::vector& local,nasal_gc& gc) diff --git a/nasal_codegen.h b/nasal_codegen.h index 6837044..af59796 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -205,7 +205,7 @@ private: std::vector global; // global : max 4095 values std::list> local; // local : max 32768 upvalues 65536 values - void die(const std::string&,const uint32_t); + void die(std::string,const uint32_t); void regist_number(const double); void regist_string(const std::string&); void find_symbol(const nasal_ast&); @@ -255,10 +255,10 @@ public: const std::vector& get_code() const {return code;} }; -void nasal_codegen::die(const std::string& info,const uint32_t line) +void nasal_codegen::die(std::string info,const uint32_t line) { nerr.load(file[fileindex]); - nerr.err("code",line,info.c_str()); + nerr.err("code",line,info); } void nasal_codegen::regist_number(const double num) @@ -455,8 +455,6 @@ void nasal_codegen::func_gen(const nasal_ast& ast) void nasal_codegen::call_gen(const nasal_ast& ast) { calc_gen(ast[0]); - if(code.empty()) - std::cout<<"warning\n"; if(code.back().op==op_callb) return; int child_size=ast.size(); @@ -1068,6 +1066,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast) switch(tmp.type()) { case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break; + case ast_file:fileindex=tmp.num();break; // special node type in main block case ast_def:def_gen(tmp);break; case ast_multi_assign:multi_assign_gen(tmp);break; case ast_conditional:conditional_gen(tmp);break; @@ -1151,68 +1150,9 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import) file=import.get_file().data(); in_iterloop.push(0); - // search symbols first - find_symbol(parse.ast()); + find_symbol(parse.ast()); // search symbols first gen(op_intg,global.size(),0); - for(auto& tmp:parse.ast().child()) - { - switch(tmp.type()) - { - case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break; - case ast_file:fileindex=tmp.num();break; - case ast_def:def_gen(tmp);break; - case ast_multi_assign:multi_assign_gen(tmp);break; - case ast_conditional:conditional_gen(tmp);break; - case ast_while: - case ast_for: - case ast_forindex: - case ast_foreach:loop_gen(tmp);break; - case ast_equal: - if(tmp[0].type()==ast_id) - { - calc_gen(tmp[1]); - mcall_id(tmp[0]); - // only the first mcall_id can use load - if(code.back().op==op_mcalll) - code.back().op=op_loadl; - else if(code.back().op==op_mupval) - code.back().op=op_loadu; - else - code.back().op=op_loadg; - } - else - { - calc_gen(tmp); - gen(op_pop,0,tmp.line()); - } - break; - case ast_id: - case ast_vec: - case ast_hash: - case ast_call: - case ast_addeq: - case ast_subeq: - case ast_multeq: - case ast_diveq: - case ast_lnkeq: - case ast_neg: - case ast_not: - case ast_add: - case ast_sub: - case ast_mult: - case ast_div: - case ast_link: - case ast_cmpeq: - case ast_neq: - case ast_leq: - case ast_less: - case ast_geq: - case ast_grt: - case ast_or: - case ast_and: - case ast_trino:calc_gen(tmp);gen(op_pop,0,tmp.line());break; - } - } + block_gen(parse.ast()); // generate main block gen(op_exit,0,0); if(global.size()>=STACK_MAX_DEPTH) die("too many global variants: "+std::to_string(global.size())+".",0); diff --git a/nasal_dbg.h b/nasal_dbg.h index 8134126..031121a 100644 --- a/nasal_dbg.h +++ b/nasal_dbg.h @@ -56,7 +56,7 @@ uint16_t nasal_dbg::get_fileindex(const std::string& filename) void nasal_dbg::err() { - std::cout + std::cerr <<"incorrect command\n" <<"input \'h\' to get help\n"; } diff --git a/nasal_err.h b/nasal_err.h index f7eaa37..3f7e2cc 100644 --- a/nasal_err.h +++ b/nasal_err.h @@ -13,7 +13,7 @@ protected: public: void load(const std::string& f) { - if(file==f) + if(file==f) // don't need to load a loaded file return; file=f; res.clear(); @@ -48,33 +48,32 @@ public: void err(const char* stage,const std::string& info) { ++error; - std::cout<<"["<c_str()); - return value.num; + return type!=vm_str?value.num:str2num(str()->c_str()); } std::string nasal_ref::to_string() { diff --git a/nasal_lexer.h b/nasal_lexer.h index 8bf8b55..b0c305f 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -113,7 +113,7 @@ private: std::vector tokens; uint32_t get_type(const std::string&); - void die(const char* info){nerr.err("lexer",line,column,info);}; + void die(std::string info){nerr.err("lexer",line,column,info);}; void open(const std::string&); std::string id_gen(); std::string num_gen(); @@ -165,7 +165,7 @@ std::string nasal_lexer::num_gen() str+=res[ptr++]; column+=str.length(); if(str.length()<3)// "0x" - die("invalid number."); + die("invalid number:"+str); return str; } // generate oct number @@ -177,7 +177,7 @@ std::string nasal_lexer::num_gen() str+=res[ptr++]; column+=str.length(); if(str.length()<3)// "0o" - die("invalid number."); + die("invalid number:"+str); return str; } // generate dec number @@ -194,7 +194,7 @@ std::string nasal_lexer::num_gen() if(str.back()=='.') { column+=str.length(); - die("invalid number."); + die("invalid number:"+str); return "0"; } } @@ -209,7 +209,7 @@ std::string nasal_lexer::num_gen() if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+') { column+=str.length(); - die("invalid number."); + die("invalid number:"+str); return "0"; } } @@ -309,7 +309,7 @@ void nasal_lexer::scan(const std::string& file) ++column; uint32_t type=get_type(str); if(!type) - die("invalid operator."); + die("invalid operator:"+str); tokens.push_back({line,column,type,str}); ++ptr; } diff --git a/nasal_parse.h b/nasal_parse.h index db5a1c8..32486b1 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -48,7 +48,7 @@ private: nasal_ast root; nasal_err& nerr; - void die(uint32_t,const std::string&); + void die(uint32_t,std::string); void match(uint32_t type,const char* info=nullptr); bool check_comma(const uint32_t*); bool check_multi_scalar(); @@ -121,7 +121,7 @@ void nasal_parse::compile(const nasal_lexer& lexer) } nerr.chkerr(); } -void nasal_parse::die(uint32_t line,const std::string& info) +void nasal_parse::die(uint32_t line,std::string info) { int col=(int)tokens[ptr].column-(int)tokens[ptr].str.length(); if(tokens[ptr].type==tok_str) @@ -434,9 +434,9 @@ nasal_ast nasal_parse::expr() { uint32_t tok_type=tokens[ptr].type; if((tok_type==tok_break || tok_type==tok_continue) && !in_loop) - die(error_line,"use break/continue in the loop"); + die(error_line,"should use break/continue in loops"); if(tok_type==tok_ret && !in_func) - die(error_line,"use return in the function"); + die(error_line,"should use return in functions"); switch(tok_type) { case tok_nil: diff --git a/test/calc.nas b/test/calc.nas index 89e506a..2125cb5 100644 --- a/test/calc.nas +++ b/test/calc.nas @@ -1,29 +1,45 @@ import("lib.nas"); -var filename=["main.cpp","nasal_err.h","nasal_ast.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"]; -var space=[" "," "," ","",""," "," "," "," "," "," "," "]; -var enter_cnt=func(s) -{ - var (cnt,len,enter)=(0,size(s),'\n'[0]); +var filename=[ + "main.cpp", + "nasal_err.h", + "nasal_ast.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" +]; +var space=[ + " ", + " ", + " ", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " " +]; +var count=func(s,c){ + var (cnt,len,ch)=(0,size(s),c[0]); for(var i=0;i');