From 025ff49ffce3a031d94e847d47dac98275d34281 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 19 Oct 2022 00:54:21 +0800 Subject: [PATCH] :rocket: add `stl/csv.nas` & ast name change --- main.cpp | 22 +- nasal_ast.h | 42 ++-- nasal_codegen.h | 592 ++++++++++++++++++++++---------------------- nasal_gc.h | 15 +- nasal_import.h | 34 +-- nasal_lexer.h | 17 +- nasal_opt.h | 8 +- nasal_parse.h | 286 ++++++++++----------- stl/csv.nas | 16 ++ test/md5compare.nas | 8 +- 10 files changed, 531 insertions(+), 509 deletions(-) create mode 100644 stl/csv.nas diff --git a/main.cpp b/main.cpp index 2e7bf5c..a15eced 100644 --- a/main.cpp +++ b/main.cpp @@ -83,45 +83,45 @@ void execute(const string& file,const std::vector& argv,const u32 cmd) { // front end use the same error module nasal_err nerr; - nasal_lexer lexer(nerr); + nasal_lexer lex(nerr); nasal_parse parse(nerr); - nasal_import linker(nerr); + nasal_import ld(nerr); nasal_codegen gen(nerr); // back end nasal_vm vm; // lexer scans file to get tokens - lexer.scan(file); + lex.scan(file); if(cmd&VM_TOKEN) - lexer.print(); + lex.print(); // parser gets lexer's token list to compile - parse.compile(lexer); + parse.compile(lex); // linker gets parser's ast and load import files to this ast - linker.link(parse,file,cmd&VM_DETAIL); + ld.link(parse,file,cmd&VM_DETAIL); // optimizer does simple optimization on ast if(cmd&VM_OPT) - optimize(parse.ast()); + optimize(parse.tree()); if(cmd&VM_AST) parse.print(); // code generator gets parser's ast and linker's import file list to generate code - gen.compile(parse,linker); + gen.compile(parse,ld); if(cmd&VM_CODE) gen.print(); // run if(cmd&VM_DEBUG) - nasal_dbg(nerr).run(gen,linker,argv); + nasal_dbg(nerr).run(gen,ld,argv); else if(cmd&VM_TIME) { auto start=std::chrono::high_resolution_clock::now(); - vm.run(gen,linker,argv,cmd&VM_DETAIL); + vm.run(gen,ld,argv,cmd&VM_DETAIL); auto end=std::chrono::high_resolution_clock::now(); std::clog<<"process exited after "<<(end-start).count()*1.0/std::chrono::high_resolution_clock::duration::period::den<<"s.\n"; } else if(cmd&VM_EXEC) - vm.run(gen,linker,argv,cmd&VM_DETAIL); + vm.run(gen,ld,argv,cmd&VM_DETAIL); } i32 main(i32 argc,const char* argv[]) diff --git a/nasal_ast.h b/nasal_ast.h index 0ba7fc3..2283c36 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -128,7 +128,7 @@ const char* ast_name[]= "return" }; -class nasal_ast +class ast { private: u32 node_line; @@ -136,24 +136,24 @@ private: u32 node_type; f64 node_num; string node_str; - std::vector node_child; + std::vector node_child; public: - nasal_ast(const u32 l,const u32 c,const u32 t): + ast(const u32 l,const u32 c,const u32 t): node_line(l),node_col(c),node_type(t),node_num(0){} - nasal_ast(const nasal_ast&); - nasal_ast(nasal_ast&&); - void tree(); + ast(const ast&); + ast(ast&&); + void print_tree(); void print(u32,bool,std::vector&); void clear(); - nasal_ast& operator=(const nasal_ast&); - nasal_ast& operator=(nasal_ast&&); - nasal_ast& operator[](usize n){return node_child[n];} - const nasal_ast& operator[](usize n) const {return node_child[n];} + ast& operator=(const ast&); + ast& operator=(ast&&); + ast& operator[](usize n){return node_child[n];} + const ast& operator[](usize n) const {return node_child[n];} usize size() const {return node_child.size();} - void add(nasal_ast&& ast){node_child.push_back(std::move(ast));} - void add(const nasal_ast& ast){node_child.push_back(ast);} + void add(ast&& node){node_child.push_back(std::move(node));} + void add(const ast& node){node_child.push_back(node);} void set_line(const u32 l){node_line=l;} void set_type(const u32 t){node_type=t;} void set_str(const string& s){node_str=s;} @@ -164,11 +164,11 @@ public: inline u32 type() const {return node_type;} inline f64 num() const {return node_num;} inline const string& str() const {return node_str;} - inline const std::vector& child() const {return node_child;} - inline std::vector& child(){return node_child;} + inline const std::vector& child() const {return node_child;} + inline std::vector& child(){return node_child;} }; -nasal_ast::nasal_ast(const nasal_ast& tmp): +ast::ast(const ast& tmp): node_str(tmp.node_str),node_child(tmp.node_child) { node_line=tmp.node_line; @@ -177,7 +177,7 @@ nasal_ast::nasal_ast(const nasal_ast& tmp): node_num =tmp.node_num; } -nasal_ast::nasal_ast(nasal_ast&& tmp) +ast::ast(ast&& tmp) { node_line=tmp.node_line; node_col=tmp.node_col; @@ -187,7 +187,7 @@ nasal_ast::nasal_ast(nasal_ast&& tmp) node_child.swap(tmp.node_child); } -nasal_ast& nasal_ast::operator=(const nasal_ast& tmp) +ast& ast::operator=(const ast& tmp) { node_line=tmp.node_line; node_col=tmp.node_col; @@ -198,7 +198,7 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp) return *this; } -nasal_ast& nasal_ast::operator=(nasal_ast&& tmp) +ast& ast::operator=(ast&& tmp) { node_line=tmp.node_line; node_col=tmp.node_col; @@ -209,7 +209,7 @@ nasal_ast& nasal_ast::operator=(nasal_ast&& tmp) return *this; } -void nasal_ast::clear() +void ast::clear() { node_line=node_col=0; node_num=0; @@ -218,13 +218,13 @@ void nasal_ast::clear() node_child.clear(); } -void nasal_ast::tree() +void ast::print_tree() { std::vector tmp; print(0,false,tmp); } -void nasal_ast::print(u32 depth,bool last,std::vector& indent) +void ast::print(u32 depth,bool last,std::vector& indent) { for(auto& i:indent) std::cout<=0) { - gen(op_calll,index,ast.line()); + gen(op_calll,index,node.line()); return; } if((index=upvalue_find(str))>=0) { - gen(op_upval,index,ast.line()); + gen(op_upval,index,node.line()); return; } if((index=global_find(str))>=0) { - gen(op_callg,index,ast.line()); + gen(op_callg,index,node.line()); return; } - die("undefined symbol \""+str+"\"",ast.line(),ast.col()); + die("undefined symbol \""+str+"\"",node.line(),node.col()); } -void nasal_codegen::call_hash(const nasal_ast& ast) +void nasal_codegen::call_hash(const ast& node) { - regist_str(ast.str()); - gen(op_callh,str_table[ast.str()],ast.line()); + regist_str(node.str()); + gen(op_callh,str_table[node.str()],node.line()); } -void nasal_codegen::call_vec(const nasal_ast& ast) +void nasal_codegen::call_vec(const ast& node) { // maybe this place can use callv-const if ast's first child is ast_num - if(ast.size()==1 && ast[0].type()!=ast_subvec) + if(node.size()==1 && node[0].type()!=ast_subvec) { - calc_gen(ast[0]); - gen(op_callv,0,ast[0].line()); + calc_gen(node[0]); + gen(op_callv,0,node[0].line()); return; } - gen(op_slcbeg,0,ast.line()); - for(auto& tmp:ast.child()) + gen(op_slcbeg,0,node.line()); + for(auto& tmp:node.child()) { if(tmp.type()!=ast_subvec) { @@ -539,23 +539,23 @@ void nasal_codegen::call_vec(const nasal_ast& ast) gen(op_slc2,0,tmp.line()); } } - gen(op_slcend,0,ast.line()); + gen(op_slcend,0,node.line()); } -void nasal_codegen::call_func(const nasal_ast& ast) +void nasal_codegen::call_func(const ast& node) { - if(!ast.size()) - gen(op_callfv,0,ast.line()); - else if(ast[0].type()==ast_pair) + if(!node.size()) + gen(op_callfv,0,node.line()); + else if(node[0].type()==ast_pair) { - hash_gen(ast); - gen(op_callfh,0,ast.line()); + hash_gen(node); + gen(op_callfh,0,node.line()); } else { - for(auto& node:ast.child()) - calc_gen(node); - gen(op_callfv,ast.size(),ast.line()); + for(auto& child:node.child()) + calc_gen(child); + gen(op_callfv,node.size(),node.line()); } } @@ -567,22 +567,22 @@ void nasal_codegen::call_func(const nasal_ast& ast) * so we use another way to avoid gc-caused SIGSEGV: reserve m-called value on stack. * you could see the notes in `nasal_vm::opr_mcallv()`. */ -void nasal_codegen::mcall(const nasal_ast& ast) +void nasal_codegen::mcall(const ast& node) { - if(ast.type()==ast_id) + if(node.type()==ast_id) { - mcall_id(ast); + mcall_id(node); return; } - if(ast.size()==1) // foreach and forindex use call-id ast to get mcall + if(node.size()==1) // foreach and forindex use call-id ast to get mcall { - mcall_id(ast[0]); + mcall_id(node[0]); return; } - calc_gen(ast[0]); - for(usize i=1;i=0) { - gen(op_mcalll,index,ast.line()); + gen(op_mcalll,index,node.line()); return; } if((index=upvalue_find(str))>=0) { - gen(op_mupval,index,ast.line()); + gen(op_mupval,index,node.line()); return; } if((index=global_find(str))>=0) { - gen(op_mcallg,index,ast.line()); + gen(op_mcallg,index,node.line()); return; } - die("undefined symbol \""+str+"\"",ast.line(),ast.col()); + die("undefined symbol \""+str+"\"",node.line(),node.col()); } -void nasal_codegen::mcall_vec(const nasal_ast& ast) +void nasal_codegen::mcall_vec(const ast& node) { - calc_gen(ast[0]); - gen(op_mcallv,0,ast.line()); + calc_gen(node[0]); + gen(op_mcallv,0,node.line()); } -void nasal_codegen::mcall_hash(const nasal_ast& ast) +void nasal_codegen::mcall_hash(const ast& node) { - regist_str(ast.str()); - gen(op_mcallh,str_table[ast.str()],ast.line()); + regist_str(node.str()); + gen(op_mcallh,str_table[node.str()],node.line()); } -void nasal_codegen::single_def(const nasal_ast& ast) +void nasal_codegen::single_def(const ast& node) { - const string& str=ast[0].str(); - calc_gen(ast[1]); + const string& str=node[0].str(); + calc_gen(node[1]); local.empty()? - gen(op_loadg,global_find(str),ast.line()): - gen(op_loadl,local_find(str),ast.line()); + gen(op_loadg,global_find(str),node.line()): + gen(op_loadl,local_find(str),node.line()); } -void nasal_codegen::multi_def(const nasal_ast& ast) +void nasal_codegen::multi_def(const ast& node) { - auto& ids=ast[0].child(); + auto& ids=node[0].child(); usize size=ids.size(); - if(ast[1].type()==ast_multi_scalar) // (var a,b,c)=(c,b,a); + if(node[1].type()==ast_multi_scalar) // (var a,b,c)=(c,b,a); { - auto& vals=ast[1].child(); + auto& vals=node[1].child(); for(usize i=0;i=0;--i) - calc_gen(ast[1][i]); + calc_gen(node[1][i]); for(i32 i=0;i jmp_label; - for(auto& tmp:ast.child()) + for(auto& tmp:node.child()) { if(tmp.type()==ast_if || tmp.type()==ast_elsif) { @@ -737,7 +737,7 @@ void nasal_codegen::conditional_gen(const nasal_ast& ast) gen(op_jf,0,tmp.line()); block_gen(tmp[1]); // without 'else' the last condition doesn't need to jmp - if(&tmp!=&ast.child().back()) + if(&tmp!=&node.child().back()) { jmp_label.push_back(code.size()); gen(op_jmp,0,tmp.line()); @@ -754,16 +754,16 @@ void nasal_codegen::conditional_gen(const nasal_ast& ast) code[i].num=code.size(); } -void nasal_codegen::loop_gen(const nasal_ast& ast) +void nasal_codegen::loop_gen(const ast& node) { continue_ptr.push_front(std::vector()); break_ptr.push_front(std::vector()); - switch(ast.type()) + switch(node.type()) { - case ast_while: while_gen(ast); break; - case ast_for: for_gen(ast); break; - case ast_forindex:forindex_gen(ast);break; - case ast_foreach: foreach_gen(ast); break; + case ast_while: while_gen(node); break; + case ast_for: for_gen(node); break; + case ast_forindex:forindex_gen(node);break; + case ast_foreach: foreach_gen(node); break; } } @@ -777,35 +777,35 @@ void nasal_codegen::load_continue_break(i32 continue_place,i32 break_place) break_ptr.pop_front(); } -void nasal_codegen::while_gen(const nasal_ast& ast) +void nasal_codegen::while_gen(const ast& node) { usize loop_ptr=code.size(); - calc_gen(ast[0]); + calc_gen(node[0]); usize condition_ptr=code.size(); - gen(op_jf,0,ast[0].line()); + gen(op_jf,0,node[0].line()); - block_gen(ast[1]); - gen(op_jmp,loop_ptr,ast[1].line()); + block_gen(node[1]); + gen(op_jmp,loop_ptr,node[1].line()); code[condition_ptr].num=code.size(); load_continue_break(code.size()-1,code.size()); } -void nasal_codegen::for_gen(const nasal_ast& ast) +void nasal_codegen::for_gen(const ast& node) { - switch(ast[0].type()) + switch(node[0].type()) { case ast_null:break; - case ast_def:def_gen(ast[0]);break; - case ast_multi_assign:multi_assign_gen(ast[0]);break; + case ast_def:def_gen(node[0]);break; + case ast_multi_assign:multi_assign_gen(node[0]);break; case ast_addeq:case ast_subeq: case ast_multeq:case ast_diveq:case ast_lnkeq: - calc_gen(ast[0]); + calc_gen(node[0]); if(op_addeq<=code.back().op && code.back().op<=op_lnkeq) code.back().num=1; else if(op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) code.back().num|=0x80000000; else - gen(op_pop,0,ast[0].line()); + gen(op_pop,0,node[0].line()); break; case ast_nil:case ast_num:case ast_str:break; case ast_vec:case ast_hash:case ast_func: @@ -818,17 +818,17 @@ void nasal_codegen::for_gen(const nasal_ast& ast) case ast_leq:case ast_less: case ast_geq:case ast_grt: case ast_trino: - calc_gen(ast[0]); + calc_gen(node[0]); if(code.back().op==op_meq) code.back().num=1; else - gen(op_pop,0,ast[0].line()); + gen(op_pop,0,node[0].line()); break; case ast_equal: - if(ast[0][0].type()==ast_id) + if(node[0][0].type()==ast_id) { - calc_gen(ast[0][1]); - mcall_id(ast[0][0]); + calc_gen(node[0][1]); + mcall_id(node[0][0]); // only the first mcall_id can use load if(code.back().op==op_mcalll) code.back().op=op_loadl; @@ -839,38 +839,38 @@ void nasal_codegen::for_gen(const nasal_ast& ast) } else { - calc_gen(ast[0]); + calc_gen(node[0]); if(code.back().op==op_meq) code.back().num=1; else - gen(op_pop,0,ast[0].line()); + gen(op_pop,0,node[0].line()); } break; } usize jmp_place=code.size(); - if(ast[1].type()==ast_null) - gen(op_pnum,num_table[1],ast[1].line()); + if(node[1].type()==ast_null) + gen(op_pnum,num_table[1],node[1].line()); else - calc_gen(ast[1]); + calc_gen(node[1]); usize label_exit=code.size(); - gen(op_jf,0,ast[1].line()); + gen(op_jf,0,node[1].line()); - block_gen(ast[3]); + block_gen(node[3]); usize continue_place=code.size(); - switch(ast[2].type()) + switch(node[2].type()) { case ast_null:break; - case ast_def:def_gen(ast[2]);break; - case ast_multi_assign:multi_assign_gen(ast[2]);break; + case ast_def:def_gen(node[2]);break; + case ast_multi_assign:multi_assign_gen(node[2]);break; case ast_addeq:case ast_subeq: case ast_multeq:case ast_diveq:case ast_lnkeq: - calc_gen(ast[2]); + calc_gen(node[2]); if(op_addeq<=code.back().op && code.back().op<=op_lnkeq) code.back().num=1; else if(op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) code.back().num|=0x80000000; else - gen(op_pop,0,ast[2].line()); + gen(op_pop,0,node[2].line()); break; case ast_nil:case ast_num:case ast_str:break; case ast_vec:case ast_hash:case ast_func: @@ -881,17 +881,17 @@ void nasal_codegen::for_gen(const nasal_ast& ast) case ast_cmpeq:case ast_neq:case ast_leq: case ast_less:case ast_geq:case ast_grt: case ast_trino: - calc_gen(ast[2]); + calc_gen(node[2]); if(code.back().op==op_meq) code.back().num=1; else - gen(op_pop,0,ast[2].line()); + gen(op_pop,0,node[2].line()); break; case ast_equal: - if(ast[2][0].type()==ast_id) + if(node[2][0].type()==ast_id) { - calc_gen(ast[2][1]); - mcall_id(ast[2][0]); + calc_gen(node[2][1]); + mcall_id(node[2][0]); // only the first mcall_id can use load if(code.back().op==op_mcalll) code.back().op=op_loadl; @@ -902,35 +902,35 @@ void nasal_codegen::for_gen(const nasal_ast& ast) } else { - calc_gen(ast[2]); + calc_gen(node[2]); if(code.back().op==op_meq) code.back().num=1; else - gen(op_pop,0,ast[2].line()); + gen(op_pop,0,node[2].line()); } break; } - gen(op_jmp,jmp_place,ast[2].line()); + gen(op_jmp,jmp_place,node[2].line()); code[label_exit].num=code.size(); load_continue_break(continue_place,code.size()); } -void nasal_codegen::forindex_gen(const nasal_ast& ast) +void nasal_codegen::forindex_gen(const ast& node) { - calc_gen(ast[1]); - gen(op_cnt,0,ast[1].line()); + calc_gen(node[1]); + gen(op_cnt,0,node[1].line()); usize ptr=code.size(); - gen(op_findex,0,ast.line()); - if(ast[0].type()==ast_iter) // define a new iterator + gen(op_findex,0,node.line()); + if(node[0].type()==ast_iter) // define a new iterator { - const string& str=ast[0][0].str(); + const string& str=node[0][0].str(); local.empty()? - gen(op_loadg,global_find(str),ast[0][0].line()): - gen(op_loadl,local_find(str),ast[0][0].line()); + gen(op_loadg,global_find(str),node[0][0].line()): + gen(op_loadl,local_find(str),node[0][0].line()); } else // use exist variable as the iterator { - mcall(ast[0]); + mcall(node[0]); if(code.back().op==op_mcallg) code.back().op=op_loadg; else if(code.back().op==op_mcalll) @@ -938,33 +938,33 @@ void nasal_codegen::forindex_gen(const nasal_ast& ast) else if(code.back().op==op_mupval) code.back().op=op_loadu; else - gen(op_meq,1,ast[0].line()); + gen(op_meq,1,node[0].line()); } ++in_iterloop.top(); - block_gen(ast[2]); + block_gen(node[2]); --in_iterloop.top(); - gen(op_jmp,ptr,ast.line()); + gen(op_jmp,ptr,node.line()); code[ptr].num=code.size(); load_continue_break(code.size()-1,code.size()); - gen(op_pop,0,ast[1].line());// pop vector - gen(op_pop,0,ast.line());// pop iterator + gen(op_pop,0,node[1].line());// pop vector + gen(op_pop,0,node.line());// pop iterator } -void nasal_codegen::foreach_gen(const nasal_ast& ast) +void nasal_codegen::foreach_gen(const ast& node) { - calc_gen(ast[1]); - gen(op_cnt,0,ast.line()); + calc_gen(node[1]); + gen(op_cnt,0,node.line()); usize ptr=code.size(); - gen(op_feach,0,ast.line()); - if(ast[0].type()==ast_iter) // define a new iterator + gen(op_feach,0,node.line()); + if(node[0].type()==ast_iter) // define a new iterator { - const string& str=ast[0][0].str(); + const string& str=node[0][0].str(); local.empty()? - gen(op_loadg,global_find(str),ast[0][0].line()): - gen(op_loadl,local_find(str),ast[0][0].line()); + gen(op_loadg,global_find(str),node[0][0].line()): + gen(op_loadl,local_find(str),node[0][0].line()); } else // use exist variable as the iterator { - mcall(ast[0]); + mcall(node[0]); if(code.back().op==op_mcallg) code.back().op=op_loadg; else if(code.back().op==op_mcalll) @@ -972,174 +972,174 @@ void nasal_codegen::foreach_gen(const nasal_ast& ast) else if(code.back().op==op_mupval) code.back().op=op_loadu; else - gen(op_meq,1,ast[0].line()); + gen(op_meq,1,node[0].line()); } ++in_iterloop.top(); - block_gen(ast[2]); + block_gen(node[2]); --in_iterloop.top(); - gen(op_jmp,ptr,ast.line()); + gen(op_jmp,ptr,node.line()); code[ptr].num=code.size(); load_continue_break(code.size()-1,code.size()); - gen(op_pop,0,ast[1].line());// pop vector - gen(op_pop,0,ast.line());// pop iterator + gen(op_pop,0,node[1].line());// pop vector + gen(op_pop,0,node.line());// pop iterator } -void nasal_codegen::or_gen(const nasal_ast& ast) +void nasal_codegen::or_gen(const ast& node) { - calc_gen(ast[0]); + calc_gen(node[0]); usize l1=code.size(); - gen(op_jt,0,ast[0].line()); + gen(op_jt,0,node[0].line()); - gen(op_pop,0,ast[0].line()); - calc_gen(ast[1]); + gen(op_pop,0,node[0].line()); + calc_gen(node[1]); usize l2=code.size(); - gen(op_jt,0,ast[1].line()); + gen(op_jt,0,node[1].line()); - gen(op_pop,0,ast[1].line()); - gen(op_pnil,0,ast[1].line()); + gen(op_pop,0,node[1].line()); + gen(op_pnil,0,node[1].line()); code[l1].num=code[l2].num=code.size(); } -void nasal_codegen::and_gen(const nasal_ast& ast) +void nasal_codegen::and_gen(const ast& node) { - calc_gen(ast[0]); - gen(op_jt,code.size()+2,ast[0].line()); + calc_gen(node[0]); + gen(op_jt,code.size()+2,node[0].line()); usize lfalse=code.size(); - gen(op_jmp,0,ast[0].line()); - gen(op_pop,0,ast[1].line());// jt jumps here + gen(op_jmp,0,node[0].line()); + gen(op_pop,0,node[1].line());// jt jumps here - calc_gen(ast[1]); - gen(op_jt,code.size()+3,ast[1].line()); + calc_gen(node[1]); + gen(op_jt,code.size()+3,node[1].line()); code[lfalse].num=code.size(); - gen(op_pop,0,ast[1].line()); - gen(op_pnil,0,ast[1].line()); + gen(op_pop,0,node[1].line()); + gen(op_pnil,0,node[1].line()); //jt jumps here } -void nasal_codegen::trino_gen(const nasal_ast& ast) +void nasal_codegen::trino_gen(const ast& node) { - calc_gen(ast[0]); + calc_gen(node[0]); usize lfalse=code.size(); - gen(op_jf,0,ast[0].line()); - calc_gen(ast[1]); + gen(op_jf,0,node[0].line()); + calc_gen(node[1]); usize lexit=code.size(); - gen(op_jmp,0,ast[1].line()); + gen(op_jmp,0,node[1].line()); code[lfalse].num=code.size(); - calc_gen(ast[2]); + calc_gen(node[2]); code[lexit].num=code.size(); } -void nasal_codegen::calc_gen(const nasal_ast& ast) +void nasal_codegen::calc_gen(const ast& node) { - switch(ast.type()) + switch(node.type()) { - case ast_nil: gen(op_pnil,0,ast.line());break; - case ast_num: num_gen(ast); break; - case ast_str: str_gen(ast); break; - case ast_id: call_id(ast); break; - case ast_vec: vec_gen(ast); break; - case ast_hash: hash_gen(ast); break; - case ast_func: func_gen(ast); break; - case ast_call: call_gen(ast); break; + case ast_nil: gen(op_pnil,0,node.line());break; + case ast_num: num_gen(node); break; + case ast_str: str_gen(node); break; + case ast_id: call_id(node); break; + case ast_vec: vec_gen(node); break; + case ast_hash: hash_gen(node); break; + case ast_func: func_gen(node); break; + case ast_call: call_gen(node); break; case ast_equal: - calc_gen(ast[1]); - mcall(ast[0]); - gen(op_meq,0,ast.line()); + calc_gen(node[1]); + mcall(node[0]); + gen(op_meq,0,node.line()); break; // ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27) case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq: - if(ast[1].type()!=ast_num) - calc_gen(ast[1]); - mcall(ast[0]); - if(ast[1].type()!=ast_num) - gen(ast.type()-ast_addeq+op_addeq,0,ast.line()); + if(node[1].type()!=ast_num) + calc_gen(node[1]); + mcall(node[0]); + if(node[1].type()!=ast_num) + gen(node.type()-ast_addeq+op_addeq,0,node.line()); else { - regist_num(ast[1].num()); - gen(ast.type()-ast_addeq+op_addeqc,num_table[ast[1].num()],ast.line()); + regist_num(node[1].num()); + gen(node.type()-ast_addeq+op_addeqc,num_table[node[1].num()],node.line()); } break; case ast_lnkeq: - if(ast[1].type()!=ast_str) - calc_gen(ast[1]); + if(node[1].type()!=ast_str) + calc_gen(node[1]); else - regist_str(ast[1].str()); - mcall(ast[0]); - if(ast[1].type()!=ast_str) - gen(op_lnkeq,0,ast.line()); + regist_str(node[1].str()); + mcall(node[0]); + if(node[1].type()!=ast_str) + gen(op_lnkeq,0,node.line()); else - gen(op_lnkeqc,str_table[ast[1].str()],ast.line()); + gen(op_lnkeqc,str_table[node[1].str()],node.line()); break; - case ast_or:or_gen(ast);break; - case ast_and:and_gen(ast);break; + case ast_or:or_gen(node);break; + case ast_and:and_gen(node);break; // ast_add(33)~ast_link(37) op_add(18)~op_lnk(22) case ast_add:case ast_sub:case ast_mult:case ast_div: - calc_gen(ast[0]); - if(ast[1].type()!=ast_num) + calc_gen(node[0]); + if(node[1].type()!=ast_num) { - calc_gen(ast[1]); - gen(ast.type()-ast_add+op_add,0,ast.line()); + calc_gen(node[1]); + gen(node.type()-ast_add+op_add,0,node.line()); } else { - regist_num(ast[1].num()); - gen(ast.type()-ast_add+op_addc,num_table[ast[1].num()],ast.line()); + regist_num(node[1].num()); + gen(node.type()-ast_add+op_addc,num_table[node[1].num()],node.line()); } break; case ast_link: - calc_gen(ast[0]); - if(ast[1].type()!=ast_str) + calc_gen(node[0]); + if(node[1].type()!=ast_str) { - calc_gen(ast[1]); - gen(op_lnk,0,ast.line()); + calc_gen(node[1]); + gen(op_lnk,0,node.line()); } else { - regist_str(ast[1].str()); - gen(op_lnkc,str_table[ast[1].str()],ast.line()); + regist_str(node[1].str()); + gen(op_lnkc,str_table[node[1].str()],node.line()); } break; // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) case ast_cmpeq:case ast_neq: - calc_gen(ast[0]); - calc_gen(ast[1]); - gen(ast.type()-ast_cmpeq+op_eq,0,ast.line()); + calc_gen(node[0]); + calc_gen(node[1]); + gen(node.type()-ast_cmpeq+op_eq,0,node.line()); break; case ast_less:case ast_leq:case ast_grt:case ast_geq: - calc_gen(ast[0]); - if(ast[1].type()!=ast_num) + calc_gen(node[0]); + if(node[1].type()!=ast_num) { - calc_gen(ast[1]); - gen(ast.type()-ast_less+op_less,0,ast.line()); + calc_gen(node[1]); + gen(node.type()-ast_less+op_less,0,node.line()); } else { - regist_num(ast[1].num()); - gen(ast.type()-ast_less+op_lessc,num_table[ast[1].num()],ast.line()); + regist_num(node[1].num()); + gen(node.type()-ast_less+op_lessc,num_table[node[1].num()],node.line()); } break; - case ast_trino:trino_gen(ast);break; + case ast_trino:trino_gen(node);break; case ast_neg: - calc_gen(ast[0]); - gen(op_usub,0,ast.line()); + calc_gen(node[0]); + gen(op_usub,0,node.line()); break; case ast_not: - calc_gen(ast[0]); - gen(op_unot,0,ast.line()); + calc_gen(node[0]); + gen(op_unot,0,node.line()); break; case ast_def: - single_def(ast); - call_id(ast[0]); + single_def(node); + call_id(node[0]); break; } } -void nasal_codegen::block_gen(const nasal_ast& ast) +void nasal_codegen::block_gen(const ast& node) { - for(auto& tmp:ast.child()) + for(auto& tmp:node.child()) switch(tmp.type()) { case ast_null:case ast_nil:case ast_num:case ast_str:break; @@ -1222,18 +1222,18 @@ void nasal_codegen::block_gen(const nasal_ast& ast) } } -void nasal_codegen::ret_gen(const nasal_ast& ast) +void nasal_codegen::ret_gen(const ast& node) { for(u32 i=0;i=STACK_DEPTH) die("too many global variants: "+std::to_string(global.size()),0,0); diff --git a/nasal_gc.h b/nasal_gc.h index 663e1f8..9ff6a94 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -21,10 +21,9 @@ enum vm_type:u8{ vm_func, vm_upval, vm_obj, - vm_co, - vm_tsize + vm_co }; -const u32 gc_tsize=vm_tsize-vm_str; +const u32 gc_tsize=vm_co-vm_str+1; // change parameters here to make your own efficient gc // better set bigger number on vm_vec const u32 ini[gc_tsize]= @@ -39,11 +38,11 @@ const u32 ini[gc_tsize]= }; const u32 incr[gc_tsize]= { - 256, // vm_str - 256, // vm_vec - 256, // vm_hash - 128, // vm_func - 128, // vm_upval + 1024,// vm_str + 512, // vm_vec + 512, // vm_hash + 512, // vm_func + 512, // vm_upval 128, // vm_obj 32 // vm_co }; diff --git a/nasal_import.h b/nasal_import.h index bebcd9a..67e0722 100644 --- a/nasal_import.h +++ b/nasal_import.h @@ -21,14 +21,14 @@ private: nasal_err& nerr; std::vector files; std::vector envpath; - bool imptchk(const nasal_ast&); + bool imptchk(const ast&); bool exist(const string&); - void linker(nasal_ast&,nasal_ast&&); - string path(const nasal_ast&); + void linker(ast&,ast&&); + string path(const ast&); string findf(const string&); - nasal_ast fimpt(nasal_ast&); - nasal_ast libimpt(); - nasal_ast load(nasal_ast&,u16); + ast fimpt(ast&); + ast libimpt(); + ast load(ast&,u16); public: nasal_import(nasal_err&); void link(nasal_parse&,const string&,bool); @@ -55,7 +55,7 @@ nasal_import::nasal_import(nasal_err& e):lib_loaded(false),nerr(e){ envpath.push_back(PATH.substr(last)); } -string nasal_import::path(const nasal_ast& node) +string nasal_import::path(const ast& node) { if(node[1].type()==ast_callf) return node[1][0].str(); @@ -101,7 +101,7 @@ string nasal_import::findf(const string& fname) return ""; } -bool nasal_import::imptchk(const nasal_ast& node) +bool nasal_import::imptchk(const ast& node) { // only these two kinds of node can be recognized as 'import': /* @@ -143,14 +143,14 @@ bool nasal_import::exist(const string& file) return false; } -void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root) +void nasal_import::linker(ast& root,ast&& add_root) { // add children of add_root to the back of root for(auto& i:add_root.child()) root.add(std::move(i)); } -nasal_ast nasal_import::fimpt(nasal_ast& node) +ast nasal_import::fimpt(ast& node) { nasal_lexer lex(nerr); nasal_parse par(nerr); @@ -166,12 +166,12 @@ nasal_ast nasal_import::fimpt(nasal_ast& node) // start importing... lex.scan(filename); par.compile(lex); - nasal_ast tmp=std::move(par.ast()); + ast tmp=std::move(par.tree()); // check if tmp has 'import' return load(tmp,files.size()-1); } -nasal_ast nasal_import::libimpt() +ast nasal_import::libimpt() { nasal_lexer lex(nerr); nasal_parse par(nerr); @@ -186,14 +186,14 @@ nasal_ast nasal_import::libimpt() // start importing... lex.scan(filename); par.compile(lex); - nasal_ast tmp=std::move(par.ast()); + ast tmp=std::move(par.tree()); // check if tmp has 'import' return load(tmp,files.size()-1); } -nasal_ast nasal_import::load(nasal_ast& root,u16 fileindex) +ast nasal_import::load(ast& root,u16 fileindex) { - nasal_ast new_root(0,0,ast_root); + ast new_root(0,0,ast_root); if(!lib_loaded) { linker(new_root,libimpt()); @@ -207,7 +207,7 @@ nasal_ast nasal_import::load(nasal_ast& root,u16 fileindex) break; } // add root to the back of new_root - nasal_ast file_head(0,0,ast_file); + ast file_head(0,0,ast_file); file_head.set_num(fileindex); new_root.add(std::move(file_head)); linker(new_root,std::move(root)); @@ -221,7 +221,7 @@ void nasal_import::link(nasal_parse& parse,const string& self,bool spath=false) files={self}; // scan root and import files,then generate a new ast and return to import_ast // the main file's index is 0 - parse.ast()=load(parse.ast(),0); + parse.tree()=load(parse.tree(),0); nerr.chkerr(); } diff --git a/nasal_lexer.h b/nasal_lexer.h index 36ca896..970cae0 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -22,15 +22,22 @@ enum tok:u32{ tok_null=0, // null token (default token type) - tok_num, // number basic token type - tok_str, // string basic token type - tok_id, // identifier basic token type + tok_num, // number literal + tok_str, // string literal + tok_id, // identifier tok_for, // loop keyword for tok_forindex,// loop keyword forindex tok_foreach, // loop keyword foreach tok_while, // loop keyword while - tok_var,tok_func,tok_break,tok_continue, - tok_ret,tok_if,tok_elsif,tok_else,tok_nil, + tok_var, // keyword for definition + tok_func, // keyword for definition of function + tok_break, // loop keyword break + tok_continue,// loop keyword continue + tok_ret, // function keyword return + tok_if, // condition expression keyword if + tok_elsif, // condition expression keyword elsif + tok_else, // condition expression keyword else + tok_nil, // nil literal tok_lcurve,tok_rcurve, tok_lbracket,tok_rbracket, tok_lbrace,tok_rbrace, diff --git a/nasal_opt.h b/nasal_opt.h index ee3ed97..0a1887b 100644 --- a/nasal_opt.h +++ b/nasal_opt.h @@ -3,7 +3,7 @@ #include -void const_str(nasal_ast& root) +void const_str(ast& root) { auto& vec=root.child(); root.set_str(vec[0].str()+vec[1].str()); @@ -11,7 +11,7 @@ void const_str(nasal_ast& root) root.set_type(ast_str); } -void const_num(nasal_ast& root) +void const_num(ast& root) { auto& vec=root.child(); f64 res; @@ -34,7 +34,7 @@ void const_num(nasal_ast& root) root.set_type(ast_num); } -void calc_const(nasal_ast& root) +void calc_const(ast& root) { auto& vec=root.child(); for(auto& i:vec) @@ -62,7 +62,7 @@ void calc_const(nasal_ast& root) vec[0].type()==ast_num && vec[1].type()==ast_num) const_num(root); } -void optimize(nasal_ast& root) +void optimize(ast& root) { for(auto& i:root.child()) calc_const(i); diff --git a/nasal_parse.h b/nasal_parse.h index a2750fe..7765c16 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -47,66 +47,66 @@ private: u32 in_func; // count function block u32 in_loop; // count loop block const token* tokens;// ref from nasal_lexer - nasal_ast root; + ast root; nasal_err& nerr; void die(u32,string,bool); void match(u32 type,const char* info=nullptr); bool check_comma(const u32*); bool check_multi_scalar(); - bool check_func_end(const nasal_ast&); + bool check_func_end(const ast&); bool check_special_call(); - bool need_semi_check(const nasal_ast&); - void check_memory_reachable(const nasal_ast&); - nasal_ast null(); - nasal_ast nil(); - nasal_ast num(); - nasal_ast str(); - nasal_ast id(); - nasal_ast vec(); - nasal_ast hash(); - nasal_ast pair(); - nasal_ast func(); - nasal_ast args(); - nasal_ast lcurve_expr(); - nasal_ast expr(); - nasal_ast exprs(); - nasal_ast calc(); - nasal_ast or_expr(); - nasal_ast and_expr(); - nasal_ast cmp_expr(); - nasal_ast additive_expr(); - nasal_ast multive_expr(); - nasal_ast unary(); - nasal_ast scalar(); - nasal_ast call_scalar(); - nasal_ast callh(); - nasal_ast callv(); - nasal_ast callf(); - nasal_ast subvec(); - nasal_ast definition(); - nasal_ast incurve_def(); - nasal_ast outcurve_def(); - nasal_ast multi_id(); - nasal_ast multi_scalar(bool); - nasal_ast multi_assgin(); - nasal_ast loop(); - nasal_ast while_loop(); - nasal_ast for_loop(); - nasal_ast forei_loop(); - nasal_ast iter_gen(); - nasal_ast conditional(); - nasal_ast continue_expr(); - nasal_ast break_expr(); - nasal_ast ret_expr(); + bool need_semi_check(const ast&); + void check_memory_reachable(const ast&); + ast null(); + ast nil(); + ast num(); + ast str(); + ast id(); + ast vec(); + ast hash(); + ast pair(); + ast func(); + ast args(); + ast lcurve_expr(); + ast expr(); + ast exprs(); + ast calc(); + ast or_expr(); + ast and_expr(); + ast cmp_expr(); + ast additive_expr(); + ast multive_expr(); + ast unary(); + ast scalar(); + ast call_scalar(); + ast callh(); + ast callv(); + ast callf(); + ast subvec(); + ast definition(); + ast incurve_def(); + ast outcurve_def(); + ast multi_id(); + ast multi_scalar(bool); + ast multi_assgin(); + ast loop(); + ast while_loop(); + ast for_loop(); + ast forei_loop(); + ast iter_gen(); + ast conditional(); + ast continue_expr(); + ast break_expr(); + ast ret_expr(); public: nasal_parse(nasal_err& e): ptr(0),in_func(0),in_loop(0), tokens(nullptr),root(0,0,ast_root),nerr(e){} - void print(){root.tree();} + void print(){root.print_tree();} void compile(const nasal_lexer&); - nasal_ast& ast(){return root;} - const nasal_ast& ast() const {return root;} + ast& tree(){return root;} + const ast& tree() const {return root;} }; void nasal_parse::compile(const nasal_lexer& lexer) { @@ -188,7 +188,7 @@ bool nasal_parse::check_multi_scalar() } return false; } -bool nasal_parse::check_func_end(const nasal_ast& node) +bool nasal_parse::check_func_end(const ast& node) { u32 type=node.type(); if(type==ast_func) @@ -235,18 +235,18 @@ bool nasal_parse::check_special_call() } return false; } -bool nasal_parse::need_semi_check(const nasal_ast& node) +bool nasal_parse::need_semi_check(const ast& node) { u32 type=node.type(); if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional) return false; return !check_func_end(node); } -void nasal_parse::check_memory_reachable(const nasal_ast& node) +void nasal_parse::check_memory_reachable(const ast& node) { if(node.type()==ast_call) { - const nasal_ast& tmp=node.child().back(); + const ast& tmp=node.child().back(); if(tmp.type()==ast_callf) die(tmp.line(),"bad left-value"); if(tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)) @@ -255,36 +255,36 @@ void nasal_parse::check_memory_reachable(const nasal_ast& node) else if(node.type()!=ast_id) die(node.line(),"bad left-value"); } -nasal_ast nasal_parse::null() +ast nasal_parse::null() { return {tokens[ptr].line,tokens[ptr].col,ast_null}; } -nasal_ast nasal_parse::nil() +ast nasal_parse::nil() { return {tokens[ptr].line,tokens[ptr].col,ast_nil}; } -nasal_ast nasal_parse::num() +ast nasal_parse::num() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_num); + ast node(tokens[ptr].line,tokens[ptr].col,ast_num); node.set_num(str2num(tokens[ptr].str.c_str())); match(tok_num); return node; } -nasal_ast nasal_parse::str() +ast nasal_parse::str() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_str); + ast node(tokens[ptr].line,tokens[ptr].col,ast_str); node.set_str(tokens[ptr].str); match(tok_str); return node; } -nasal_ast nasal_parse::id() +ast nasal_parse::id() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_id); + ast node(tokens[ptr].line,tokens[ptr].col,ast_id); node.set_str(tokens[ptr].str); match(tok_id); return node; } -nasal_ast nasal_parse::vec() +ast nasal_parse::vec() { // panic set for this token is not ',' // this is the FIRST set of calculation @@ -295,7 +295,7 @@ nasal_ast nasal_parse::vec() tok_func,tok_var,tok_lcurve, tok_lbrace,tok_lbracket,tok_null }; - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_vec); + ast node(tokens[ptr].line,tokens[ptr].col,ast_vec); match(tok_lbracket); while(tokens[ptr].type!=tok_rbracket) { @@ -310,9 +310,9 @@ nasal_ast nasal_parse::vec() match(tok_rbracket,"expected ']' when generating vector"); return node; } -nasal_ast nasal_parse::hash() +ast nasal_parse::hash() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_hash); + ast node(tokens[ptr].line,tokens[ptr].col,ast_hash); match(tok_lbrace); while(tokens[ptr].type!=tok_rbrace) { @@ -327,9 +327,9 @@ nasal_ast nasal_parse::hash() match(tok_rbrace,"expected '}' when generating hash"); return node; } -nasal_ast nasal_parse::pair() +ast nasal_parse::pair() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_pair); + ast node(tokens[ptr].line,tokens[ptr].col,ast_pair); if(tokens[ptr].type==tok_id) node.add(id()); else if(tokens[ptr].type==tok_str) @@ -340,10 +340,10 @@ nasal_ast nasal_parse::pair() node.add(calc()); return node; } -nasal_ast nasal_parse::func() +ast nasal_parse::func() { ++in_func; - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_func); + ast node(tokens[ptr].line,tokens[ptr].col,ast_func); match(tok_func); if(tokens[ptr].type==tok_lcurve) node.add(args()); @@ -353,16 +353,16 @@ nasal_ast nasal_parse::func() --in_func; return node; } -nasal_ast nasal_parse::args() +ast nasal_parse::args() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_args); + ast node(tokens[ptr].line,tokens[ptr].col,ast_args); match(tok_lcurve); while(tokens[ptr].type!=tok_rcurve) { - nasal_ast tmp=id(); + ast tmp=id(); if(tokens[ptr].type==tok_eq || tokens[ptr].type==tok_ellipsis) { - nasal_ast special_arg(tokens[ptr].line,tokens[ptr].col,ast_null); + ast special_arg(tokens[ptr].line,tokens[ptr].col,ast_null); if(tokens[ptr].type==tok_eq) { match(tok_eq); @@ -430,13 +430,13 @@ nasal_ast nasal_parse::args() } return node; } -nasal_ast nasal_parse::lcurve_expr() +ast nasal_parse::lcurve_expr() { if(tokens[ptr+1].type==tok_var) return definition(); return check_multi_scalar()?multi_assgin():calc(); } -nasal_ast nasal_parse::expr() +ast nasal_parse::expr() { u32 type=tokens[ptr].type; if((type==tok_break || type==tok_continue) && !in_loop) @@ -472,14 +472,14 @@ nasal_ast nasal_parse::expr() } return {tokens[ptr].line,tokens[ptr].col,ast_null}; } -nasal_ast nasal_parse::exprs() +ast nasal_parse::exprs() { if(tokens[ptr].type==tok_eof) { die(error_line,"expected expression block"); return null(); } - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_block); + ast node(tokens[ptr].line,tokens[ptr].col,ast_block); if(tokens[ptr].type==tok_lbrace) { match(tok_lbrace); @@ -502,13 +502,13 @@ nasal_ast nasal_parse::exprs() } return node; } -nasal_ast nasal_parse::calc() +ast nasal_parse::calc() { - nasal_ast node=or_expr(); + ast node=or_expr(); if(tokens[ptr].type==tok_quesmark) { // trinocular calculation - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,ast_trino); + ast tmp(tokens[ptr].line,tokens[ptr].col,ast_trino); match(tok_quesmark); tmp.add(std::move(node)); tmp.add(calc()); @@ -520,7 +520,7 @@ nasal_ast nasal_parse::calc() { check_memory_reachable(node); // tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26 - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_eq+ast_equal); + ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_eq+ast_equal); tmp.add(std::move(node)); match(tokens[ptr].type); tmp.add(calc()); @@ -528,12 +528,12 @@ nasal_ast nasal_parse::calc() } return node; } -nasal_ast nasal_parse::or_expr() +ast nasal_parse::or_expr() { - nasal_ast node=and_expr(); + ast node=and_expr(); while(tokens[ptr].type==tok_or) { - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,ast_or); + ast tmp(tokens[ptr].line,tokens[ptr].col,ast_or); tmp.add(std::move(node)); match(tok_or); tmp.add(and_expr()); @@ -541,12 +541,12 @@ nasal_ast nasal_parse::or_expr() } return node; } -nasal_ast nasal_parse::and_expr() +ast nasal_parse::and_expr() { - nasal_ast node=cmp_expr(); + ast node=cmp_expr(); while(tokens[ptr].type==tok_and) { - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,ast_and); + ast tmp(tokens[ptr].line,tokens[ptr].col,ast_and); tmp.add(std::move(node)); match(tok_and); tmp.add(cmp_expr()); @@ -554,13 +554,13 @@ nasal_ast nasal_parse::and_expr() } return node; } -nasal_ast nasal_parse::cmp_expr() +ast nasal_parse::cmp_expr() { - nasal_ast node=additive_expr(); + ast node=additive_expr(); while(tok_cmpeq<=tokens[ptr].type && tokens[ptr].type<=tok_geq) { // tok_cmpeq~tok_geq is 43~48,ast_cmpeq~ast_geq is 27~32 - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_cmpeq+ast_cmpeq); + ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_cmpeq+ast_cmpeq); tmp.add(std::move(node)); match(tokens[ptr].type); tmp.add(additive_expr()); @@ -568,12 +568,12 @@ nasal_ast nasal_parse::cmp_expr() } return node; } -nasal_ast nasal_parse::additive_expr() +ast nasal_parse::additive_expr() { - nasal_ast node=multive_expr(); + ast node=multive_expr(); while(tokens[ptr].type==tok_add || tokens[ptr].type==tok_sub || tokens[ptr].type==tok_link) { - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,ast_null); + ast tmp(tokens[ptr].line,tokens[ptr].col,ast_null); switch(tokens[ptr].type) { case tok_add: tmp.set_type(ast_add); break; @@ -587,12 +587,12 @@ nasal_ast nasal_parse::additive_expr() } return node; } -nasal_ast nasal_parse::multive_expr() +ast nasal_parse::multive_expr() { - nasal_ast node=(tokens[ptr].type==tok_sub || tokens[ptr].type==tok_not)?unary():scalar(); + ast node=(tokens[ptr].type==tok_sub || tokens[ptr].type==tok_not)?unary():scalar(); while(tokens[ptr].type==tok_mult || tokens[ptr].type==tok_div) { - nasal_ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_mult+ast_mult); + ast tmp(tokens[ptr].line,tokens[ptr].col,tokens[ptr].type-tok_mult+ast_mult); tmp.add(std::move(node)); match(tokens[ptr].type); tmp.add((tokens[ptr].type==tok_sub || tokens[ptr].type==tok_not)?unary():scalar()); @@ -600,9 +600,9 @@ nasal_ast nasal_parse::multive_expr() } return node; } -nasal_ast nasal_parse::unary() +ast nasal_parse::unary() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_null); + ast node(tokens[ptr].line,tokens[ptr].col,ast_null); switch(tokens[ptr].type) { case tok_sub:node.set_type(ast_neg);match(tok_sub);break; @@ -611,9 +611,9 @@ nasal_ast nasal_parse::unary() node.add((tokens[ptr].type==tok_sub || tokens[ptr].type==tok_not)?unary():scalar()); return node; } -nasal_ast nasal_parse::scalar() +ast nasal_parse::scalar() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_null); + ast node(tokens[ptr].line,tokens[ptr].col,ast_null); if(tokens[ptr].type==tok_nil) {node=nil();match(tok_nil);} else if(tokens[ptr].type==tok_num) node=num(); else if(tokens[ptr].type==tok_str) node=str(); @@ -643,7 +643,7 @@ nasal_ast nasal_parse::scalar() // check call and avoid ambiguous syntax if(is_call(tokens[ptr].type) && !(tokens[ptr].type==tok_lcurve && tokens[ptr+1].type==tok_var)) { - nasal_ast tmp=std::move(node); + ast tmp=std::move(node); node={tokens[ptr].line,tokens[ptr].col,ast_call}; node.add(std::move(tmp)); while(is_call(tokens[ptr].type)) @@ -651,7 +651,7 @@ nasal_ast nasal_parse::scalar() } return node; } -nasal_ast nasal_parse::call_scalar() +ast nasal_parse::call_scalar() { switch(tokens[ptr].type) { @@ -662,15 +662,15 @@ nasal_ast nasal_parse::call_scalar() // should never run this expression return {tokens[ptr].line,tokens[ptr].col,ast_nil}; } -nasal_ast nasal_parse::callh() +ast nasal_parse::callh() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_callh); + ast node(tokens[ptr].line,tokens[ptr].col,ast_callh); match(tok_dot); node.set_str(tokens[ptr].str); match(tok_id,"expected hashmap key"); // get key return node; } -nasal_ast nasal_parse::callv() +ast nasal_parse::callv() { // panic set for this token is not ',' // this is the FIRST set of subvec @@ -682,7 +682,7 @@ nasal_ast nasal_parse::callv() tok_lbrace,tok_lbracket,tok_colon, tok_null }; - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_callv); + ast node(tokens[ptr].line,tokens[ptr].col,ast_callv); match(tok_lbracket); while(tokens[ptr].type!=tok_rbracket) { @@ -699,7 +699,7 @@ nasal_ast nasal_parse::callv() match(tok_rbracket,"expected ']' when calling vector"); return node; } -nasal_ast nasal_parse::callf() +ast nasal_parse::callf() { // panic set for this token is not ',' // this is the FIRST set of calculation/hashmember @@ -710,7 +710,7 @@ nasal_ast nasal_parse::callf() tok_func,tok_var,tok_lcurve, tok_lbrace,tok_lbracket,tok_null }; - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_callf); + ast node(tokens[ptr].line,tokens[ptr].col,ast_callf); bool special_call=check_special_call(); match(tok_lcurve); while(tokens[ptr].type!=tok_rcurve) @@ -726,12 +726,12 @@ nasal_ast nasal_parse::callf() match(tok_rcurve,"expected ')' when calling function"); return node; } -nasal_ast nasal_parse::subvec() +ast nasal_parse::subvec() { - nasal_ast node=tokens[ptr].type==tok_colon?nil():calc(); + ast node=tokens[ptr].type==tok_colon?nil():calc(); if(tokens[ptr].type==tok_colon) { - nasal_ast tmp(node.line(),node.col(),ast_subvec); + ast tmp(node.line(),node.col(),ast_subvec); match(tok_colon); tmp.add(std::move(node)); tmp.add((tokens[ptr].type==tok_comma || tokens[ptr].type==tok_rbracket)?nil():calc()); @@ -739,9 +739,9 @@ nasal_ast nasal_parse::subvec() } return node; } -nasal_ast nasal_parse::definition() +ast nasal_parse::definition() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_def); + ast node(tokens[ptr].line,tokens[ptr].col,ast_def); if(tokens[ptr].type==tok_var) { match(tok_var); @@ -765,24 +765,24 @@ nasal_ast nasal_parse::definition() die(node[0].line(),"too much or lack values in multi-definition"); return node; } -nasal_ast nasal_parse::incurve_def() +ast nasal_parse::incurve_def() { match(tok_lcurve); match(tok_var); - nasal_ast node=multi_id(); + ast node=multi_id(); match(tok_rcurve); return node; } -nasal_ast nasal_parse::outcurve_def() +ast nasal_parse::outcurve_def() { match(tok_lcurve); - nasal_ast node=multi_id(); + ast node=multi_id(); match(tok_rcurve); return node; } -nasal_ast nasal_parse::multi_id() +ast nasal_parse::multi_id() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_id); + ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_id); while(tokens[ptr].type!=tok_eof) { node.add(id()); @@ -800,7 +800,7 @@ nasal_ast nasal_parse::multi_id() } return node; } -nasal_ast nasal_parse::multi_scalar(bool check_call_memory) +ast nasal_parse::multi_scalar(bool check_call_memory) { // if check_call_memory is true,we will check if value called here can reach a memory space const u32 panic_set[]={ @@ -809,7 +809,7 @@ nasal_ast nasal_parse::multi_scalar(bool check_call_memory) tok_func,tok_var,tok_lcurve, tok_lbrace,tok_lbracket,tok_null }; - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_scalar); + ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_scalar); match(tok_lcurve); while(tokens[ptr].type!=tok_rcurve) { @@ -826,9 +826,9 @@ nasal_ast nasal_parse::multi_scalar(bool check_call_memory) match(tok_rcurve,"expected ')' after multi-scalar"); return node; } -nasal_ast nasal_parse::multi_assgin() +ast nasal_parse::multi_assgin() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_assign); + ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_assign); node.add(multi_scalar(true)); match(tok_eq); if(tokens[ptr].type==tok_eof) @@ -845,10 +845,10 @@ nasal_ast nasal_parse::multi_assgin() die(node[0].line(),"too much or lack values in multi-assignment"); return node; } -nasal_ast nasal_parse::loop() +ast nasal_parse::loop() { ++in_loop; - nasal_ast node(0,0,ast_null); + ast node(0,0,ast_null); switch(tokens[ptr].type) { case tok_while: node=while_loop(); break; @@ -859,9 +859,9 @@ nasal_ast nasal_parse::loop() --in_loop; return node; } -nasal_ast nasal_parse::while_loop() +ast nasal_parse::while_loop() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_while); + ast node(tokens[ptr].line,tokens[ptr].col,ast_while); match(tok_while); match(tok_lcurve); node.add(calc()); @@ -869,9 +869,9 @@ nasal_ast nasal_parse::while_loop() node.add(exprs()); return node; } -nasal_ast nasal_parse::for_loop() +ast nasal_parse::for_loop() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_for); + ast node(tokens[ptr].line,tokens[ptr].col,ast_for); match(tok_for); match(tok_lcurve); // first expression @@ -905,9 +905,9 @@ nasal_ast nasal_parse::for_loop() node.add(exprs()); return node; } -nasal_ast nasal_parse::forei_loop() +ast nasal_parse::forei_loop() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_null); + ast node(tokens[ptr].line,tokens[ptr].col,ast_null); switch(tokens[ptr].type) { case tok_forindex:node.set_type(ast_forindex);match(tok_forindex);break; @@ -927,9 +927,9 @@ nasal_ast nasal_parse::forei_loop() node.add(exprs()); return node; } -nasal_ast nasal_parse::iter_gen() +ast nasal_parse::iter_gen() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_null); + ast node(tokens[ptr].line,tokens[ptr].col,ast_null); if(tokens[ptr].type==tok_var) { match(tok_var); @@ -946,10 +946,10 @@ nasal_ast nasal_parse::iter_gen() } return node; } -nasal_ast nasal_parse::conditional() +ast nasal_parse::conditional() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_conditional); - nasal_ast ifnode(tokens[ptr].line,tokens[ptr].col,ast_if); + ast node(tokens[ptr].line,tokens[ptr].col,ast_conditional); + ast ifnode(tokens[ptr].line,tokens[ptr].col,ast_if); match(tok_if); match(tok_lcurve); ifnode.add(calc()); @@ -958,7 +958,7 @@ nasal_ast nasal_parse::conditional() node.add(std::move(ifnode)); while(tokens[ptr].type==tok_elsif) { - nasal_ast elsifnode(tokens[ptr].line,tokens[ptr].col,ast_elsif); + ast elsifnode(tokens[ptr].line,tokens[ptr].col,ast_elsif); match(tok_elsif); match(tok_lcurve); elsifnode.add(calc()); @@ -968,28 +968,28 @@ nasal_ast nasal_parse::conditional() } if(tokens[ptr].type==tok_else) { - nasal_ast elsenode(tokens[ptr].line,tokens[ptr].col,ast_else); + ast elsenode(tokens[ptr].line,tokens[ptr].col,ast_else); match(tok_else); elsenode.add(exprs()); node.add(std::move(elsenode)); } return node; } -nasal_ast nasal_parse::continue_expr() +ast nasal_parse::continue_expr() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_continue); + ast node(tokens[ptr].line,tokens[ptr].col,ast_continue); match(tok_continue); return node; } -nasal_ast nasal_parse::break_expr() +ast nasal_parse::break_expr() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_break); + ast node(tokens[ptr].line,tokens[ptr].col,ast_break); match(tok_break); return node; } -nasal_ast nasal_parse::ret_expr() +ast nasal_parse::ret_expr() { - nasal_ast node(tokens[ptr].line,tokens[ptr].col,ast_ret); + ast node(tokens[ptr].line,tokens[ptr].col,ast_ret); match(tok_ret); u32 type=tokens[ptr].type; if(type==tok_nil || type==tok_num || diff --git a/stl/csv.nas b/stl/csv.nas new file mode 100644 index 0000000..d9781d7 --- /dev/null +++ b/stl/csv.nas @@ -0,0 +1,16 @@ +# lib csv.nas +# ValKmjolnir 2022/10/15 +var read_csv=func(path,delimeter=",",endline="\n"){ + var context=io.fin(path); + context=split(endline,context); + forindex(var i;context){ + context[i]=split(delimeter,context[i]); + } + if(size(context)<=1){ + die("incorrect csv file <"~path~">: "~size(context)~" line(s)."); + } + return { + property:context[0], + data:context[1:] + }; +} \ No newline at end of file diff --git a/test/md5compare.nas b/test/md5compare.nas index bf8a075..ad7c4ee 100644 --- a/test/md5compare.nas +++ b/test/md5compare.nas @@ -13,7 +13,7 @@ var compare=func(){ var total=end-begin; var timestamp=maketimestamp(); timestamp.stamp(); - var bar=process_bar.high_resolution_bar(50); + var bar=process_bar.high_resolution_bar(40); for(var i=begin;i