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;
}
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::exit(1);
return;
}
void execute(std::string& file,std::string& command)
void execute(const std::string& file,const std::string& command)
{
nasal_lexer lexer;
nasal_parse parse;

View File

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

View File

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

View File

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

View File

@ -277,7 +277,7 @@ struct nasal_gc
std::vector<nasal_ref> local;
void mark();
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();
nasal_ref gc_alloc(int);
nasal_ref builtin_alloc(int);
@ -338,7 +338,7 @@ void nasal_gc::sweep()
}
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 j=0;j<increment[i];++j)

View File

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

View File

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

View File

@ -48,14 +48,15 @@ private:
std::vector<token> error_token;
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
void die(int,std::string&&);
void die(int,const std::string&&);
void die(int,const char*);
void match(int type,const char* err_info="");
bool check_comma(int*);
bool check_comma(const int*);
bool check_multi_scalar();
bool check_function_end(nasal_ast&);
bool check_function_end(const nasal_ast&);
bool check_special_call();
bool need_semi_check(nasal_ast&);
void check_memory_reachable(nasal_ast&);
bool need_semi_check(const nasal_ast&);
void check_memory_reachable(const nasal_ast&);
nasal_ast null_node_gen();
nasal_ast nil_gen();
nasal_ast num_gen();
@ -140,11 +141,15 @@ void nasal_parse::main_process(std::vector<token>& toks)
<<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
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;
std::cout<<"[parse] line "<<line<<": "<<info<<".\n";
return;
}
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;
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)
if(tok_list[ptr].type==panic_set[i])
@ -198,7 +203,7 @@ bool nasal_parse::check_multi_scalar()
}
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();
if(type==ast_func)
@ -246,18 +251,18 @@ bool nasal_parse::check_special_call()
}
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();
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
return false;
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)
{
nasal_ast& tmp=node.get_children().back();
const nasal_ast& tmp=node.get_children().back();
if(tmp.get_type()==ast_callf)
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))
@ -298,7 +303,7 @@ nasal_ast nasal_parse::vec_gen()
// panic set for this token is not ','
// this is the FIRST set of calculation
// 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);
match(tok_lbracket);
while(tok_list[ptr].type!=tok_rbracket)
@ -694,7 +699,7 @@ nasal_ast nasal_parse::callv()
// panic set for this token is not ','
// this is the FIRST set of subvec
// 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);
match(tok_lbracket);
while(tok_list[ptr].type!=tok_rbracket)
@ -715,7 +720,7 @@ nasal_ast nasal_parse::callf()
// panic set for this token is not ','
// this is the FIRST set of calculation/hashmember
// 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);
bool special_call=check_special_call();
match(tok_lcurve);
@ -811,7 +816,7 @@ nasal_ast nasal_parse::multi_id()
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
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);
match(tok_lcurve);
while(tok_list[ptr].type!=tok_rcurve)

View File

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

View File

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