update
This commit is contained in:
parent
28cc088461
commit
c250bfb8d8
|
@ -1,11 +1,17 @@
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
|
// source code will be put in resource
|
||||||
resource_file resource;
|
resource_file resource;
|
||||||
|
// source code will be generated to tokens in lexer
|
||||||
nasal_lexer lexer;
|
nasal_lexer lexer;
|
||||||
|
// token list will be checked in parser and output the abstract syntax tree
|
||||||
nasal_parse parser;
|
nasal_parse parser;
|
||||||
|
// libroot stores the ast of lib file
|
||||||
abstract_syntax_tree libroot;
|
abstract_syntax_tree libroot;
|
||||||
|
// root stores the ast of source code
|
||||||
abstract_syntax_tree root;
|
abstract_syntax_tree root;
|
||||||
abstract_syntax_tree linker;
|
// executable_ast generates libroot and root together
|
||||||
|
abstract_syntax_tree executable_ast;
|
||||||
|
|
||||||
nasal_runtime runtime;
|
nasal_runtime runtime;
|
||||||
|
|
||||||
|
@ -69,7 +75,7 @@ int main()
|
||||||
lexer.delete_all_tokens();
|
lexer.delete_all_tokens();
|
||||||
parser.delete_all_elements();
|
parser.delete_all_elements();
|
||||||
root.set_clear();
|
root.set_clear();
|
||||||
linker.set_clear();
|
executable_ast.set_clear();
|
||||||
std::cout<<">> [Delete] complete."<<std::endl;
|
std::cout<<">> [Delete] complete."<<std::endl;
|
||||||
}
|
}
|
||||||
else if(command=="lib")
|
else if(command=="lib")
|
||||||
|
@ -148,11 +154,10 @@ int main()
|
||||||
parser.main_generate();
|
parser.main_generate();
|
||||||
if(!parser.get_error())
|
if(!parser.get_error())
|
||||||
{
|
{
|
||||||
linker.set_clear();
|
executable_ast.set_clear();
|
||||||
linker=libroot;
|
executable_ast=libroot;
|
||||||
linker.merge_children(parser.get_root());
|
executable_ast.merge_children(parser.get_root());
|
||||||
root=linker;
|
runtime.main_proc(executable_ast);
|
||||||
runtime.main_proc(root);
|
|
||||||
//root.print_tree();
|
//root.print_tree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -204,180 +204,6 @@ void print_ast_type(int type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum parse_error_type
|
|
||||||
{
|
|
||||||
parse_unknown_error=0, // unknown error
|
|
||||||
error_token_in_main, // when a token should not be the begin of a statement in main
|
|
||||||
error_token_in_block, // when a token should not be the begin of a statement in block
|
|
||||||
|
|
||||||
lack_semi,
|
|
||||||
lack_id,
|
|
||||||
lack_left_curve,
|
|
||||||
lack_right_curve,
|
|
||||||
lack_right_brace,
|
|
||||||
|
|
||||||
definition_lack_id, // lack identifier
|
|
||||||
definition_lack_equal, // lack '=' when not getting ';'
|
|
||||||
assignment_begin_error, // assignment begins with more than one identifier_call
|
|
||||||
multi_definition_need_curve, // lack right curve when generating 'var (id,id,id)'
|
|
||||||
|
|
||||||
multi_assignment_need_curve, // lack right curve when generating (scalar,scalar)=(scalar,scalar)
|
|
||||||
multi_assignment_need_equal, // lack '=' when generating (scalar,scalar)=(scalar,scalar)
|
|
||||||
|
|
||||||
error_begin_token_of_scalar, // in scalar_generate()
|
|
||||||
|
|
||||||
default_dynamic_parameter, // default parameter should not be dynamic
|
|
||||||
parameter_lack_part, // parameter lack a ')' or identifier
|
|
||||||
parameter_lack_curve, // parameter lack a ',' or ')'
|
|
||||||
|
|
||||||
special_call_func_lack_id,
|
|
||||||
special_call_func_lack_colon,
|
|
||||||
call_func_lack_comma, // lack comma when giving parameters to a function
|
|
||||||
call_hash_lack_id, // lack identifier when calling a hash
|
|
||||||
call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here)
|
|
||||||
call_vector_lack_bracket, // lack ']' when calling a vector
|
|
||||||
call_vector_wrong_token, // get wrong token when calling a vector
|
|
||||||
|
|
||||||
vector_gen_lack_end, // lack ',' or ')' when generating a vector
|
|
||||||
hash_gen_lack_id, // lack identifier or string when generating a hash
|
|
||||||
hash_gen_lack_colon, // lack ':' when generating a hash
|
|
||||||
hash_gen_lack_end, // lack ',' or '}' when generating a hash
|
|
||||||
|
|
||||||
ternary_operator_lack_colon, // lack ':'
|
|
||||||
};
|
|
||||||
void print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
|
||||||
{
|
|
||||||
std::string error_info_head=">> [Parse-error] line ";
|
|
||||||
std::string warning_info_head=">> [Parse-warning] line ";
|
|
||||||
switch(error_type)
|
|
||||||
{
|
|
||||||
case parse_unknown_error:
|
|
||||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<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 error_token_in_block:
|
|
||||||
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' in block scope."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case lack_semi:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \';\' at the end of the statement."<<std::endl;break;
|
|
||||||
case lack_id:
|
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier here."<<std::endl;break;
|
|
||||||
case lack_left_curve:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
|
||||||
case lack_right_curve:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
|
||||||
case lack_right_brace:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \'}\' here."<<std::endl;break;
|
|
||||||
|
|
||||||
case definition_lack_id:
|
|
||||||
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
|
||||||
case definition_lack_equal:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' when generating definition."<<std::endl;
|
|
||||||
break;
|
|
||||||
case assignment_begin_error:
|
|
||||||
std::cout<<error_info_head<<line<<": assignment should begin with one identifier_call."<<std::endl;
|
|
||||||
break;
|
|
||||||
case multi_definition_need_curve:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case multi_assignment_need_curve:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case multi_assignment_need_equal:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case error_begin_token_of_scalar:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a scalar here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case default_dynamic_parameter:
|
|
||||||
std::cout<<error_info_head<<line<<": dynamic parameter should not have a default value."<<std::endl;break;
|
|
||||||
case parameter_lack_part:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' or identifier here when generating parameter_list."<<std::endl;break;
|
|
||||||
case parameter_lack_curve:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \')\' or \',\' here when generating parameter_list."<<std::endl;break;
|
|
||||||
|
|
||||||
case special_call_func_lack_id:
|
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' when calling functions."<<std::endl;
|
|
||||||
break;
|
|
||||||
case special_call_func_lack_colon:
|
|
||||||
std::cout<<error_info_head<<line<<": expect an \':\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' when calling functions."<<std::endl;
|
|
||||||
break;
|
|
||||||
case call_func_lack_comma:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' when calling a function but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case call_hash_lack_id:
|
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier after \'.\' ."<<std::endl;break;
|
|
||||||
case call_vector_wrong_comma:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a scalar after \',\' but get \']\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case call_vector_lack_bracket:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \']\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case call_vector_wrong_token:
|
|
||||||
std::cout<<error_info_head<<line<<": expect \':\' or ',' or ']' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vector_gen_lack_end:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' or \')\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case hash_gen_lack_id:
|
|
||||||
std::cout<<error_info_head<<line<<": expect an identifier or string here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case hash_gen_lack_colon:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
case hash_gen_lack_end:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \',\' or \'}\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ternary_operator_lack_colon:
|
|
||||||
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
|
||||||
print_parse_token(error_token_type);
|
|
||||||
std::cout<<"\' ."<<std::endl;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum scalar_type
|
enum scalar_type
|
||||||
{
|
{
|
||||||
scalar_nil=0,
|
scalar_nil=0,
|
||||||
|
|
|
@ -12,6 +12,7 @@ class nasal_function
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::list<std::map<std::string,int> > local_scope;
|
std::list<std::map<std::string,int> > local_scope;
|
||||||
|
abstract_syntax_tree parameter_list;
|
||||||
abstract_syntax_tree function_root;
|
abstract_syntax_tree function_root;
|
||||||
// parent_hash_addr is used to store the address of the hash which has this nasal_function
|
// parent_hash_addr is used to store the address of the hash which has this nasal_function
|
||||||
// because nasal_function needs this address to adjust the identifier called 'me' in local_scope
|
// because nasal_function needs this address to adjust the identifier called 'me' in local_scope
|
||||||
|
@ -19,8 +20,10 @@ class nasal_function
|
||||||
public:
|
public:
|
||||||
void set_clear();
|
void set_clear();
|
||||||
void set_local_scope(std::list<std::map<std::string,int> >&);
|
void set_local_scope(std::list<std::map<std::string,int> >&);
|
||||||
|
void set_paramemter_list(abstract_syntax_tree&);
|
||||||
void set_statement_block(abstract_syntax_tree&);
|
void set_statement_block(abstract_syntax_tree&);
|
||||||
std::list<std::map<std::string,int> >& get_local_scope();
|
std::list<std::map<std::string,int> >& get_local_scope();
|
||||||
|
abstract_syntax_tree& get_parameter_list();
|
||||||
abstract_syntax_tree& get_statement_block();
|
abstract_syntax_tree& get_statement_block();
|
||||||
void deep_copy(nasal_function&);
|
void deep_copy(nasal_function&);
|
||||||
};
|
};
|
||||||
|
@ -255,6 +258,11 @@ void nasal_function::set_local_scope(std::list<std::map<std::string,int> >& tmp_
|
||||||
nasal_gc.reference_add(i->second);
|
nasal_gc.reference_add(i->second);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
void nasal_function::set_paramemter_list(abstract_syntax_tree& para_list)
|
||||||
|
{
|
||||||
|
parameter_list=para_list;
|
||||||
|
return;
|
||||||
|
}
|
||||||
void nasal_function::set_statement_block(abstract_syntax_tree& func_block)
|
void nasal_function::set_statement_block(abstract_syntax_tree& func_block)
|
||||||
{
|
{
|
||||||
function_root=func_block;
|
function_root=func_block;
|
||||||
|
@ -264,6 +272,10 @@ std::list<std::map<std::string,int> >& nasal_function::get_local_scope()
|
||||||
{
|
{
|
||||||
return local_scope;
|
return local_scope;
|
||||||
}
|
}
|
||||||
|
abstract_syntax_tree& nasal_function::get_parameter_list()
|
||||||
|
{
|
||||||
|
return parameter_list;
|
||||||
|
}
|
||||||
abstract_syntax_tree& nasal_function::get_statement_block()
|
abstract_syntax_tree& nasal_function::get_statement_block()
|
||||||
{
|
{
|
||||||
return function_root;
|
return function_root;
|
||||||
|
@ -282,6 +294,7 @@ void nasal_function::deep_copy(nasal_function& tmp)
|
||||||
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
for(std::map<std::string,int>::iterator i=iter->begin();i!=iter->end();++i)
|
||||||
nasal_gc.reference_add(i->second);
|
nasal_gc.reference_add(i->second);
|
||||||
// copy abstract_syntax_tree
|
// copy abstract_syntax_tree
|
||||||
|
parameter_list=tmp.parameter_list;
|
||||||
function_root=tmp.function_root;
|
function_root=tmp.function_root;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +355,11 @@ void nasal_vector::vec_push(int addr)
|
||||||
}
|
}
|
||||||
int nasal_vector::get_elem(int addr)
|
int nasal_vector::get_elem(int addr)
|
||||||
{
|
{
|
||||||
if(0<=addr && addr<nas_array.size())
|
// 0 ~ size-1 -size ~ -1
|
||||||
|
int bound=nas_array.size();
|
||||||
|
if(-bound<=addr && addr<0)
|
||||||
|
return nas_array[bound+addr];
|
||||||
|
else if(0<=addr && addr<bound)
|
||||||
return nas_array[addr];
|
return nas_array[addr];
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,27 +7,64 @@ class nasal_parse
|
||||||
std::stack<token> parse_token_stream;
|
std::stack<token> parse_token_stream;
|
||||||
std::stack<token> checked_tokens;
|
std::stack<token> checked_tokens;
|
||||||
token this_token;
|
token this_token;
|
||||||
int error;
|
int error;
|
||||||
abstract_syntax_tree root;
|
abstract_syntax_tree root;
|
||||||
|
enum parse_error_type
|
||||||
|
{
|
||||||
|
parse_unknown_error=0, // unknown error
|
||||||
|
error_token_in_main, // when a token should not be the begin of a statement in main
|
||||||
|
error_token_in_block, // when a token should not be the begin of a statement in block
|
||||||
|
|
||||||
|
lack_semi,
|
||||||
|
lack_id,
|
||||||
|
lack_left_curve,
|
||||||
|
lack_right_curve,
|
||||||
|
lack_right_brace,
|
||||||
|
|
||||||
|
definition_lack_id, // lack identifier
|
||||||
|
definition_lack_equal, // lack '=' when not getting ';'
|
||||||
|
assignment_begin_error, // assignment begins with more than one identifier_call
|
||||||
|
multi_definition_need_curve, // lack right curve when generating 'var (id,id,id)'
|
||||||
|
|
||||||
|
multi_assignment_need_curve, // lack right curve when generating (scalar,scalar)=(scalar,scalar)
|
||||||
|
multi_assignment_need_equal, // lack '=' when generating (scalar,scalar)=(scalar,scalar)
|
||||||
|
|
||||||
|
error_begin_token_of_scalar, // in scalar_generate()
|
||||||
|
|
||||||
|
default_dynamic_parameter, // default parameter should not be dynamic
|
||||||
|
parameter_lack_part, // parameter lack a ')' or identifier
|
||||||
|
parameter_lack_curve, // parameter lack a ',' or ')'
|
||||||
|
|
||||||
|
special_call_func_lack_id,
|
||||||
|
special_call_func_lack_colon,
|
||||||
|
call_func_lack_comma, // lack comma when giving parameters to a function
|
||||||
|
call_hash_lack_id, // lack identifier when calling a hash
|
||||||
|
call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here)
|
||||||
|
call_vector_lack_bracket, // lack ']' when calling a vector
|
||||||
|
call_vector_wrong_token, // get wrong token when calling a vector
|
||||||
|
|
||||||
|
vector_gen_lack_end, // lack ',' or ')' when generating a vector
|
||||||
|
hash_gen_lack_id, // lack identifier or string when generating a hash
|
||||||
|
hash_gen_lack_colon, // lack ':' when generating a hash
|
||||||
|
hash_gen_lack_end, // lack ',' or '}' when generating a hash
|
||||||
|
|
||||||
|
ternary_operator_lack_colon, // lack ':'
|
||||||
|
};
|
||||||
|
void print_parse_error(int,int,int);
|
||||||
// most important function of parser
|
// most important function of parser
|
||||||
// these two functions are used to get and push token
|
// these two functions are used to get and push token
|
||||||
// by using them,parser can generate ast
|
// by using them,parser can generate ast
|
||||||
void get_token();
|
void get_token();
|
||||||
void push_token();
|
void push_token();
|
||||||
|
|
||||||
// block statements generation
|
// block statements generation
|
||||||
abstract_syntax_tree block_generate();
|
abstract_syntax_tree block_generate();
|
||||||
|
|
||||||
// check ';'
|
// check ';'
|
||||||
void check_semi();
|
void check_semi();
|
||||||
|
|
||||||
// check '(' confliction
|
// check '(' confliction
|
||||||
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
bool check_multi_assignment();// check multi_call_id '=' multi_scalar
|
||||||
bool check_multi_scalar(); // check multi_scalar
|
bool check_multi_scalar(); // check multi_scalar
|
||||||
bool check_var_in_curve(); // check multi_definition: (var id,id,id)
|
bool check_var_in_curve(); // check multi_definition: (var id,id,id)
|
||||||
bool check_function_end(abstract_syntax_tree&); // check end of definition or '=' is a function
|
bool check_function_end(abstract_syntax_tree&); // check end of definition or '=' is a function
|
||||||
|
|
||||||
/*
|
/*
|
||||||
calculation() will get elements generated by and_calculation()
|
calculation() will get elements generated by and_calculation()
|
||||||
and_calculation() will get elements generated by or_calculation()
|
and_calculation() will get elements generated by or_calculation()
|
||||||
|
@ -48,14 +85,13 @@ class nasal_parse
|
||||||
abstract_syntax_tree additive_calculation();
|
abstract_syntax_tree additive_calculation();
|
||||||
abstract_syntax_tree multive_calculation();
|
abstract_syntax_tree multive_calculation();
|
||||||
abstract_syntax_tree scalar_generate();
|
abstract_syntax_tree scalar_generate();
|
||||||
|
|
||||||
// normal data type generation
|
// normal data type generation
|
||||||
abstract_syntax_tree hash_generate();
|
abstract_syntax_tree hash_generate();
|
||||||
abstract_syntax_tree vector_generate();
|
abstract_syntax_tree vector_generate();
|
||||||
abstract_syntax_tree function_generate();
|
abstract_syntax_tree function_generate();
|
||||||
|
|
||||||
// return_expr() generates ebnf: <return> [<calculation>] ';'
|
// return_expr() generates ebnf: <return> [<calculation>] ';'
|
||||||
abstract_syntax_tree return_expr();
|
abstract_syntax_tree return_expr();
|
||||||
|
// normal expressions
|
||||||
abstract_syntax_tree multi_scalar_assignment();
|
abstract_syntax_tree multi_scalar_assignment();
|
||||||
abstract_syntax_tree definition();
|
abstract_syntax_tree definition();
|
||||||
abstract_syntax_tree loop_expr();
|
abstract_syntax_tree loop_expr();
|
||||||
|
@ -74,9 +110,8 @@ class nasal_parse
|
||||||
}
|
}
|
||||||
void print_detail_token();
|
void print_detail_token();
|
||||||
void get_token_list(std::list<token>&);
|
void get_token_list(std::list<token>&);
|
||||||
int get_error();
|
int get_error();
|
||||||
abstract_syntax_tree& get_root();
|
abstract_syntax_tree& get_root();
|
||||||
|
|
||||||
// abstract_syntax_tree generation
|
// abstract_syntax_tree generation
|
||||||
// main process of parser
|
// main process of parser
|
||||||
void main_generate();
|
void main_generate();
|
||||||
|
@ -114,6 +149,8 @@ void nasal_parse::print_detail_token()
|
||||||
|
|
||||||
void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||||
{
|
{
|
||||||
|
// get detail_token_stream from lexer
|
||||||
|
// clear the parse_token_stream and checked_tokens list
|
||||||
while(!parse_token_stream.empty())
|
while(!parse_token_stream.empty())
|
||||||
parse_token_stream.pop();
|
parse_token_stream.pop();
|
||||||
while(!checked_tokens.empty())
|
while(!checked_tokens.empty())
|
||||||
|
@ -142,6 +179,130 @@ void nasal_parse::get_token_list(std::list<token>& detail_token_stream)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nasal_parse::print_parse_error(int error_type,int line,int error_token_type=__stack_end)
|
||||||
|
{
|
||||||
|
std::string error_info_head=">> [Parse] line ";
|
||||||
|
switch(error_type)
|
||||||
|
{
|
||||||
|
case parse_unknown_error:
|
||||||
|
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<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 error_token_in_block:
|
||||||
|
std::cout<<error_info_head<<line<<": statements should not begin with \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' in block scope."<<std::endl;
|
||||||
|
break;
|
||||||
|
case lack_semi:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \';\' at the end of the statement."<<std::endl;break;
|
||||||
|
case lack_id:
|
||||||
|
std::cout<<error_info_head<<line<<": expect an identifier here."<<std::endl;break;
|
||||||
|
case lack_left_curve:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \'(\' here."<<std::endl;break;
|
||||||
|
case lack_right_curve:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \')\' here."<<std::endl;break;
|
||||||
|
case lack_right_brace:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \'}\' here."<<std::endl;break;
|
||||||
|
case definition_lack_id:
|
||||||
|
std::cout<<error_info_head<<line<<": expect identifier(s) after \'var\'."<<std::endl;break;
|
||||||
|
case definition_lack_equal:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' when generating definition."<<std::endl;
|
||||||
|
break;
|
||||||
|
case assignment_begin_error:
|
||||||
|
std::cout<<error_info_head<<line<<": assignment should begin with one identifier_call."<<std::endl;
|
||||||
|
break;
|
||||||
|
case multi_definition_need_curve:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case multi_assignment_need_curve:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \')\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case multi_assignment_need_equal:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \'=\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case error_begin_token_of_scalar:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a scalar here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case default_dynamic_parameter:
|
||||||
|
std::cout<<error_info_head<<line<<": dynamic parameter should not have a default value."<<std::endl;break;
|
||||||
|
case parameter_lack_part:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \')\' or identifier here when generating parameter_list."<<std::endl;break;
|
||||||
|
case parameter_lack_curve:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \')\' or \',\' here when generating parameter_list."<<std::endl;break;
|
||||||
|
case special_call_func_lack_id:
|
||||||
|
std::cout<<error_info_head<<line<<": expect an identifier here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' when calling functions."<<std::endl;
|
||||||
|
break;
|
||||||
|
case special_call_func_lack_colon:
|
||||||
|
std::cout<<error_info_head<<line<<": expect an \':\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' when calling functions."<<std::endl;
|
||||||
|
break;
|
||||||
|
case call_func_lack_comma:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \',\' when calling a function but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case call_hash_lack_id:
|
||||||
|
std::cout<<error_info_head<<line<<": expect an identifier after \'.\' ."<<std::endl;break;
|
||||||
|
case call_vector_wrong_comma:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a scalar after \',\' but get \']\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case call_vector_lack_bracket:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \']\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case call_vector_wrong_token:
|
||||||
|
std::cout<<error_info_head<<line<<": expect \':\' or ',' or ']' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case vector_gen_lack_end:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \',\' or \')\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case hash_gen_lack_id:
|
||||||
|
std::cout<<error_info_head<<line<<": expect an identifier or string here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case hash_gen_lack_colon:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case hash_gen_lack_end:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \',\' or \'}\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
case ternary_operator_lack_colon:
|
||||||
|
std::cout<<error_info_head<<line<<": expect a \':\' here but get \'";
|
||||||
|
print_parse_token(error_token_type);
|
||||||
|
std::cout<<"\' ."<<std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout<<error_info_head<<line<<": unknown parse error.(token id: "<<error_token_type<<")."<<std::endl;break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void nasal_parse::get_token()
|
void nasal_parse::get_token()
|
||||||
{
|
{
|
||||||
if(!parse_token_stream.empty())
|
if(!parse_token_stream.empty())
|
||||||
|
|
|
@ -41,7 +41,7 @@ class nasal_runtime
|
||||||
void definition (std::list<std::map<std::string,int> >&,std::map<std::string,int>&,abstract_syntax_tree&);
|
void definition (std::list<std::map<std::string,int> >&,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&);
|
||||||
int func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&);
|
int func_proc (std::list<std::map<std::string,int> >&,abstract_syntax_tree&,abstract_syntax_tree&);
|
||||||
public:
|
public:
|
||||||
nasal_runtime()
|
nasal_runtime()
|
||||||
{
|
{
|
||||||
|
@ -203,11 +203,18 @@ int nasal_runtime::function_generation(std::list<std::map<std::string,int> >& lo
|
||||||
nasal_gc.get_scalar(addr).set_type(scalar_function);
|
nasal_gc.get_scalar(addr).set_type(scalar_function);
|
||||||
nasal_gc.get_scalar(addr).get_function().set_local_scope(local_scope);
|
nasal_gc.get_scalar(addr).get_function().set_local_scope(local_scope);
|
||||||
// function
|
// function
|
||||||
// parameters
|
// parameters
|
||||||
// block
|
// block
|
||||||
// calls...
|
// calls...
|
||||||
std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();
|
std::list<abstract_syntax_tree>::iterator i=node.get_children().begin();
|
||||||
|
nasal_gc.get_scalar(addr).get_function().set_paramemter_list(*i);
|
||||||
|
++i;
|
||||||
|
nasal_gc.get_scalar(addr).get_function().set_statement_block(*i);
|
||||||
|
++i;
|
||||||
|
for(;i!=node.get_children().end();++i)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
int nasal_runtime::calculation(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
||||||
|
@ -1114,6 +1121,7 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
}
|
}
|
||||||
else if(called_type==scalar_hash)
|
else if(called_type==scalar_hash)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
if(nasal_gc.get_scalar(data_addr).get_type()!=scalar_string)
|
||||||
{
|
{
|
||||||
error_interrupt(__error_value_type,iter->get_node_line());
|
error_interrupt(__error_value_type,iter->get_node_line());
|
||||||
|
@ -1351,7 +1359,7 @@ void nasal_runtime::conditional(std::list<std::map<std::string,int> >& local_sco
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& func_root)
|
int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& parameter_list,abstract_syntax_tree& func_root)
|
||||||
{
|
{
|
||||||
if(func_root.get_node_type()!=__function)
|
if(func_root.get_node_type()!=__function)
|
||||||
{
|
{
|
||||||
|
@ -1361,12 +1369,12 @@ int nasal_runtime::func_proc(std::list<std::map<std::string,int> >& local_scope,
|
||||||
std::map<std::string,int> new_scope;
|
std::map<std::string,int> new_scope;
|
||||||
local_scope.push_back(new_scope);
|
local_scope.push_back(new_scope);
|
||||||
// loading parameters
|
// loading parameters
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=func_root.get_children().front().get_children().begin();iter!=func_root.get_children().front().get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=parameter_list.get_children().begin();iter!=parameter_list.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
// process
|
// process
|
||||||
for(std::list<abstract_syntax_tree>::iterator iter=func_root.get_children().back().get_children().begin();iter!=func_root.get_children().back().get_children().end();++iter)
|
for(std::list<abstract_syntax_tree>::iterator iter=func_root.get_children().begin();iter!=func_root.get_children().end();++iter)
|
||||||
{
|
{
|
||||||
// use local value node_type to avoid calling function too many times.
|
// use local value node_type to avoid calling function too many times.
|
||||||
int node_type=iter->get_node_type();
|
int node_type=iter->get_node_type();
|
||||||
|
|
Loading…
Reference in New Issue