diff --git a/README.md b/README.md index caa15b6..07798ec 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,19 @@ But in last summer holiday, members in FGPRC told me that it is hard to debug wi So i tried to write a new interpreter to help them checking syntax error and even, runtime error. -I wrote the lexer, parser and runtime(bytecode virtual machine/ast-runtime virtual machine) to help checking errors. +I wrote the lexer, parser and runtimebytecode virtual machine(there was an ast-interpreter,but i deleted it after version4.0) to help checking errors. -They found it easier for them to check errors before copying nasal-codes in nasal-console in Flightgear to test. +They found it much easier to check syntax and runtime errors before copying nasal-codes in nasal-console in Flightgear to test. + +Also, you could use this language to write some interesting programs and run them without the lib of Flightgear. + +You could add your own built-in functions to change this interpreter to a useful tool in your own projects(such as a script in your own game). # How to Compile -MUST USE -O2 ! +Better choose the latest update of the interpreter. -pragma gcc optimize(2) seems useless when using g++ +MUST USE -O2 ! pragma gcc optimize(2) seems useless when using g++ > g++ -std=c++11 -O2 main.cpp -o main.exe @@ -156,7 +160,7 @@ for(var i=0;i<4000000;i+=1); ## basic value type -nasal has 6 value types.Number,string,vector,hash,function,nil. +Nasal has 6 value types.Number,string,vector,hash,function,nil. Number has 3 formats.Dec,hex and oct; diff --git a/main.cpp b/main.cpp index 170dfb0..068870c 100644 --- a/main.cpp +++ b/main.cpp @@ -115,11 +115,7 @@ int main() { #ifdef _WIN32 system("cls"); -#endif -#ifdef _linux_ - system("clear"); -#endif -#ifdef TARGET_OS_MAC +#else system("clear"); #endif } diff --git a/nasal.ebnf b/nasal.ebnf index ee5a6b9..28e833b 100644 --- a/nasal.ebnf +++ b/nasal.ebnf @@ -68,6 +68,7 @@ scalar::= |hash {call_scalar} |number |string + |nil |'(' calculation ')' {call_scalar} ; call_scalar::= diff --git a/nasal_gc.h b/nasal_gc.h index c6c3a32..20c549f 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -311,32 +311,24 @@ struct nasal_gc std::queue free_list; // gc free list std::vector global; std::list > local; - void mark(); - void sweep(); - void gc_init(std::vector&,std::vector&); - void gc_clear(); - nasal_val* gc_alloc(int); + void mark(); + void sweep(); + void gc_init(std::vector&,std::vector&); + void gc_clear(); + nasal_val* gc_alloc(int); }; /* gc functions */ void nasal_gc::mark() { std::queue bfs; - zero_addr->mark=true; - one_addr->mark=true; - nil_addr->mark=true; for(auto i=global.begin();i!=global.end();++i) bfs.push(*i); - int size=num_addrs.size(); - for(int i=0;ibegin();j!=i->end();++j) bfs.push(*j); - size=slice_stack.size(); - for(int i=0;i& nums,std::vector& strs) zero_addr=new nasal_val(vm_num); // init constant 0 zero_addr->ptr.num=0; - memory.push_back(zero_addr); one_addr=new nasal_val(vm_num); // init constant 1 one_addr->ptr.num=1; - memory.push_back(one_addr); nil_addr=new nasal_val(vm_nil); // init nil - memory.push_back(nil_addr); *val_stack=nil_addr; // the first space will not store any values,but gc checks @@ -425,8 +414,7 @@ void nasal_gc::gc_init(std::vector& nums,std::vector& strs) } void nasal_gc::gc_clear() { - int size=memory.size(); - for(int i=0;iclear(); delete memory[i]; @@ -438,6 +426,9 @@ void nasal_gc::gc_clear() local.clear(); slice_stack.clear(); + delete nil_addr; + delete one_addr; + delete zero_addr; for(int i=0;i=res_size) die(line_code,"get EOF when generating string.",line,line_code.length()); + if(str_begin=='`' && token_str.length()>1) + die(line_code,"\'`\' is used for string that includes one character.",line,line_code.length()); return token_str; } diff --git a/nasal_parse.h b/nasal_parse.h index 1ee6b04..865434f 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -45,11 +45,13 @@ private: int error; nasal_ast root; std::vector tok_list; + std::vector 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 reset(); void die(int,std::string); - void match(int); + void match(int type,std::string err_info=""); + bool check_comma(int*); bool check_multi_def(); bool check_multi_scalar(); bool check_function_end(nasal_ast&); @@ -63,7 +65,7 @@ private: nasal_ast id_gen(); nasal_ast vec_gen(); nasal_ast hash_gen(); - nasal_ast hmem_gen(); // hash member + nasal_ast hmem_gen(); nasal_ast func_gen(); nasal_ast args_gen(); nasal_ast expr(); @@ -102,18 +104,15 @@ public: void main_process(); nasal_ast& get_root(); }; - int nasal_parse::get_error() { return error; } - void nasal_parse::set_toklist(std::vector& toks) { tok_list=toks; return; } - void nasal_parse::main_process() { reset(); @@ -124,52 +123,49 @@ void nasal_parse::main_process() root.add_child(expr()); if(tok_list[ptr].type==tok_semi) match(tok_semi); - else if(need_semi_check(root.get_children().back())) + else if(need_semi_check(root.get_children().back()) && tok_list[ptr].type!=tok_eof) { // the last expression can be recognized without semi - if(tok_list[ptr].type!=tok_eof) - die(error_line,"expected \";\""); + die(error_line,"expected \";\""); } } + if(!error_token.size()) + return; + int sameline=error_token[0].line; + for(int i=0;i> [parse] line "<0.001) +while(error>0.0005) { error=0; for(var i=0;i<4;i+=1)