diff --git a/version2.0/abstract_syntax_tree.h b/version2.0/abstract_syntax_tree.h index 68268fb..7b74141 100644 --- a/version2.0/abstract_syntax_tree.h +++ b/version2.0/abstract_syntax_tree.h @@ -119,7 +119,10 @@ void abstract_syntax_tree::set_type(const int __type) void abstract_syntax_tree::set_line(const int __line) { - line=__line; + if(__line>=0) + line=__line; + else + line=0; return; } @@ -143,6 +146,9 @@ void abstract_syntax_tree::set_name(std::string __str) void abstract_syntax_tree::add_child(abstract_syntax_tree p) { + // use abstract_syntax_tree instead of abstract_syntax_tree& + // because when this function get a 'p' from returned value of + // another function,this may result in s SIGSEGV. children.push_back(p); return; } diff --git a/version2.0/main.cpp b/version2.0/main.cpp index f292511..df06f97 100644 --- a/version2.0/main.cpp +++ b/version2.0/main.cpp @@ -22,8 +22,8 @@ int main() std::cout<<">> [lib ] add lib file."<> [rs ] print resource code."<> [total ] print resource code with lib code."<> [lexer ] turn code into tokens."<> [parser] turn tokens into abstract syntax tree."<> [lex ] turn code into tokens."<> [par ] turn tokens into abstract syntax tree."<> [ast ] check the abstract syntax tree."<> [run ] run code."<> [exit ] quit nasal interpreter."<>[Lexer] error occurred,stop."<>[Lexer] error occurred,stop."<>[Parse] error occurred,stop."<>[Lexer] error occurred,stop."< >= __and_operator,__or_operator,__nor_operator,__add_operator,__sub_operator,__mul_operator,__div_operator,__link_operator, @@ -62,6 +63,7 @@ void print_parse_token(int type) switch(type) { case __stack_end: context="#"; break; + case __stack_top: context="#"; break; case __cmp_equal: context="=="; break; case __cmp_not_equal: context="!="; break; @@ -141,4 +143,30 @@ void print_parse_token(int type) return; } +enum parse_error_type +{ + parse_unknown_error, // unknown error + error_token_in_main, // when a token should not be the begin of a statement in main + definition_lack_var, // lack 'var' reserve word + definition_lack_id, // lack identifier +}; + +void print_parse_error(int error_type,int line,int error_token_type=__stack_end) +{ + std::string error_info_head=">>[Parse-error] line "; + switch(error_type) + { + case parse_unknown_error: std::cout<>[Parse-error] fatal error occurred."<>[Parse-error] empty token stack."<>[Parse-error] empty checked token stack."<>[Parse-error] fatal error occurred."<>[Parse-error] empty checked-token stack."<>[Abstract-syntax-tree] get root address: "<<(&root)<<" ."<get_token(); + definition_node.set_line(this_token.line); if(this_token.type!=__var) { ++error; @@ -215,6 +221,7 @@ abstract_syntax_tree nasal_parse::loop_expr() abstract_syntax_tree loop_main_node; loop_main_node.set_type(__loop); this->get_token(); + loop_main_node.set_line(this_token.line); switch(this_token.type) { case __for: @@ -229,6 +236,8 @@ abstract_syntax_tree nasal_parse::choose_expr() { abstract_syntax_tree choose_main_node; choose_main_node.set_type(__ifelse); + this->get_token(); + choose_main_node.set_line(this_token.line); return choose_main_node; } #endif diff --git a/version2.0/test.nas b/version2.0/test.nas index 57672b0..175f6d5 100644 --- a/version2.0/test.nas +++ b/version2.0/test.nas @@ -1,3 +1,20 @@ +# basic type +nil; +2147483647; +0x7fffffff; +0xdeadbeef; +0o70120327; +"hello world!"; +'hello world!'; +-12; +!0; +-((30)); +[]; +{}; +[0,1,2,3,4,5][2]; # 2 +{str:"hello"}.str; # "hello" +{str:"hello"}["str"]; # "hello" + # normal scalar var number_1=1; var number_2=0xdeadbeef; @@ -5,6 +22,7 @@ var number_3=0x13702; var number_4=0.12341490239423; var string_1="hello"; var string_2='hello'; +var string_3=number_1? 'yes':'no'; # yes # vector var vector_1=[]; @@ -51,14 +69,18 @@ print(source['member_2']()); print(source.member_2()); var test_func=func{return 1;} -print(func test_func()); # 1 -print(test_func()); # 1 -print(func test_func); # nothing -print(test_func); # nothing +print(func test_func()); # 1 +print(test_func()); # 1 +print(func test_func); # nothing +print(test_func); # nothing +print(([0,1,2,3])[1]); # 1 +print(({str:"what?"})["str"]); # what? +print(({str:"what?"}).str); # what? # lambda (func(x){return x>0? x:0;})(12); (func{print("hello world");})(); +(((func(x){return 1.0/math.exp(x);})))(0); # flexible definition & assignment var (r,g,b)=[0x00,0x10,0xff]; @@ -67,4 +89,23 @@ var color=[0x00,0x10,0xff]; var (r,g,b)=color; (var r,g,b)=color; (r,g,b)=(b,g,r); -(number_1,number_2)=(number_2,number_1); \ No newline at end of file +(number_1,number_2)=(number_2,number_1); + +# calculation +1+1; +1+1-2+3-4+5-6; +1+1*8-9/3; +1*(1+2*(3+4*(5+6*(7+8*(9+10/(1+1)))))); +((-1*2+9))/7-1; +((({num:2})))["num"]*2*2*2; +((((([0,1,2])[0:2]))[0:2]))[1]-1; +(((((((((((((((((((1+1+2+3+5)+8))+13)))+21))))+34)))))+55))))*89; +number_1*(number_2+number_3)/90-number_4; +(func test_func)()-1; +hash_3.member_3+(func {return {what:"i don't tell you.",case_small:80,case_large:100}})["case_large"]/10; +-1*10+5 or 10-10; +nil and 1+7*8; +(number_1 or number_2) and (number_3 or number_4-number_4*1); +[0,1,4,3,2][4]*2-4+1*2*2*2*2*2/8; +{num:0}.num or {what_is_the_secret_of_universe:42}["what_is_the_secret_of_universe"]; +"123"~"456"-123456*2/2; \ No newline at end of file