bad access bug fixed

This commit is contained in:
Li Haokun 2021-09-13 19:55:03 +08:00 committed by GitHub
parent 071d8bd1ce
commit 618ce59233
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 61 deletions

View File

@ -43,14 +43,14 @@ void logo()
return; return;
} }
void die(const char* stage,std::string& filename) void die(const char* stage,const std::string& filename)
{ {
std::cout<<"["<<stage<<"] in <"<<filename<<">: error(s) occurred,stop.\n"; std::cout<<"["<<stage<<"] in <"<<filename<<">: error(s) occurred,stop.\n";
std::exit(1); std::exit(1);
return; return;
} }
void execute(std::string& file,std::string& command) void execute(const std::string& file,const std::string& command)
{ {
nasal_lexer lexer; nasal_lexer lexer;
nasal_parse parse; nasal_parse parse;

View File

@ -108,7 +108,7 @@ double str2num(const char* str)
/* /*
show raw string show raw string
*/ */
void raw_string(std::string& str) void raw_string(const std::string& str)
{ {
for(auto i:str) for(auto i:str)
switch(i) switch(i)

View File

@ -57,18 +57,19 @@ private:
std::vector<nasal_ast> children; std::vector<nasal_ast> children;
public: public:
nasal_ast(){line=0;type=ast_null;} nasal_ast(){line=0;type=ast_null;}
nasal_ast(int l,int t){line=l;type=t;} nasal_ast(const int l,const int t){line=l;type=t;}
nasal_ast(const nasal_ast&); nasal_ast(const nasal_ast&);
nasal_ast(nasal_ast&&); nasal_ast(nasal_ast&&);
nasal_ast& operator=(const nasal_ast&); nasal_ast& operator=(const nasal_ast&);
nasal_ast& operator=(nasal_ast&&); nasal_ast& operator=(nasal_ast&&);
void print_ast(int); void print_ast(const int);
void clear(); void clear();
void add_child(nasal_ast&& ast){children.push_back(std::move(ast));} void add_child(nasal_ast&& ast){children.push_back(std::move(ast));}
void set_line(int l){line=l;} void add_child(const nasal_ast& ast){children.push_back(ast);}
void set_type(int t){type=t;} void set_line(const int l){line=l;}
void set_str(std::string& s){str=s;} void set_type(const int t){type=t;}
void set_num(double n){num=n;} void set_str(const std::string& s){str=s;}
void set_num(const double n){num=n;}
int get_line(){return line;} int get_line(){return line;}
int get_type(){return type;} int get_type(){return type;}
double get_num() {return num;} double get_num() {return num;}
@ -132,7 +133,7 @@ void nasal_ast::clear()
return; return;
} }
void nasal_ast::print_ast(int depth) void nasal_ast::print_ast(const int depth)
{ {
for(int i=0;i<depth;++i) for(int i=0;i<depth;++i)
std::cout<<"| "; std::cout<<"| ";

View File

@ -208,8 +208,8 @@ private:
std::vector<std::string> global; std::vector<std::string> global;
std::list<std::vector<std::string>> local; std::list<std::vector<std::string>> local;
void die(std::string,int); void die(const std::string,const int);
void regist_number(double); void regist_number(const double);
void regist_string(const std::string&); void regist_string(const std::string&);
void find_symbol(const nasal_ast&); void find_symbol(const nasal_ast&);
void add_sym(const std::string&); void add_sym(const std::string&);
@ -249,7 +249,7 @@ private:
void ret_gen(const nasal_ast&); void ret_gen(const nasal_ast&);
public: public:
int get_error(){return error;} int get_error(){return error;}
void main_progress(const nasal_ast&,std::vector<std::string>&); void main_progress(const nasal_ast&,const std::vector<std::string>&);
void print_op(int); void print_op(int);
void print_byte_code(); void print_byte_code();
std::vector<std::string>& get_str_table(){return str_res_table;} std::vector<std::string>& get_str_table(){return str_res_table;}
@ -257,14 +257,14 @@ public:
std::vector<opcode>& get_exec_code(){return exec_code;} std::vector<opcode>& get_exec_code(){return exec_code;}
}; };
void nasal_codegen::die(std::string info,int line) void nasal_codegen::die(const std::string info,const int line)
{ {
++error; ++error;
std::cout<<"[code] <"<<file_name[fileindex]<<"> line "<<line<<": "<<info<<"\n"; std::cout<<"[code] <"<<file_name[fileindex]<<"> line "<<line<<": "<<info<<"\n";
return; return;
} }
void nasal_codegen::regist_number(double num) void nasal_codegen::regist_number(const double num)
{ {
int size=number_table.size(); int size=number_table.size();
if(!number_table.count(num)) if(!number_table.count(num))
@ -740,10 +740,12 @@ void nasal_codegen::conditional_gen(const nasal_ast& ast)
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_jf,0,0); gen(op_jf,0,0);
block_gen(tmp.get_children()[1]); block_gen(tmp.get_children()[1]);
jmp_label.push_back(exec_code.size());
// without 'else' the last condition doesn't need to jmp // without 'else' the last condition doesn't need to jmp
if(&tmp!=&ast.get_children().back()) if(&tmp!=&ast.get_children().back())
{
jmp_label.push_back(exec_code.size());
gen(op_jmp,0,0); gen(op_jmp,0,0);
}
exec_code[ptr].num=exec_code.size(); exec_code[ptr].num=exec_code.size();
} }
else else
@ -1169,7 +1171,7 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
return; return;
} }
void nasal_codegen::main_progress(const nasal_ast& ast,std::vector<std::string>& files) void nasal_codegen::main_progress(const nasal_ast& ast,const std::vector<std::string>& files)
{ {
error=0; error=0;
in_foreach=0; in_foreach=0;

View File

@ -277,7 +277,7 @@ struct nasal_gc
std::vector<nasal_ref> local; std::vector<nasal_ref> local;
void mark(); void mark();
void sweep(); void sweep();
void gc_init(std::vector<double>&,std::vector<std::string>&); void gc_init(const std::vector<double>&,const std::vector<std::string>&);
void gc_clear(); void gc_clear();
nasal_ref gc_alloc(int); nasal_ref gc_alloc(int);
nasal_ref builtin_alloc(int); nasal_ref builtin_alloc(int);
@ -338,7 +338,7 @@ void nasal_gc::sweep()
} }
return; return;
} }
void nasal_gc::gc_init(std::vector<double>& nums,std::vector<std::string>& strs) void nasal_gc::gc_init(const std::vector<double>& nums,const std::vector<std::string>& strs)
{ {
for(int i=vm_num;i<vm_type_size;++i) for(int i=vm_num;i<vm_type_size;++i)
for(int j=0;j<increment[i];++j) for(int j=0;j<increment[i];++j)

View File

@ -9,27 +9,29 @@ private:
nasal_parse import_par; nasal_parse import_par;
nasal_ast import_ast; nasal_ast import_ast;
std::vector<std::string> filename_table; std::vector<std::string> filename_table;
void die(std::string&,const char*); void die(const std::string&,const char*);
bool check_import(nasal_ast&); bool check_import(const nasal_ast&);
bool check_exist(std::string&); bool check_exist(const std::string&);
void linker(nasal_ast&,nasal_ast&&); void linker(nasal_ast&,nasal_ast&&);
nasal_ast file_import(nasal_ast&); nasal_ast file_import(nasal_ast&);
nasal_ast load(nasal_ast&,uint16_t); nasal_ast load(nasal_ast&,uint16_t);
public: public:
int get_error(){return error;} const int get_error(){return error;}
void link(nasal_ast&,std::string&); void link(nasal_ast&,const std::string&);
nasal_ast& get_root(){return import_ast;} const nasal_ast&
std::vector<std::string>& get_file(){return filename_table;} get_root(){return import_ast;}
const std::vector<std::string>&
get_file(){return filename_table;}
}; };
void nasal_import::die(std::string& filename,const char* error_stage) void nasal_import::die(const std::string& filename,const char* error_stage)
{ {
++error; ++error;
std::cout<<"[import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<".\n"; std::cout<<"[import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<".\n";
return; return;
} }
bool nasal_import::check_import(nasal_ast& node) bool nasal_import::check_import(const nasal_ast& node)
{ {
/* /*
only this kind of node can be recognized as 'import': only this kind of node can be recognized as 'import':
@ -40,7 +42,7 @@ only this kind of node can be recognized as 'import':
*/ */
if(node.get_type()!=ast_call) if(node.get_type()!=ast_call)
return false; return false;
std::vector<nasal_ast>& ref_vec=node.get_children(); const std::vector<nasal_ast>& ref_vec=node.get_children();
if(ref_vec.size()!=2) if(ref_vec.size()!=2)
return false; return false;
if(ref_vec[0].get_str()!="import") if(ref_vec[0].get_str()!="import")
@ -52,7 +54,7 @@ only this kind of node can be recognized as 'import':
return true; return true;
} }
bool nasal_import::check_exist(std::string& file) bool nasal_import::check_exist(const std::string& file)
{ {
// avoid importing the same file // avoid importing the same file
for(auto& fname:filename_table) for(auto& fname:filename_table)
@ -116,7 +118,7 @@ nasal_ast nasal_import::load(nasal_ast& root,uint16_t fileindex)
return new_root; return new_root;
} }
void nasal_import::link(nasal_ast& root,std::string& self) void nasal_import::link(nasal_ast& root,const std::string& self)
{ {
// initializing // initializing
error=0; error=0;

View File

@ -34,7 +34,7 @@ enum token_type
struct struct
{ {
const char* str; const char* str;
int tok_type; const int tok_type;
}token_table[]= }token_table[]=
{ {
{"for" ,tok_for }, {"for" ,tok_for },
@ -103,20 +103,20 @@ private:
std::string line_code; std::string line_code;
std::string res; std::string res;
std::vector<token> token_list; std::vector<token> token_list;
int get_tok_type(std::string&); int get_tok_type(const std::string&);
void die(const char*); void die(const char*);
std::string id_gen(); std::string id_gen();
std::string num_gen(); std::string num_gen();
std::string str_gen(); std::string str_gen();
public: public:
void openfile(std::string&); void openfile(const std::string&);
void scanner(); void scanner();
void print_token(); void print_token();
int get_error(){return error;} int get_error(){return error;}
std::vector<token>& get_token_list(){return token_list;} std::vector<token>& get_token_list(){return token_list;}
}; };
void nasal_lexer::openfile(std::string& filename) void nasal_lexer::openfile(const std::string& filename)
{ {
error=0; error=0;
res.clear(); res.clear();
@ -137,7 +137,7 @@ void nasal_lexer::openfile(std::string& filename)
return; return;
} }
int nasal_lexer::get_tok_type(std::string& tk_str) int nasal_lexer::get_tok_type(const std::string& tk_str)
{ {
for(int i=0;token_table[i].str;++i) for(int i=0;token_table[i].str;++i)
if(tk_str==token_table[i].str) if(tk_str==token_table[i].str)

View File

@ -48,14 +48,15 @@ private:
std::vector<token> error_token; std::vector<token> error_token;
int in_function; // count when generating function block,used to check return-expression int in_function; // count when generating function block,used to check return-expression
int in_loop; // count when generating loop block,used to check break/continue-expression int in_loop; // count when generating loop block,used to check break/continue-expression
void die(int,std::string&&); void die(int,const std::string&&);
void die(int,const char*);
void match(int type,const char* err_info=""); void match(int type,const char* err_info="");
bool check_comma(int*); bool check_comma(const int*);
bool check_multi_scalar(); bool check_multi_scalar();
bool check_function_end(nasal_ast&); bool check_function_end(const nasal_ast&);
bool check_special_call(); bool check_special_call();
bool need_semi_check(nasal_ast&); bool need_semi_check(const nasal_ast&);
void check_memory_reachable(nasal_ast&); void check_memory_reachable(const nasal_ast&);
nasal_ast null_node_gen(); nasal_ast null_node_gen();
nasal_ast nil_gen(); nasal_ast nil_gen();
nasal_ast num_gen(); nasal_ast num_gen();
@ -140,11 +141,15 @@ void nasal_parse::main_process(std::vector<token>& toks)
<<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n"; <<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
return; return;
} }
void nasal_parse::die(int line,std::string&& info) void nasal_parse::die(int line,const std::string&& info)
{
++error;
std::cout<<"[parse] line "<<line<<": "<<info<<".\n";
}
void nasal_parse::die(int line,const char* info)
{ {
++error; ++error;
std::cout<<"[parse] line "<<line<<": "<<info<<".\n"; std::cout<<"[parse] line "<<line<<": "<<info<<".\n";
return;
} }
void nasal_parse::match(int type,const char* err_info) void nasal_parse::match(int type,const char* err_info)
{ {
@ -169,7 +174,7 @@ void nasal_parse::match(int type,const char* err_info)
++ptr; ++ptr;
return; return;
} }
bool nasal_parse::check_comma(int* panic_set) bool nasal_parse::check_comma(const int* panic_set)
{ {
for(int i=0;panic_set[i];++i) for(int i=0;panic_set[i];++i)
if(tok_list[ptr].type==panic_set[i]) if(tok_list[ptr].type==panic_set[i])
@ -198,7 +203,7 @@ bool nasal_parse::check_multi_scalar()
} }
return false; return false;
} }
bool nasal_parse::check_function_end(nasal_ast& node) bool nasal_parse::check_function_end(const nasal_ast& node)
{ {
int type=node.get_type(); int type=node.get_type();
if(type==ast_func) if(type==ast_func)
@ -246,18 +251,18 @@ bool nasal_parse::check_special_call()
} }
return false; return false;
} }
bool nasal_parse::need_semi_check(nasal_ast& node) bool nasal_parse::need_semi_check(const nasal_ast& node)
{ {
int type=node.get_type(); int type=node.get_type();
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional) if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
return false; return false;
return !check_function_end(node); return !check_function_end(node);
} }
void nasal_parse::check_memory_reachable(nasal_ast& node) void nasal_parse::check_memory_reachable(const nasal_ast& node)
{ {
if(node.get_type()==ast_call) if(node.get_type()==ast_call)
{ {
nasal_ast& tmp=node.get_children().back(); const nasal_ast& tmp=node.get_children().back();
if(tmp.get_type()==ast_callf) if(tmp.get_type()==ast_callf)
die(tmp.get_line(),"bad left-value"); die(tmp.get_line(),"bad left-value");
if(tmp.get_type()==ast_callv && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec)) if(tmp.get_type()==ast_callv && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec))
@ -298,7 +303,7 @@ nasal_ast nasal_parse::vec_gen()
// panic set for this token is not ',' // panic set for this token is not ','
// this is the FIRST set of calculation // this is the FIRST set of calculation
// array end with tok_null=0 // array end with tok_null=0
int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null}; const int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null};
nasal_ast node(tok_list[ptr].line,ast_vec); nasal_ast node(tok_list[ptr].line,ast_vec);
match(tok_lbracket); match(tok_lbracket);
while(tok_list[ptr].type!=tok_rbracket) while(tok_list[ptr].type!=tok_rbracket)
@ -694,7 +699,7 @@ nasal_ast nasal_parse::callv()
// panic set for this token is not ',' // panic set for this token is not ','
// this is the FIRST set of subvec // this is the FIRST set of subvec
// array end with tok_null=0 // array end with tok_null=0
int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_colon,tok_null}; const int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_colon,tok_null};
nasal_ast node(tok_list[ptr].line,ast_callv); nasal_ast node(tok_list[ptr].line,ast_callv);
match(tok_lbracket); match(tok_lbracket);
while(tok_list[ptr].type!=tok_rbracket) while(tok_list[ptr].type!=tok_rbracket)
@ -715,7 +720,7 @@ nasal_ast nasal_parse::callf()
// panic set for this token is not ',' // panic set for this token is not ','
// this is the FIRST set of calculation/hashmember // this is the FIRST set of calculation/hashmember
// array end with tok_null=0 // array end with tok_null=0
int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null}; const int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null};
nasal_ast node(tok_list[ptr].line,ast_callf); nasal_ast node(tok_list[ptr].line,ast_callf);
bool special_call=check_special_call(); bool special_call=check_special_call();
match(tok_lcurve); match(tok_lcurve);
@ -811,7 +816,7 @@ nasal_ast nasal_parse::multi_id()
nasal_ast nasal_parse::multi_scalar(bool check_call_memory) nasal_ast nasal_parse::multi_scalar(bool check_call_memory)
{ {
// if check_call_memory is true,we will check if value called here can reach a memory space // if check_call_memory is true,we will check if value called here can reach a memory space
int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null}; const int panic_set[]={tok_id,tok_str,tok_num,tok_not,tok_sub,tok_nil,tok_func,tok_var,tok_lcurve,tok_lbrace,tok_lbracket,tok_null};
nasal_ast node(tok_list[ptr].line,ast_multi_scalar); nasal_ast node(tok_list[ptr].line,ast_multi_scalar);
match(tok_lcurve); match(tok_lcurve);
while(tok_list[ptr].type!=tok_rcurve) while(tok_list[ptr].type!=tok_rcurve)

View File

@ -105,17 +105,17 @@ private:
public: public:
nasal_vm():stack_top(gc.stack_top){}; nasal_vm():stack_top(gc.stack_top){};
void init( void init(
std::vector<std::string>&, const std::vector<std::string>&,
std::vector<double>&, const std::vector<double>&,
std::vector<std::string>&); const std::vector<std::string>&);
void clear(); void clear();
void run(std::vector<opcode>&,bool); void run(std::vector<opcode>&,bool);
}; };
void nasal_vm::init( void nasal_vm::init(
std::vector<std::string>& strs, const std::vector<std::string>& strs,
std::vector<double>& nums, const std::vector<double>& nums,
std::vector<std::string>& filenames) const std::vector<std::string>& filenames)
{ {
gc.gc_init(nums,strs); gc.gc_init(nums,strs);
gc.val_stack[STACK_MAX_DEPTH-1]=nullptr; gc.val_stack[STACK_MAX_DEPTH-1]=nullptr;

View File

@ -14,9 +14,8 @@ var is_prime_sqrt=func(x){
return 1; return 1;
} }
var primes=[2]; var primes=[];
var filter=func(x){ var filter=func(x){
#println(x);
foreach(var i;primes){ foreach(var i;primes){
if(x/i==int(x/i)) if(x/i==int(x/i))
return 0; return 0;
@ -34,7 +33,7 @@ var filter=func(x){
func(){ func(){
var cnt=0; var cnt=0;
for(var i=0;i<50000;i+=1) for(var i=2;i<50000;i+=1)
if(filter(i)) if(filter(i))
cnt+=1; cnt+=1;
println(cnt); println(cnt);