update
This commit is contained in:
parent
1dc355a722
commit
e989eca0c7
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ int main()
|
|||
std::cout<<">> [lib ] add lib file."<<std::endl;
|
||||
std::cout<<">> [rs ] print resource code."<<std::endl;
|
||||
std::cout<<">> [total ] print resource code with lib code."<<std::endl;
|
||||
std::cout<<">> [lexer ] turn code into tokens."<<std::endl;
|
||||
std::cout<<">> [parser] turn tokens into abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
||||
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||
std::cout<<">> [run ] run code."<<std::endl;
|
||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||
|
@ -61,7 +61,7 @@ int main()
|
|||
{
|
||||
resource.print_resource(true);
|
||||
}
|
||||
else if(command=="lexer")
|
||||
else if(command=="lex")
|
||||
{
|
||||
lexer.scanner(resource.get_source());
|
||||
lexer.generate_detail_token();
|
||||
|
@ -70,7 +70,7 @@ int main()
|
|||
else
|
||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
||||
}
|
||||
else if(command=="parser")
|
||||
else if(command=="par")
|
||||
{
|
||||
lexer.scanner(resource.get_source());
|
||||
lexer.generate_detail_token();
|
||||
|
@ -99,6 +99,24 @@ int main()
|
|||
else
|
||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
||||
}
|
||||
else if(command=="run")
|
||||
{
|
||||
lexer.scanner(resource.get_source());
|
||||
lexer.generate_detail_token();
|
||||
if(!lexer.get_error())
|
||||
{
|
||||
parser.get_token_list(lexer.get_detail_token_list());
|
||||
parser.main_generate();
|
||||
if(!parser.get_error())
|
||||
{
|
||||
// run code
|
||||
}
|
||||
else
|
||||
std::cout<<">>[Parse] error occurred,stop."<<std::endl;
|
||||
}
|
||||
else
|
||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
||||
}
|
||||
else if(command=="exit")
|
||||
break;
|
||||
else
|
||||
|
|
|
@ -25,6 +25,7 @@ void print_lexer_token(int type)
|
|||
enum parse_token_type
|
||||
{
|
||||
__stack_end=1,
|
||||
__stack_top,
|
||||
__cmp_equal,__cmp_not_equal,__cmp_less,__cmp_less_or_equal,__cmp_more,__cmp_more_or_equal,
|
||||
// == != < <= > >=
|
||||
__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<<error_info_head<<line<<": unknown parse error. error id: parse_unknown_error."<<std::endl;break;
|
||||
case error_token_in_main:
|
||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
||||
print_parse_token(error_token_type);
|
||||
std::cout<<"\' in main scope."<<std::endl;
|
||||
break;
|
||||
case definition_lack_var: std::cout<<error_info_head<<line<<": expect a \'var\' here."<<std::endl;break;
|
||||
case definition_lack_id: std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
||||
default: std::cout<<error_info_head<<line<<": unknown parse error. error id: other_type."<<std::endl;break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,6 +91,7 @@ void nasal_parse::get_token()
|
|||
{
|
||||
this_token.type=__stack_end;
|
||||
this_token.str="__stack_end";
|
||||
std::cout<<">>[Parse-error] fatal error occurred."<<std::endl;
|
||||
std::cout<<">>[Parse-error] empty token stack."<<std::endl;
|
||||
}
|
||||
return;
|
||||
|
@ -105,7 +106,10 @@ void nasal_parse::push_token()
|
|||
checked_tokens.pop();
|
||||
}
|
||||
else
|
||||
std::cout<<">>[Parse-error] empty checked token stack."<<std::endl;
|
||||
{
|
||||
std::cout<<">>[Parse-error] fatal error occurred."<<std::endl;
|
||||
std::cout<<">>[Parse-error] empty checked-token stack."<<std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -116,6 +120,7 @@ int nasal_parse::get_error()
|
|||
|
||||
abstract_syntax_tree& nasal_parse::get_root()
|
||||
{
|
||||
std::cout<<">>[Abstract-syntax-tree] get root address: "<<(&root)<<" ."<<std::endl;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -190,6 +195,7 @@ abstract_syntax_tree nasal_parse::var_outside_definition()
|
|||
abstract_syntax_tree definition_node;
|
||||
definition_node.set_type(__definition);
|
||||
this->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
|
||||
|
|
|
@ -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);
|
||||
(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;
|
Loading…
Reference in New Issue