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)
|
void abstract_syntax_tree::set_line(const int __line)
|
||||||
{
|
{
|
||||||
|
if(__line>=0)
|
||||||
line=__line;
|
line=__line;
|
||||||
|
else
|
||||||
|
line=0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +146,9 @@ void abstract_syntax_tree::set_name(std::string __str)
|
||||||
|
|
||||||
void abstract_syntax_tree::add_child(abstract_syntax_tree p)
|
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);
|
children.push_back(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ int main()
|
||||||
std::cout<<">> [lib ] add lib file."<<std::endl;
|
std::cout<<">> [lib ] add lib file."<<std::endl;
|
||||||
std::cout<<">> [rs ] print resource code."<<std::endl;
|
std::cout<<">> [rs ] print resource code."<<std::endl;
|
||||||
std::cout<<">> [total ] print resource code with lib 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<<">> [lex ] turn code into tokens."<<std::endl;
|
||||||
std::cout<<">> [parser] turn tokens into abstract syntax tree."<<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<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||||
std::cout<<">> [run ] run code."<<std::endl;
|
std::cout<<">> [run ] run code."<<std::endl;
|
||||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||||
|
@ -61,7 +61,7 @@ int main()
|
||||||
{
|
{
|
||||||
resource.print_resource(true);
|
resource.print_resource(true);
|
||||||
}
|
}
|
||||||
else if(command=="lexer")
|
else if(command=="lex")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
lexer.generate_detail_token();
|
lexer.generate_detail_token();
|
||||||
|
@ -70,7 +70,7 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
else if(command=="parser")
|
else if(command=="par")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
lexer.generate_detail_token();
|
lexer.generate_detail_token();
|
||||||
|
@ -99,6 +99,24 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">>[Lexer] error occurred,stop."<<std::endl;
|
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")
|
else if(command=="exit")
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
|
|
|
@ -25,6 +25,7 @@ void print_lexer_token(int type)
|
||||||
enum parse_token_type
|
enum parse_token_type
|
||||||
{
|
{
|
||||||
__stack_end=1,
|
__stack_end=1,
|
||||||
|
__stack_top,
|
||||||
__cmp_equal,__cmp_not_equal,__cmp_less,__cmp_less_or_equal,__cmp_more,__cmp_more_or_equal,
|
__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,
|
__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)
|
switch(type)
|
||||||
{
|
{
|
||||||
case __stack_end: context="#"; break;
|
case __stack_end: context="#"; break;
|
||||||
|
case __stack_top: context="#"; break;
|
||||||
|
|
||||||
case __cmp_equal: context="=="; break;
|
case __cmp_equal: context="=="; break;
|
||||||
case __cmp_not_equal: context="!="; break;
|
case __cmp_not_equal: context="!="; break;
|
||||||
|
@ -141,4 +143,30 @@ void print_parse_token(int type)
|
||||||
return;
|
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
|
#endif
|
||||||
|
|
|
@ -91,6 +91,7 @@ void nasal_parse::get_token()
|
||||||
{
|
{
|
||||||
this_token.type=__stack_end;
|
this_token.type=__stack_end;
|
||||||
this_token.str="__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;
|
std::cout<<">>[Parse-error] empty token stack."<<std::endl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -105,7 +106,10 @@ void nasal_parse::push_token()
|
||||||
checked_tokens.pop();
|
checked_tokens.pop();
|
||||||
}
|
}
|
||||||
else
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +120,7 @@ int nasal_parse::get_error()
|
||||||
|
|
||||||
abstract_syntax_tree& nasal_parse::get_root()
|
abstract_syntax_tree& nasal_parse::get_root()
|
||||||
{
|
{
|
||||||
|
std::cout<<">>[Abstract-syntax-tree] get root address: "<<(&root)<<" ."<<std::endl;
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +195,7 @@ abstract_syntax_tree nasal_parse::var_outside_definition()
|
||||||
abstract_syntax_tree definition_node;
|
abstract_syntax_tree definition_node;
|
||||||
definition_node.set_type(__definition);
|
definition_node.set_type(__definition);
|
||||||
this->get_token();
|
this->get_token();
|
||||||
|
definition_node.set_line(this_token.line);
|
||||||
if(this_token.type!=__var)
|
if(this_token.type!=__var)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
|
@ -215,6 +221,7 @@ abstract_syntax_tree nasal_parse::loop_expr()
|
||||||
abstract_syntax_tree loop_main_node;
|
abstract_syntax_tree loop_main_node;
|
||||||
loop_main_node.set_type(__loop);
|
loop_main_node.set_type(__loop);
|
||||||
this->get_token();
|
this->get_token();
|
||||||
|
loop_main_node.set_line(this_token.line);
|
||||||
switch(this_token.type)
|
switch(this_token.type)
|
||||||
{
|
{
|
||||||
case __for:
|
case __for:
|
||||||
|
@ -229,6 +236,8 @@ abstract_syntax_tree nasal_parse::choose_expr()
|
||||||
{
|
{
|
||||||
abstract_syntax_tree choose_main_node;
|
abstract_syntax_tree choose_main_node;
|
||||||
choose_main_node.set_type(__ifelse);
|
choose_main_node.set_type(__ifelse);
|
||||||
|
this->get_token();
|
||||||
|
choose_main_node.set_line(this_token.line);
|
||||||
return choose_main_node;
|
return choose_main_node;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
# normal scalar
|
||||||
var number_1=1;
|
var number_1=1;
|
||||||
var number_2=0xdeadbeef;
|
var number_2=0xdeadbeef;
|
||||||
|
@ -5,6 +22,7 @@ var number_3=0x13702;
|
||||||
var number_4=0.12341490239423;
|
var number_4=0.12341490239423;
|
||||||
var string_1="hello";
|
var string_1="hello";
|
||||||
var string_2='hello';
|
var string_2='hello';
|
||||||
|
var string_3=number_1? 'yes':'no'; # yes
|
||||||
|
|
||||||
# vector
|
# vector
|
||||||
var vector_1=[];
|
var vector_1=[];
|
||||||
|
@ -55,10 +73,14 @@ print(func test_func()); # 1
|
||||||
print(test_func()); # 1
|
print(test_func()); # 1
|
||||||
print(func test_func); # nothing
|
print(func test_func); # nothing
|
||||||
print(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
|
# lambda
|
||||||
(func(x){return x>0? x:0;})(12);
|
(func(x){return x>0? x:0;})(12);
|
||||||
(func{print("hello world");})();
|
(func{print("hello world");})();
|
||||||
|
(((func(x){return 1.0/math.exp(x);})))(0);
|
||||||
|
|
||||||
# flexible definition & assignment
|
# flexible definition & assignment
|
||||||
var (r,g,b)=[0x00,0x10,0xff];
|
var (r,g,b)=[0x00,0x10,0xff];
|
||||||
|
@ -68,3 +90,22 @@ var (r,g,b)=color;
|
||||||
(var r,g,b)=color;
|
(var r,g,b)=color;
|
||||||
(r,g,b)=(b,g,r);
|
(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