diff --git a/lib.nas b/lib.nas index be3b61e..a850a15 100644 --- a/lib.nas +++ b/lib.nas @@ -287,6 +287,8 @@ var io= fin: func(filename){return __fin(filename);}, # input a string as the content of a file. fout: func(filename,str){return __fout(filename,str);}, + # use C access + exists:func(filename){return __exists(filename);}, # same as C fopen. open file and get the FILE*. open: func(filename,mode="r"){return __open(filename,mode);}, # same as C fclose. close file by FILE*. @@ -378,6 +380,8 @@ var math= { e: 2.7182818284590452354, pi: 3.14159265358979323846264338327950288, + D2R: 2.7182818284590452354/180, + R2D: 180/2.7182818284590452354, inf: 1/0, nan: 0/0, abs: func(x) {return x>0?x:-x; }, @@ -422,7 +426,22 @@ var unix= var dylib= { # open dynamic lib. - dlopen: func(libname){return __dlopen;}, + dlopen: func(libname){ + var envpath=split(os.platform()=="windows"?";":":",unix.getenv("PATH")); + var path=os.platform()=="windows"?["\\","\\module\\"]:["/","/module/"]; + foreach(var p;envpath){ + p=[p~path[0]~libname,p~path[1]~libname]; + if(io.exists(p[0])){ + libname=p[0]; + break; + } + if(io.exists(p[1])){ + libname=p[1]; + break; + } + } + return __dlopen(libname); + }, # load symbol from an open dynamic lib. dlsym: func(lib,sym){return __dlsym; }, # close dynamic lib, this operation will make all the symbols loaded from it invalid. @@ -443,32 +462,10 @@ var os= # runtime gives us some functions that we could manage it manually. var runtime= { - # do garbage collection manually. - # carefully use it because using it frequently may make program running slower. - gc: func(){return __gc;}, - # command line arguments argv: func(){return __sysargv;} }; -# important global constants -var D2R=math.pi/180; -var FPS2KT=0.5925; -var FT2M=0.3048; -var GAL2L=3.7854; -var IN2M=0.0254; -var KG2LB=2.2046; -var KT2FPS=1.6878; -var KT2MPS=0.5144; -var L2GAL=0.2642; -var LB2KG=0.4536; -var M2FT=3.2808; -var M2IN=39.3701; -var M2NM=0.00054; -var MPS2KT=1.9438; -var NM2M=1852; -var R2D=180/math.pi; - # functions that not supported in this runtime: var bind=func(function,locals,outer_scope=nil){ die("this runtime does not support bind"); @@ -496,4 +493,4 @@ var coroutine={ yield: func(args...) {return __coyield; }, status: func(co) {return __costatus;}, running:func() {return __corun; } -}; \ No newline at end of file +}; diff --git a/main.cpp b/main.cpp index 57efd33..203dc05 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,7 @@ const u32 VM_EXEC =0x20; const u32 VM_DBGINFO =0x40; const u32 VM_DEBUG =0x80; const u32 VM_OPTIMIZE =0x100; +const u32 VM_SHOWPATH =0x200; void help() { @@ -38,8 +39,9 @@ void help() <<" -d, --detail | execute and get detail crash info.\n" <<" | get garbage collector info if didn't crash.\n" <<" -op, --optimize| use optimizer(beta).\n" - <<" | if want to use -op and run, please use -op -e/-t/-o/-d.\n" - <<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\n" + <<" | if want to use -op and run, please use -op -e/-t/-d.\n" + <<" -dbg, --debug | debug mode (this will ignore -t -d).\n" + <<" -cp, --chkpath | show path if linker cannot find files.\n" <<"file:\n" <<" input file name to execute script file.\n" <<"argv:\n" @@ -90,7 +92,7 @@ void execute(const string& file,const std::vector& argv,const u32 cmd) // parser gets lexer's token list to compile parse.compile(lexer); // linker gets parser's ast and load import files to this ast - linker.link(parse,file); + linker.link(parse,file,cmd&VM_SHOWPATH); // optimizer does simple optimization on ast if(cmd&VM_OPTIMIZE) optimize(parse.ast()); @@ -145,7 +147,8 @@ int main(int argc,const char* argv[]) {"--time",VM_EXECTIME|VM_EXEC},{"-t",VM_EXECTIME|VM_EXEC}, {"--detail",VM_DBGINFO|VM_EXEC},{"-d",VM_DBGINFO|VM_EXEC}, {"--optimize",VM_OPTIMIZE},{"-op",VM_OPTIMIZE}, - {"--debug",VM_DEBUG},{"-dbg",VM_DEBUG} + {"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}, + {"--chkpath",VM_SHOWPATH|VM_EXEC},{"-cp",VM_SHOWPATH|VM_EXEC} }; u32 cmd=0; string filename; diff --git a/nasal_builtin.h b/nasal_builtin.h index 36094cd..e9d9cc2 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -60,6 +60,7 @@ native(builtin_right); native(builtin_cmp); native(builtin_chr); native(builtin_values); +native(builtin_exists); native(builtin_open); native(builtin_close); native(builtin_read); @@ -89,7 +90,6 @@ native(builtin_dlsym); native(builtin_dlclose); native(builtin_dlcall); native(builtin_platform); -native(builtin_gc); native(builtin_md5); native(builtin_cocreate); native(builtin_coresume); @@ -166,6 +166,7 @@ struct {"__cmp", builtin_cmp }, {"__chr", builtin_chr }, {"__values", builtin_values }, + {"__exists", builtin_exists }, {"__open", builtin_open }, {"__close", builtin_close }, {"__read", builtin_read }, @@ -195,7 +196,6 @@ struct {"__dlclose", builtin_dlclose }, {"__dlcall", builtin_dlcall }, {"__platform",builtin_platform}, - {"__gc", builtin_gc }, {"__md5", builtin_md5 }, {"__cocreate",builtin_cocreate}, {"__coresume",builtin_coresume}, @@ -749,6 +749,12 @@ nas_ref builtin_values(nas_ref* local,nasal_gc& gc) v.push_back(i.second); return vec; } +nas_ref builtin_exists(nas_ref* local,nasal_gc& gc) +{ + if(local[1].type!=vm_str) + return zero; + return access(local[1].str().c_str(),F_OK)!=-1?one:zero; +} void obj_file_dtor(void* ptr) { fclose((FILE*)ptr); @@ -1198,12 +1204,6 @@ nas_ref builtin_platform(nas_ref* local,nasal_gc& gc) #endif return gc.newstr("unknown"); } -nas_ref builtin_gc(nas_ref* local,nasal_gc& gc) -{ - gc.mark(); - gc.sweep(); - return nil; -} // md5 related functions string tohex(u32 num) diff --git a/nasal_codegen.h b/nasal_codegen.h index 4a2b063..49bf78d 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -692,7 +692,7 @@ void nasal_codegen::multi_def(const nasal_ast& ast) if(ast[1].type()==ast_multi_scalar) // (var a,b,c)=(c,b,a); { auto& vals=ast[1].child(); - for(int i=0;i files; @@ -16,12 +17,13 @@ private: bool exist(const string&); void linker(nasal_ast&,nasal_ast&&); string path(const nasal_ast&); + string findf(const string&); nasal_ast fimpt(nasal_ast&); nasal_ast libimpt(); nasal_ast load(nasal_ast&,u16); public: nasal_import(nasal_err&); - void link(nasal_parse&,const string&); + void link(nasal_parse&,const string&,bool); const std::vector& filelist() const {return files;} }; @@ -60,6 +62,38 @@ string nasal_import::path(const nasal_ast& node) return fpath+".nas"; } +string nasal_import::findf(const string& fname) +{ +#ifdef _WIN32 + std::vector filepath={fname,"stl\\"+fname}; +#else + std::vector filepath={fname,"stl/"+fname}; +#endif + for(auto&p:envpath) + { +#ifdef _WIN32 + filepath.push_back(p+"\\"+fname); + filepath.push_back(p+"\\stl\\"+fname); +#else + filepath.push_back(p+"/"+fname); + filepath.push_back(p+"/stl/"+fname); +#endif + } + for(auto& i:filepath) + if(access(i.c_str(),F_OK)!=-1) + return i; + if(!show_path) + { + nerr.err("link","cannot find file <"+fname+">"); + return ""; + } + string paths=""; + for(auto& i:filepath) + paths+=" "+i+"\n"; + nerr.err("link","cannot find file <"+fname+"> in these paths:\n"+paths); + return ""; +} + bool nasal_import::imptchk(const nasal_ast& node) { // only these two kinds of node can be recognized as 'import': @@ -118,13 +152,9 @@ nasal_ast nasal_import::fimpt(nasal_ast& node) node.clear(); // avoid infinite loading loop - if(exist(filename)) + filename=findf(filename); + if(!filename.length() || exist(filename)) return {0,ast_root}; - if(access(filename.c_str(),F_OK)==-1) - { - nerr.err("link","cannot open file <"+filename+">"); - return {0,ast_root}; - } // start importing... lex.scan(filename); @@ -136,42 +166,11 @@ nasal_ast nasal_import::fimpt(nasal_ast& node) nasal_ast nasal_import::libimpt() { -#ifdef _WIN32 -#define nalib ".\\lib.nas" -#define nastllib ".\\stl\\lib.nas" -#define path_nalib "\\lib.nas" -#define path_stllib "\\stl\\lib.nas" -#else -#define nalib "./lib.nas" -#define nastllib "./stl/lib.nas" -#define path_nalib "/lib.nas" -#define path_stllib "/stl/lib.nas" -#endif - std::vector libpath={nalib,nastllib}; - for(auto& p:envpath) - { - libpath.push_back(p+path_nalib); - libpath.push_back(p+path_stllib); - } - nasal_lexer lex(nerr); nasal_parse par(nerr); - string filename=""; - for(auto& i:libpath) - if(access(i.c_str(),F_OK)!=-1) - { - filename=i; - break; - } + string filename=findf("lib.nas"); if(!filename.length()) - { - string paths=""; - for(auto& i:libpath) - paths+=" "+i+"\n"; - nerr.err("link","cannot find lib file in these paths:\n"+paths); - nerr.chkerr(); return {0,ast_root}; - } // avoid infinite loading loop if(exist(filename)) @@ -208,13 +207,15 @@ nasal_ast nasal_import::load(nasal_ast& root,u16 fileindex) return new_root; } -void nasal_import::link(nasal_parse& parse,const string& self) +void nasal_import::link(nasal_parse& parse,const string& self,bool spath=false) { + show_path=spath; // initializing files={self}; // scan root and import files,then generate a new ast and return to import_ast // the main file's index is 0 parse.ast()=load(parse.ast(),0); + nerr.chkerr(); } #endif \ No newline at end of file diff --git a/stl/fg_env.nas b/stl/fg_env.nas index c8168d0..209deb8 100644 --- a/stl/fg_env.nas +++ b/stl/fg_env.nas @@ -10,6 +10,24 @@ println("-------------------------------------------------------------"); println(" See help using command line argument: --fg-env-help"); println("-------------------------------------------------------------"); +# important global constants +var D2R=math.pi/180; +var FPS2KT=0.5925; +var FT2M=0.3048; +var GAL2L=3.7854; +var IN2M=0.0254; +var KG2LB=2.2046; +var KT2FPS=1.6878; +var KT2MPS=0.5144; +var L2GAL=0.2642; +var LB2KG=0.4536; +var M2FT=3.2808; +var M2IN=39.3701; +var M2NM=0.00054; +var MPS2KT=1.9438; +var NM2M=1852; +var R2D=180/math.pi; + var fg_env_cli={ "--fg-env-help":{ info:"get help", diff --git a/stl/lib.nas b/stl/lib.nas index be3b61e..a850a15 100644 --- a/stl/lib.nas +++ b/stl/lib.nas @@ -287,6 +287,8 @@ var io= fin: func(filename){return __fin(filename);}, # input a string as the content of a file. fout: func(filename,str){return __fout(filename,str);}, + # use C access + exists:func(filename){return __exists(filename);}, # same as C fopen. open file and get the FILE*. open: func(filename,mode="r"){return __open(filename,mode);}, # same as C fclose. close file by FILE*. @@ -378,6 +380,8 @@ var math= { e: 2.7182818284590452354, pi: 3.14159265358979323846264338327950288, + D2R: 2.7182818284590452354/180, + R2D: 180/2.7182818284590452354, inf: 1/0, nan: 0/0, abs: func(x) {return x>0?x:-x; }, @@ -422,7 +426,22 @@ var unix= var dylib= { # open dynamic lib. - dlopen: func(libname){return __dlopen;}, + dlopen: func(libname){ + var envpath=split(os.platform()=="windows"?";":":",unix.getenv("PATH")); + var path=os.platform()=="windows"?["\\","\\module\\"]:["/","/module/"]; + foreach(var p;envpath){ + p=[p~path[0]~libname,p~path[1]~libname]; + if(io.exists(p[0])){ + libname=p[0]; + break; + } + if(io.exists(p[1])){ + libname=p[1]; + break; + } + } + return __dlopen(libname); + }, # load symbol from an open dynamic lib. dlsym: func(lib,sym){return __dlsym; }, # close dynamic lib, this operation will make all the symbols loaded from it invalid. @@ -443,32 +462,10 @@ var os= # runtime gives us some functions that we could manage it manually. var runtime= { - # do garbage collection manually. - # carefully use it because using it frequently may make program running slower. - gc: func(){return __gc;}, - # command line arguments argv: func(){return __sysargv;} }; -# important global constants -var D2R=math.pi/180; -var FPS2KT=0.5925; -var FT2M=0.3048; -var GAL2L=3.7854; -var IN2M=0.0254; -var KG2LB=2.2046; -var KT2FPS=1.6878; -var KT2MPS=0.5144; -var L2GAL=0.2642; -var LB2KG=0.4536; -var M2FT=3.2808; -var M2IN=39.3701; -var M2NM=0.00054; -var MPS2KT=1.9438; -var NM2M=1852; -var R2D=180/math.pi; - # functions that not supported in this runtime: var bind=func(function,locals,outer_scope=nil){ die("this runtime does not support bind"); @@ -496,4 +493,4 @@ var coroutine={ yield: func(args...) {return __coyield; }, status: func(co) {return __costatus;}, running:func() {return __corun; } -}; \ No newline at end of file +};