bad access bug fixed
This commit is contained in:
parent
071d8bd1ce
commit
618ce59233
4
main.cpp
4
main.cpp
|
@ -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;
|
||||
|
|
2
nasal.h
2
nasal.h
|
@ -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)
|
||||
|
|
15
nasal_ast.h
15
nasal_ast.h
|
@ -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<<"| ";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
12
nasal_vm.h
12
nasal_vm.h
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue