update & bug fixed
This commit is contained in:
parent
b862aa91eb
commit
9474ac9ef0
12
main.cpp
12
main.cpp
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
131
nasal_codegen.h
131
nasal_codegen.h
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue