update & bug fixed

This commit is contained in:
Valk Richard Li 2021-01-05 23:17:32 +08:00
parent b862aa91eb
commit 9474ac9ef0
6 changed files with 72 additions and 173 deletions

View File

@ -12,7 +12,6 @@ void help()
std::cout<<">> [\"file\"] input a file name.\n";
std::cout<<">> [help ] show help.\n";
std::cout<<">> [clear ] clear the screen.\n";
std::cout<<">> [del ] clear the input filename.\n";
std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
std::cout<<">> [code ] show byte code.\n";
@ -32,15 +31,6 @@ void logo()
return;
}
void del_func()
{
lexer.clear();
parse.clear();
inputfile="null";
std::cout<<">> [Delete] complete.\n";
return;
}
void die(std::string stage,std::string filename)
{
std::cout<<">> ["<<stage<<"] in <\""<<filename<<"\">: error(s) occurred,stop.\n";
@ -169,8 +159,6 @@ int main()
system("clear");
#endif
}
else if(command=="del")
del_func();
else if(command=="lex")
lex_func();
else if(command=="ast")

View File

@ -136,8 +136,6 @@ void nasal_bytecode_vm::die(std::string str)
}
bool nasal_bytecode_vm::check_condition(nasal_scalar* value_addr)
{
if(!value_addr)
return false;
int type=value_addr->get_type();
if(type==vm_number)
return (value_addr->get_number()!=0);
@ -918,8 +916,8 @@ void nasal_bytecode_vm::opr_slicebegin()
}
void nasal_bytecode_vm::opr_sliceend()
{
vm.del_reference(*value_stack_top--);
*(++value_stack_top)=slice_stack.top();
vm.del_reference(*value_stack_top);
*value_stack_top=slice_stack.top();
slice_stack.pop();
return;
}

View File

@ -111,13 +111,7 @@ struct opcode
{
unsigned char op;
unsigned int index;
opcode()
{
op=op_nop;
index=0;
return;
}
opcode(unsigned char _op,unsigned int _index)
opcode(unsigned char _op=op_nop,unsigned int _index=0)
{
op=_op;
index=_index;
@ -327,12 +321,12 @@ void nasal_codegen::call_gen(nasal_ast& ast)
for(int i=1;i<child_size;++i)
{
nasal_ast& tmp=ast.get_children()[i];
if(tmp.get_type()==ast_call_hash)
call_hash(tmp);
else if(tmp.get_type()==ast_call_vec)
call_vec(tmp);
else if(tmp.get_type()==ast_call_func)
call_func(tmp);
switch(tmp.get_type())
{
case ast_call_hash:call_hash(tmp);break;
case ast_call_vec: call_vec(tmp); break;
case ast_call_func:call_func(tmp);break;
}
}
return;
}
@ -391,37 +385,12 @@ void nasal_codegen::call_vec(nasal_ast& ast)
void nasal_codegen::call_func(nasal_ast& ast)
{
if(!ast.get_children().size())
{
gen(op_newvec,0);
gen(op_callf,0);
return;
}
if(ast.get_children()[0].get_type()==ast_hashmember)
{
gen(op_newhash,0);
int size=ast.get_children().size();
for(int i=0;i<size;++i)
{
nasal_ast& tmp=ast.get_children()[i];
calculation_gen(tmp.get_children()[1]);
std::string str=tmp.get_children()[0].get_str();
regist_string(str);
gen(op_hashapp,string_table[str]);
}
gen(op_callf,0);
}
else if(ast.get_children()[0].get_type()==ast_hashmember)
hash_gen(ast);
else
{
gen(op_newvec,0);
int size=ast.get_children().size();
for(int i=0;i<size;++i)
{
nasal_ast& tmp=ast.get_children()[i];
calculation_gen(tmp);
gen(op_vecapp,0);
}
gen(op_callf,0);
}
vector_gen(ast);
gen(op_callf,0);
return;
}
@ -570,6 +539,9 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
void nasal_codegen::loop_gen(nasal_ast& ast)
{
std::vector<int> new_level;
continue_ptr.push_front(new_level);
break_ptr.push_front(new_level);
switch(ast.get_type())
{
case ast_while: while_gen(ast); break;
@ -598,10 +570,6 @@ void nasal_codegen::while_gen(nasal_ast& ast)
int condition_ptr=exec_code.size();
gen(op_jmpfalse,0);
std::vector<int> new_continue_ptr;
std::vector<int> new_break_ptr;
continue_ptr.push_front(new_continue_ptr);
break_ptr.push_front(new_break_ptr);
block_gen(ast.get_children()[1]);
gen(op_jmp,loop_ptr);
exec_code[condition_ptr].index=exec_code.size();
@ -634,10 +602,6 @@ void nasal_codegen::for_gen(nasal_ast& ast)
int label_exit=exec_code.size();
gen(op_jmpfalse,0);
std::vector<int> new_continue_ptr;
std::vector<int> new_break_ptr;
continue_ptr.push_front(new_continue_ptr);
break_ptr.push_front(new_break_ptr);
block_gen(ast.get_children()[3]);
int continue_place=exec_code.size();
switch(ast.get_children()[2].get_type())
@ -678,10 +642,7 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
gen(op_meq,0);
pop_gen();
}
std::vector<int> new_continue_ptr;
std::vector<int> new_break_ptr;
continue_ptr.push_front(new_continue_ptr);
break_ptr.push_front(new_break_ptr);
block_gen(ast.get_children()[2]);
gen(op_jmp,ptr);
exec_code[ptr].index=exec_code.size();
@ -708,10 +669,7 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
gen(op_meq,0);
pop_gen();
}
std::vector<int> new_continue_ptr;
std::vector<int> new_break_ptr;
continue_ptr.push_front(new_continue_ptr);
break_ptr.push_front(new_break_ptr);
block_gen(ast.get_children()[2]);
gen(op_jmp,ptr);
exec_code[ptr].index=exec_code.size();
@ -723,21 +681,13 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
void nasal_codegen::or_gen(nasal_ast& ast)
{
// a
// jt l1
// pop
// b
// jt l1
// pop
// pushnil
int l1,l2;
calculation_gen(ast.get_children()[0]);
l1=exec_code.size();
int l1=exec_code.size();
gen(op_jmptrue,0);
pop_gen();
calculation_gen(ast.get_children()[1]);
l2=exec_code.size();
int l2=exec_code.size();
gen(op_jmptrue,0);
pop_gen();
@ -749,26 +699,17 @@ void nasal_codegen::or_gen(nasal_ast& ast)
void nasal_codegen::and_gen(nasal_ast& ast)
{
// a
// jt l1
// jmp lfalse
// l1:pop
// b
// jt l2
// lfalse:pop
// pushnil
// l2:
calculation_gen(ast.get_children()[0]);
gen(op_jmptrue,exec_code.size()+2);
int ptr=exec_code.size();
int lfalse=exec_code.size();
gen(op_jmp,0);
pop_gen();// jt jumps here
calculation_gen(ast.get_children()[1]);
gen(op_jmptrue,exec_code.size()+3);
exec_code[ptr].index=exec_code.size();
exec_code[lfalse].index=exec_code.size();
pop_gen();
nil_gen();
//jt jumps here
@ -778,14 +719,14 @@ void nasal_codegen::and_gen(nasal_ast& ast)
void nasal_codegen::trino_gen(nasal_ast& ast)
{
calculation_gen(ast.get_children()[0]);
int ptr=exec_code.size();
int lfalse=exec_code.size();
gen(op_jmpfalse,0);
calculation_gen(ast.get_children()[1]);
int ptr_exit=exec_code.size();
int lexit=exec_code.size();
gen(op_jmp,0);
exec_code[ptr].index=exec_code.size();
exec_code[lfalse].index=exec_code.size();
calculation_gen(ast.get_children()[2]);
exec_code[ptr_exit].index=exec_code.size();
exec_code[lexit].index=exec_code.size();
return;
}
@ -793,14 +734,14 @@ void nasal_codegen::calculation_gen(nasal_ast& ast)
{
switch(ast.get_type())
{
case ast_nil:nil_gen();break;
case ast_number:number_gen(ast);break;
case ast_string:string_gen(ast);break;
case ast_identifier:call_id(ast);break;
case ast_vector:vector_gen(ast);break;
case ast_hash:hash_gen(ast);break;
case ast_function:function_gen(ast);break;
case ast_call:call_gen(ast);break;
case ast_nil: nil_gen(); break;
case ast_number: number_gen(ast); break;
case ast_string: string_gen(ast); break;
case ast_identifier: call_id(ast); break;
case ast_vector: vector_gen(ast); break;
case ast_hash: hash_gen(ast); break;
case ast_function: function_gen(ast); break;
case ast_call: call_gen(ast); break;
case ast_equal:
calculation_gen(ast.get_children()[1]);
mem_call(ast.get_children()[0]);
@ -918,11 +859,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
nasal_ast& tmp=ast.get_children()[i];
switch(tmp.get_type())
{
case ast_null:
case ast_nil:
case ast_number:
case ast_string:
case ast_function:break;
case ast_null:case ast_nil:case ast_number:case ast_string:case ast_function:break;
case ast_definition:definition_gen(tmp);break;
case ast_multi_assign:multi_assignment_gen(tmp);break;
case ast_conditional:conditional_gen(tmp);break;

View File

@ -77,8 +77,6 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
{
// initializing
nasal_ast tmp(0,ast_root);
import_lex.clear();
import_par.clear();
// get filename and set node to ast_null
std::string filename=node.get_children()[1].get_children()[0].get_str();

View File

@ -106,7 +106,6 @@ private:
std::string number_gen();
std::string string_gen();
public:
void clear();
void openfile(std::string);
void die(std::string,int,int);
void scanner();
@ -115,15 +114,6 @@ public:
std::vector<token>& get_token_list();
};
void nasal_lexer::clear()
{
error=res_size=line=ptr=0;
line_code="";
res.clear();
token_list.clear();
return;
}
void nasal_lexer::openfile(std::string filename)
{
error=0;

View File

@ -55,6 +55,7 @@ private:
bool check_function_end(nasal_ast&);
bool check_special_call();
bool need_semi_check(nasal_ast&);
void check_memory_reachable(nasal_ast&);
nasal_ast null_node_gen();
nasal_ast nil_gen();
nasal_ast number_gen();
@ -97,7 +98,6 @@ private:
nasal_ast return_expr();
public:
int get_error();
void clear();
void set_toklist(std::vector<token>&);
void main_process();
nasal_ast& get_root();
@ -108,14 +108,6 @@ int nasal_parse::get_error()
return error;
}
void nasal_parse::clear()
{
tok_list_size=ptr=error=in_function=in_loop=0;
tok_list.clear();
root.clear();
return;
}
void nasal_parse::set_toklist(std::vector<token>& lex_token)
{
tok_list=lex_token;
@ -262,6 +254,27 @@ bool nasal_parse::need_semi_check(nasal_ast& node)
return !check_function_end(node);
}
void nasal_parse::check_memory_reachable(nasal_ast& node)
{
if(node.get_type()==ast_call)
{
if(node.get_children()[0].get_type()!=ast_identifier)
die(node.get_line(),"cannot get the memory of a temporary data");
int size=node.get_children().size();
for(int i=0;i<size;++i)
{
nasal_ast& tmp_node=node.get_children()[i];
if(tmp_node.get_type()==ast_call_func)
die(tmp_node.get_line(),"cannot get the memory of function-returned value");
if(tmp_node.get_type()==ast_call_vec && (tmp_node.get_children().size()>1 || tmp_node.get_children()[0].get_type()==ast_subvec))
die(tmp_node.get_line(),"cannot get the memory in temporary sliced vector");
}
}
else if(node.get_type()!=ast_identifier)
die(node.get_line(),"cannot use calculation as the memory of scalar");
return;
}
nasal_ast nasal_parse::null_node_gen()
{
nasal_ast node(tok_list[ptr].line,ast_null);
@ -561,8 +574,7 @@ nasal_ast nasal_parse::calculation()
tmp.add_child(node);
++ptr;
tmp.add_child(calculation());
++ptr;
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
if(++ptr>=tok_list_size || tok_list[ptr].type!=tok_colon)
{
die(error_line,"expected \":\"");
return node;
@ -574,27 +586,7 @@ nasal_ast nasal_parse::calculation()
else if(ptr<tok_list_size && tok_equal<=tok_list[ptr].type && tok_list[ptr].type<=tok_link_equal)
{
// check the left expression to confirm it is available to get memory
if(node.get_type()!=ast_call && node.get_type()!=ast_identifier)
die(node.get_line(),"cannot use calculation as the memory of scalar");
if(node.get_type()==ast_call)
{
if(node.get_children()[0].get_type()!=ast_identifier)
die(node.get_children()[0].get_line(),"cannot get the memory of temporary value");
int size=node.get_children().size();
for(int i=0;i<size;++i)
{
nasal_ast& tmp_node=node.get_children()[i];
if(tmp_node.get_type()==ast_call_func)
die(tmp_node.get_line(),"cannot get the memory of function-returned value");
if(tmp_node.get_type()==ast_call_vec)
{
if(tmp_node.get_children().size()>1)
die(tmp_node.get_line(),"cannot get the memory in temporary sliced vector");
else if(tmp_node.get_children()[0].get_type()==ast_subvec)
die(tmp_node.get_children()[0].get_line(),"cannot get the memory in temporary sliced vector");
}
}
}
check_memory_reachable(node);
// tok_equal~tok_link_equal is 37 to 42,ast_equal~ast_link_equal is 21~26
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_equal+ast_equal);
tmp.add_child(node);
@ -914,7 +906,12 @@ nasal_ast nasal_parse::definition()
nasal_ast node(tok_list[ptr].line,ast_definition);
if(tok_list[ptr].type==tok_var)
{
switch(tok_list[++ptr].type)
if(++ptr>=tok_list_size)
{
die(error_line,"expected identifier");
return node;
}
switch(tok_list[ptr].type)
{
case tok_identifier:node.add_child(id_gen()); break;
case tok_left_curve:node.add_child(var_outcurve_def()); break;
@ -947,12 +944,8 @@ nasal_ast nasal_parse::definition()
nasal_ast nasal_parse::var_incurve_def()
{
nasal_ast node;
ptr+=2;// check_multi_definition will check the 'var'
if(ptr>=tok_list_size || tok_list[ptr].type!=tok_identifier)
{
die(error_line,"expected identifier");
return node;
}
ptr+=2;
// check_multi_definition will check the 'var',so there's no need to check this again
node=multi_id();
if(++ptr<tok_list_size && is_call(tok_list[ptr].type))
die(error_line,"don\'t call identifier in multi-definition");
@ -963,13 +956,9 @@ nasal_ast nasal_parse::var_incurve_def()
nasal_ast nasal_parse::var_outcurve_def()
{
nasal_ast node;
if(++ptr>=tok_list_size || tok_list[ptr].type!=tok_identifier)
{
die(error_line,"expected identifier");
return node;
}
++ptr;
node=multi_id();
if(++ptr<tok_list_size && (tok_list[ptr].type==tok_dot || tok_list[ptr].type==tok_left_bracket || tok_list[ptr].type==tok_left_curve))
if(++ptr<tok_list_size && is_call(tok_list[ptr].type))
die(error_line,"don\'t call identifier in multi-definition");
else if(ptr>=tok_list_size || tok_list[ptr].type!=tok_right_curve)
die(error_line,"expected \")\"");
@ -1006,9 +995,8 @@ nasal_ast nasal_parse::multi_scalar(bool check_call_memory)
while(ptr<tok_list_size && tok_list[ptr].type!=tok_right_curve)
{
node.add_child(calculation());
int type=node.get_children().back().get_type();
if(check_call_memory && type!=ast_call && type!=ast_identifier)
die(node.get_children().back().get_line(),"cannot use calculation as the memory of scalar");
if(check_call_memory)
check_memory_reachable(node.get_children().back());
if(++ptr>=tok_list_size)
break;
if(tok_list[ptr].type==tok_comma)