update
This commit is contained in:
parent
eda2f7b863
commit
ab885724d9
|
@ -47,6 +47,7 @@ int main()
|
||||||
std::cout<<">> [par ] 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<<">> [logo ] print logo of nasal ."<<std::endl;
|
||||||
std::cout<<">> [info ] print lexer,parser and ast on screen."<<std::endl;
|
std::cout<<">> [info ] print lexer,parser and ast on screen."<<std::endl;
|
||||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +161,14 @@ int main()
|
||||||
else
|
else
|
||||||
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
std::cout<<">> [Lexer] error occurred,stop."<<std::endl;
|
||||||
}
|
}
|
||||||
|
else if(command=="logo")
|
||||||
|
{
|
||||||
|
std::cout<<" __ _ "<<std::endl;
|
||||||
|
std::cout<<" /\\ \\ \\__ _ ___ __ _| |"<<std::endl;
|
||||||
|
std::cout<<" / \\/ / _` / __|/ _` | |"<<std::endl;
|
||||||
|
std::cout<<" / /\\ / (_| \\__ \\ (_| | |"<<std::endl;
|
||||||
|
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|"<<std::endl;
|
||||||
|
}
|
||||||
else if(command=="info")
|
else if(command=="info")
|
||||||
{
|
{
|
||||||
lexer.scanner(resource.get_source());
|
lexer.scanner(resource.get_source());
|
||||||
|
|
|
@ -21,7 +21,7 @@ class nasal_runtime
|
||||||
__stack_overflow,
|
__stack_overflow,
|
||||||
};
|
};
|
||||||
int runtime_error_exit_mark;
|
int runtime_error_exit_mark;
|
||||||
void error_interrupt (const int);
|
void error_interrupt (const int,const int);
|
||||||
int number_generation (abstract_syntax_tree&);
|
int number_generation (abstract_syntax_tree&);
|
||||||
int string_generation (abstract_syntax_tree&);
|
int string_generation (abstract_syntax_tree&);
|
||||||
int vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int vector_generation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
|
@ -29,7 +29,6 @@ class nasal_runtime
|
||||||
int function_generation(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int function_generation(std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int calculation (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int call_identifier (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
int assignment (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
|
||||||
void definition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
void definition (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
void loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
void loop_expr (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
void conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
void conditional (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
||||||
|
@ -50,23 +49,23 @@ class nasal_runtime
|
||||||
void main_proc(abstract_syntax_tree&);
|
void main_proc(abstract_syntax_tree&);
|
||||||
};
|
};
|
||||||
|
|
||||||
void nasal_runtime::error_interrupt(const int type)
|
void nasal_runtime::error_interrupt(const int type,const int line)
|
||||||
{
|
{
|
||||||
std::string error_head=">> [Runtime] fatal error: ";
|
std::cout<<">> [Runtime] line "<<line<<": ";
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case __incorrect_head_of_tree:
|
case __incorrect_head_of_tree:
|
||||||
std::cout<<error_head<<"lib hasn\'t been loaded."<<std::endl;break;
|
std::cout<<"lib hasn\'t been loaded."<<std::endl;break;
|
||||||
case __incorrect_head_of_func:
|
case __incorrect_head_of_func:
|
||||||
std::cout<<error_head<<"called identifier is not a function."<<std::endl;break;
|
std::cout<<"called identifier is not a function."<<std::endl;break;
|
||||||
case __not_numerable_str:
|
case __not_numerable_str:
|
||||||
std::cout<<error_head<<"this string is not a numerable one."<<std::endl;break;
|
std::cout<<"this string is not a numerable one."<<std::endl;break;
|
||||||
case __stack_overflow:
|
case __stack_overflow:
|
||||||
std::cout<<error_head<<"stack overflow."<<std::endl;break;
|
std::cout<<"stack overflow."<<std::endl;break;
|
||||||
case __error_value_type:
|
case __error_value_type:
|
||||||
std::cout<<error_head<<"operator gets error value type."<<std::endl;break;
|
std::cout<<"operator gets error value type."<<std::endl;break;
|
||||||
default:
|
default:
|
||||||
std::cout<<error_head<<"unknown error."<<std::endl;break;
|
std::cout<<"unknown error."<<std::endl;break;
|
||||||
}
|
}
|
||||||
runtime_error_exit_mark=type;
|
runtime_error_exit_mark=type;
|
||||||
return;
|
return;
|
||||||
|
@ -192,55 +191,58 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
|
||||||
return function_generation(local_scope,node);
|
return function_generation(local_scope,node);
|
||||||
else if(node_type==__id)
|
else if(node_type==__id)
|
||||||
return call_identifier(local_scope,node);
|
return call_identifier(local_scope,node);
|
||||||
else if(node_type==__add_operator)
|
else if(node_type==__add_operator || node_type==__sub_operator || node_type==__mul_operator || node_type==__div_operator)
|
||||||
{
|
{
|
||||||
|
// scalar_nil canot be used here
|
||||||
int ret_addr=-1;
|
int ret_addr=-1;
|
||||||
int addr_1=calculation(local_scope,node.get_children().front());
|
int addr_1=-1;
|
||||||
int addr_2=calculation(local_scope,node.get_children().back());
|
int addr_2=-1;
|
||||||
|
if(node.get_children().size()==1)
|
||||||
|
{
|
||||||
|
// note: sub operator and nor operator may mean that this is unary calculation
|
||||||
|
addr_1=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(addr_1).set_type(scalar_number);
|
||||||
|
nasal_gc.get_scalar(addr_1).get_number().set_number(0);
|
||||||
|
addr_2=calculation(local_scope,node.get_children().front());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr_1=calculation(local_scope,node.get_children().front());
|
||||||
|
addr_2=calculation(local_scope,node.get_children().back());
|
||||||
|
}
|
||||||
// check if the address is available
|
// check if the address is available
|
||||||
if(addr_1<0 || addr_2<0)
|
if(addr_1<0 || addr_2<0)
|
||||||
return -1;
|
return -1;
|
||||||
int type_1=nasal_gc.get_scalar(addr_1).get_type();
|
int type_1=nasal_gc.get_scalar(addr_1).get_type();
|
||||||
int type_2=nasal_gc.get_scalar(addr_2).get_type();
|
int type_2=nasal_gc.get_scalar(addr_2).get_type();
|
||||||
|
double num_1=0;
|
||||||
|
double num_2=0;
|
||||||
if(type_1==scalar_number && type_2==scalar_number)
|
if(type_1==scalar_number && type_2==scalar_number)
|
||||||
{
|
{
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
num_1=nasal_gc.get_scalar(addr_1).get_number().get_number();
|
||||||
double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number();
|
num_2=nasal_gc.get_scalar(addr_2).get_number().get_number();
|
||||||
double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number();
|
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1+num_2);
|
|
||||||
}
|
}
|
||||||
else if(type_1==scalar_number && type_2==scalar_string)
|
else if(type_1==scalar_number && type_2==scalar_string)
|
||||||
{
|
{
|
||||||
double num_1=nasal_gc.get_scalar(addr_1).get_number().get_number();
|
num_1=nasal_gc.get_scalar(addr_1).get_number().get_number();
|
||||||
std::string tmp_str=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
std::string tmp_str=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
||||||
if(check_numerable_string(tmp_str))
|
if(check_numerable_string(tmp_str))
|
||||||
{
|
num_2=trans_string_to_number(tmp_str);
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
|
||||||
double num_2=trans_string_to_number(tmp_str);
|
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1+num_2);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_interrupt(__not_numerable_str);
|
error_interrupt(__not_numerable_str,node.get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(type_1==scalar_string && type_2==scalar_number)
|
else if(type_1==scalar_string && type_2==scalar_number)
|
||||||
{
|
{
|
||||||
std::string tmp_str=nasal_gc.get_scalar(addr_1).get_string().get_string();
|
std::string tmp_str=nasal_gc.get_scalar(addr_1).get_string().get_string();
|
||||||
double num_2=nasal_gc.get_scalar(addr_2).get_number().get_number();
|
num_2=nasal_gc.get_scalar(addr_2).get_number().get_number();
|
||||||
if(check_numerable_string(tmp_str))
|
if(check_numerable_string(tmp_str))
|
||||||
{
|
num_1=trans_string_to_number(tmp_str);
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
|
||||||
double num_1=trans_string_to_number(tmp_str);
|
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1+num_2);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_interrupt(__not_numerable_str);
|
error_interrupt(__not_numerable_str,node.get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,71 +252,136 @@ int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scop
|
||||||
std::string tmp_str_2=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
std::string tmp_str_2=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
||||||
if(check_numerable_string(tmp_str_1) && check_numerable_string(tmp_str_2))
|
if(check_numerable_string(tmp_str_1) && check_numerable_string(tmp_str_2))
|
||||||
{
|
{
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
num_1=trans_string_to_number(tmp_str_1);
|
||||||
double num_1=trans_string_to_number(tmp_str_1);
|
num_2=trans_string_to_number(tmp_str_2);
|
||||||
double num_2=trans_string_to_number(tmp_str_2);
|
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1+num_2);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_interrupt(__not_numerable_str);
|
error_interrupt(__not_numerable_str,node.get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_interrupt(__error_value_type);;
|
error_interrupt(__error_value_type,node.get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
||||||
|
switch(node_type)
|
||||||
|
{
|
||||||
|
case __add_operator:nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1+num_2);break;
|
||||||
|
case __sub_operator:nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1-num_2);break;
|
||||||
|
case __mul_operator:nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1*num_2);break;
|
||||||
|
case __div_operator:nasal_gc.get_scalar(ret_addr).get_number().set_number(num_1/num_2);break;
|
||||||
|
}
|
||||||
nasal_gc.reference_delete(addr_1);
|
nasal_gc.reference_delete(addr_1);
|
||||||
nasal_gc.reference_delete(addr_2);
|
nasal_gc.reference_delete(addr_2);
|
||||||
return ret_addr;
|
return ret_addr;
|
||||||
}
|
}
|
||||||
else if(node_type==__sub_operator)
|
else if(node_type==__link_operator)
|
||||||
{
|
{
|
||||||
|
// scalar_nil cannot be used here
|
||||||
int ret_addr=-1;
|
int ret_addr=-1;
|
||||||
// note: sub operator maybe mean that this is unary calculation
|
int addr_1=calculation(local_scope,node.get_children().front());
|
||||||
if(node.get_children().size()==1)
|
int addr_2=calculation(local_scope,node.get_children().back());
|
||||||
|
// check if the address is available
|
||||||
|
if(addr_1<0 || addr_2<0)
|
||||||
|
return -1;
|
||||||
|
int type_1=nasal_gc.get_scalar(addr_1).get_type();
|
||||||
|
int type_2=nasal_gc.get_scalar(addr_2).get_type();
|
||||||
|
std::string str_1;
|
||||||
|
std::string str_2;
|
||||||
|
if(type_1==scalar_number && type_2==scalar_number)
|
||||||
{
|
{
|
||||||
int addr=calculation(local_scope,node.get_children().front());
|
str_1=trans_number_to_string(nasal_gc.get_scalar(addr_1).get_number().get_number());
|
||||||
if(ret_addr<0)
|
str_2=trans_number_to_string(nasal_gc.get_scalar(addr_2).get_number().get_number());
|
||||||
return -1;
|
}
|
||||||
int type=nasal_gc.get_scalar(addr).get_type();
|
else if(type_1==scalar_number && type_2==scalar_string)
|
||||||
if(type==scalar_number)
|
{
|
||||||
{
|
str_1=trans_number_to_string(nasal_gc.get_scalar(addr_1).get_number().get_number());
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
str_2=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
||||||
double num=nasal_gc.get_scalar(addr).get_number().get_number();
|
}
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
else if(type_1==scalar_string && type_2==scalar_number)
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(-num);
|
{
|
||||||
}
|
str_1=nasal_gc.get_scalar(addr_1).get_string().get_string();
|
||||||
else if(type==scalar_string)
|
str_2=trans_number_to_string(nasal_gc.get_scalar(addr_2).get_number().get_number());
|
||||||
{
|
}
|
||||||
std::string tmp_str=nasal_gc.get_scalar(ret_addr).get_string().get_string();
|
else if(type_1==scalar_string && type_2==scalar_string)
|
||||||
if(check_numerable_string(tmp_str))
|
{
|
||||||
{
|
str_1=nasal_gc.get_scalar(addr_1).get_string().get_string();
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
str_2=nasal_gc.get_scalar(addr_2).get_string().get_string();
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
|
||||||
nasal_gc.get_scalar(ret_addr).get_number().set_number(-trans_string_to_number(tmp_str));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error_interrupt(__not_numerable_str);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nasal_gc.reference_delete(addr);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int addr_1=calculation(local_scope,node.get_children().front());
|
error_interrupt(__error_value_type,node.get_node_line());
|
||||||
int addr_2=calculation(local_scope,node.get_children().back());
|
return -1;
|
||||||
if(addr_1<0 || addr_2<0)
|
|
||||||
return -1;
|
|
||||||
// unfinished
|
|
||||||
}
|
}
|
||||||
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_string);
|
||||||
|
nasal_gc.get_scalar(ret_addr).get_string().set_string(str_1+str_2);
|
||||||
|
nasal_gc.reference_delete(addr_1);
|
||||||
|
nasal_gc.reference_delete(addr_2);
|
||||||
return ret_addr;
|
return ret_addr;
|
||||||
}
|
}
|
||||||
|
else if(node_type==__cmp_equal || node_type==__cmp_not_equal || node_type==__cmp_less || node_type==__cmp_less_or_equal || node_type==__cmp_more || node_type==__cmp_more_or_equal)
|
||||||
|
{
|
||||||
|
int ret_addr=-1;
|
||||||
|
int addr_1=calculation(local_scope,node.get_children().front());
|
||||||
|
int addr_2=calculation(local_scope,node.get_children().back());
|
||||||
|
// check if the address is available
|
||||||
|
if(addr_1<0 || addr_2<0)
|
||||||
|
return -1;
|
||||||
|
int type_1=nasal_gc.get_scalar(addr_1).get_type();
|
||||||
|
int type_2=nasal_gc.get_scalar(addr_2).get_type();
|
||||||
|
// note: cmp operator change strings into numbers then making comparation
|
||||||
|
if(type_1==scalar_number && type_2==scalar_number)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(type_1==scalar_number && type_2==scalar_string)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(type_1==scalar_string && type_2==scalar_number)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(type_1==scalar_string && type_2==scalar_string)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_interrupt(__error_value_type,node.get_node_line());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_number);
|
||||||
|
//
|
||||||
|
nasal_gc.reference_delete(addr_1);
|
||||||
|
nasal_gc.reference_delete(addr_2);
|
||||||
|
return ret_addr;
|
||||||
|
}
|
||||||
|
else if(node_type==__equal)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(node_type==__add_equal || node_type==__sub_equal || node_type==__mul_equal || node_type==__div_equal || node_type==__link_equal)
|
||||||
|
{
|
||||||
|
// scalar_nil also cannot be used here
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(node_type==__and_operator || node_type==__or_operator || node_type==__nor_operator)
|
||||||
|
{
|
||||||
|
// or will return the first value that is not null
|
||||||
|
// and will return the last value that is not null
|
||||||
|
// nor will return 0 if the value is not null
|
||||||
|
// nor will return 1 if the value is null(0,nil,'0',"0")
|
||||||
|
// if or gets all 0,or returns 0
|
||||||
|
// if and gets a 0,and returns 0
|
||||||
|
;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
|
@ -328,12 +395,6 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
addr=(*iter)[tmp_id_name];
|
addr=(*iter)[tmp_id_name];
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int nasal_runtime::assignment(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
|
||||||
{
|
|
||||||
if(local_scope.empty())
|
|
||||||
;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
void nasal_runtime::definition(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
void nasal_runtime::definition(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
{
|
{
|
||||||
if(local_scope.empty())
|
if(local_scope.empty())
|
||||||
|
@ -359,7 +420,7 @@ int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,
|
||||||
{
|
{
|
||||||
if(func_root.get_node_type()!=__function)
|
if(func_root.get_node_type()!=__function)
|
||||||
{
|
{
|
||||||
error_interrupt(__incorrect_head_of_func);
|
error_interrupt(__incorrect_head_of_func,func_root.get_node_line());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::map<std::string,int> new_scope;
|
std::map<std::string,int> new_scope;
|
||||||
|
@ -415,7 +476,7 @@ void nasal_runtime::main_proc(abstract_syntax_tree& root)
|
||||||
|
|
||||||
if(root.get_node_type()!=__root)
|
if(root.get_node_type()!=__root)
|
||||||
{
|
{
|
||||||
error_interrupt(__incorrect_head_of_tree);
|
error_interrupt(__incorrect_head_of_tree,root.get_node_line());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=root.get_children().begin();iter!=root.get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=root.get_children().begin();iter!=root.get_children().end();++iter)
|
||||||
|
|
Loading…
Reference in New Issue