🚀 move fg constants to `stl/fg_env.nas`, add `io.exists`. now dlopen and import can search file in PATH.

This commit is contained in:
ValKmjolnir 2022-07-28 21:44:55 +08:00
parent 33e584ab5c
commit 006ed644e6
7 changed files with 118 additions and 102 deletions

45
lib.nas
View File

@ -287,6 +287,8 @@ var io=
fin: func(filename){return __fin(filename);}, fin: func(filename){return __fin(filename);},
# input a string as the content of a file. # input a string as the content of a file.
fout: func(filename,str){return __fout(filename,str);}, 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*. # same as C fopen. open file and get the FILE*.
open: func(filename,mode="r"){return __open(filename,mode);}, open: func(filename,mode="r"){return __open(filename,mode);},
# same as C fclose. close file by FILE*. # same as C fclose. close file by FILE*.
@ -378,6 +380,8 @@ var math=
{ {
e: 2.7182818284590452354, e: 2.7182818284590452354,
pi: 3.14159265358979323846264338327950288, pi: 3.14159265358979323846264338327950288,
D2R: 2.7182818284590452354/180,
R2D: 180/2.7182818284590452354,
inf: 1/0, inf: 1/0,
nan: 0/0, nan: 0/0,
abs: func(x) {return x>0?x:-x; }, abs: func(x) {return x>0?x:-x; },
@ -422,7 +426,22 @@ var unix=
var dylib= var dylib=
{ {
# open dynamic lib. # 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. # load symbol from an open dynamic lib.
dlsym: func(lib,sym){return __dlsym; }, dlsym: func(lib,sym){return __dlsym; },
# close dynamic lib, this operation will make all the symbols loaded from it invalid. # 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. # runtime gives us some functions that we could manage it manually.
var runtime= 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 # command line arguments
argv: func(){return __sysargv;} 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: # functions that not supported in this runtime:
var bind=func(function,locals,outer_scope=nil){ var bind=func(function,locals,outer_scope=nil){
die("this runtime does not support bind"); die("this runtime does not support bind");
@ -496,4 +493,4 @@ var coroutine={
yield: func(args...) {return __coyield; }, yield: func(args...) {return __coyield; },
status: func(co) {return __costatus;}, status: func(co) {return __costatus;},
running:func() {return __corun; } running:func() {return __corun; }
}; };

View File

@ -9,6 +9,7 @@ const u32 VM_EXEC =0x20;
const u32 VM_DBGINFO =0x40; const u32 VM_DBGINFO =0x40;
const u32 VM_DEBUG =0x80; const u32 VM_DEBUG =0x80;
const u32 VM_OPTIMIZE =0x100; const u32 VM_OPTIMIZE =0x100;
const u32 VM_SHOWPATH =0x200;
void help() void help()
{ {
@ -38,8 +39,9 @@ void help()
<<" -d, --detail | execute and get detail crash info.\n" <<" -d, --detail | execute and get detail crash info.\n"
<<" | get garbage collector info if didn't crash.\n" <<" | get garbage collector info if didn't crash.\n"
<<" -op, --optimize| use optimizer(beta).\n" <<" -op, --optimize| use optimizer(beta).\n"
<<" | if want to use -op and run, please use -op -e/-t/-o/-d.\n" <<" | if want to use -op and run, please use -op -e/-t/-d.\n"
<<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\n" <<" -dbg, --debug | debug mode (this will ignore -t -d).\n"
<<" -cp, --chkpath | show path if linker cannot find files.\n"
<<"file:\n" <<"file:\n"
<<" input file name to execute script file.\n" <<" input file name to execute script file.\n"
<<"argv:\n" <<"argv:\n"
@ -90,7 +92,7 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd)
// parser gets lexer's token list to compile // parser gets lexer's token list to compile
parse.compile(lexer); parse.compile(lexer);
// linker gets parser's ast and load import files to this ast // 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 // optimizer does simple optimization on ast
if(cmd&VM_OPTIMIZE) if(cmd&VM_OPTIMIZE)
optimize(parse.ast()); optimize(parse.ast());
@ -145,7 +147,8 @@ int main(int argc,const char* argv[])
{"--time",VM_EXECTIME|VM_EXEC},{"-t",VM_EXECTIME|VM_EXEC}, {"--time",VM_EXECTIME|VM_EXEC},{"-t",VM_EXECTIME|VM_EXEC},
{"--detail",VM_DBGINFO|VM_EXEC},{"-d",VM_DBGINFO|VM_EXEC}, {"--detail",VM_DBGINFO|VM_EXEC},{"-d",VM_DBGINFO|VM_EXEC},
{"--optimize",VM_OPTIMIZE},{"-op",VM_OPTIMIZE}, {"--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; u32 cmd=0;
string filename; string filename;

View File

@ -60,6 +60,7 @@ native(builtin_right);
native(builtin_cmp); native(builtin_cmp);
native(builtin_chr); native(builtin_chr);
native(builtin_values); native(builtin_values);
native(builtin_exists);
native(builtin_open); native(builtin_open);
native(builtin_close); native(builtin_close);
native(builtin_read); native(builtin_read);
@ -89,7 +90,6 @@ native(builtin_dlsym);
native(builtin_dlclose); native(builtin_dlclose);
native(builtin_dlcall); native(builtin_dlcall);
native(builtin_platform); native(builtin_platform);
native(builtin_gc);
native(builtin_md5); native(builtin_md5);
native(builtin_cocreate); native(builtin_cocreate);
native(builtin_coresume); native(builtin_coresume);
@ -166,6 +166,7 @@ struct
{"__cmp", builtin_cmp }, {"__cmp", builtin_cmp },
{"__chr", builtin_chr }, {"__chr", builtin_chr },
{"__values", builtin_values }, {"__values", builtin_values },
{"__exists", builtin_exists },
{"__open", builtin_open }, {"__open", builtin_open },
{"__close", builtin_close }, {"__close", builtin_close },
{"__read", builtin_read }, {"__read", builtin_read },
@ -195,7 +196,6 @@ struct
{"__dlclose", builtin_dlclose }, {"__dlclose", builtin_dlclose },
{"__dlcall", builtin_dlcall }, {"__dlcall", builtin_dlcall },
{"__platform",builtin_platform}, {"__platform",builtin_platform},
{"__gc", builtin_gc },
{"__md5", builtin_md5 }, {"__md5", builtin_md5 },
{"__cocreate",builtin_cocreate}, {"__cocreate",builtin_cocreate},
{"__coresume",builtin_coresume}, {"__coresume",builtin_coresume},
@ -749,6 +749,12 @@ nas_ref builtin_values(nas_ref* local,nasal_gc& gc)
v.push_back(i.second); v.push_back(i.second);
return vec; 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) void obj_file_dtor(void* ptr)
{ {
fclose((FILE*)ptr); fclose((FILE*)ptr);
@ -1198,12 +1204,6 @@ nas_ref builtin_platform(nas_ref* local,nasal_gc& gc)
#endif #endif
return gc.newstr("unknown"); return gc.newstr("unknown");
} }
nas_ref builtin_gc(nas_ref* local,nasal_gc& gc)
{
gc.mark();
gc.sweep();
return nil;
}
// md5 related functions // md5 related functions
string tohex(u32 num) string tohex(u32 num)

View File

@ -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); if(ast[1].type()==ast_multi_scalar) // (var a,b,c)=(c,b,a);
{ {
auto& vals=ast[1].child(); auto& vals=ast[1].child();
for(int i=0;i<size;++i) for(usize i=0;i<size;++i)
{ {
calc_gen(vals[i]); calc_gen(vals[i]);
const string& str=ids[i].str(); const string& str=ids[i].str();
@ -704,7 +704,7 @@ void nasal_codegen::multi_def(const nasal_ast& ast)
else // (var a,b,c)=[0,1,2]; else // (var a,b,c)=[0,1,2];
{ {
calc_gen(ast[1]); calc_gen(ast[1]);
for(int i=0;i<size;++i) for(usize i=0;i<size;++i)
{ {
gen(op_callvi,i,ast[1].line()); gen(op_callvi,i,ast[1].line());
const string& str=ids[i].str(); const string& str=ids[i].str();

View File

@ -8,6 +8,7 @@
class nasal_import class nasal_import
{ {
private: private:
bool show_path;
bool lib_loaded; bool lib_loaded;
nasal_err& nerr; nasal_err& nerr;
std::vector<string> files; std::vector<string> files;
@ -16,12 +17,13 @@ private:
bool exist(const string&); bool exist(const string&);
void linker(nasal_ast&,nasal_ast&&); void linker(nasal_ast&,nasal_ast&&);
string path(const nasal_ast&); string path(const nasal_ast&);
string findf(const string&);
nasal_ast fimpt(nasal_ast&); nasal_ast fimpt(nasal_ast&);
nasal_ast libimpt(); nasal_ast libimpt();
nasal_ast load(nasal_ast&,u16); nasal_ast load(nasal_ast&,u16);
public: public:
nasal_import(nasal_err&); nasal_import(nasal_err&);
void link(nasal_parse&,const string&); void link(nasal_parse&,const string&,bool);
const std::vector<string>& filelist() const {return files;} const std::vector<string>& filelist() const {return files;}
}; };
@ -60,6 +62,38 @@ string nasal_import::path(const nasal_ast& node)
return fpath+".nas"; return fpath+".nas";
} }
string nasal_import::findf(const string& fname)
{
#ifdef _WIN32
std::vector<string> filepath={fname,"stl\\"+fname};
#else
std::vector<string> 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) bool nasal_import::imptchk(const nasal_ast& node)
{ {
// only these two kinds of node can be recognized as 'import': // 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(); node.clear();
// avoid infinite loading loop // avoid infinite loading loop
if(exist(filename)) filename=findf(filename);
if(!filename.length() || exist(filename))
return {0,ast_root}; 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... // start importing...
lex.scan(filename); lex.scan(filename);
@ -136,42 +166,11 @@ nasal_ast nasal_import::fimpt(nasal_ast& node)
nasal_ast nasal_import::libimpt() 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<string> libpath={nalib,nastllib};
for(auto& p:envpath)
{
libpath.push_back(p+path_nalib);
libpath.push_back(p+path_stllib);
}
nasal_lexer lex(nerr); nasal_lexer lex(nerr);
nasal_parse par(nerr); nasal_parse par(nerr);
string filename=""; string filename=findf("lib.nas");
for(auto& i:libpath)
if(access(i.c_str(),F_OK)!=-1)
{
filename=i;
break;
}
if(!filename.length()) 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}; return {0,ast_root};
}
// avoid infinite loading loop // avoid infinite loading loop
if(exist(filename)) if(exist(filename))
@ -208,13 +207,15 @@ nasal_ast nasal_import::load(nasal_ast& root,u16 fileindex)
return new_root; 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 // initializing
files={self}; files={self};
// scan root and import files,then generate a new ast and return to import_ast // scan root and import files,then generate a new ast and return to import_ast
// the main file's index is 0 // the main file's index is 0
parse.ast()=load(parse.ast(),0); parse.ast()=load(parse.ast(),0);
nerr.chkerr();
} }
#endif #endif

View File

@ -10,6 +10,24 @@ println("-------------------------------------------------------------");
println(" See help using command line argument: --fg-env-help"); println(" See help using command line argument: --fg-env-help");
println("-------------------------------------------------------------"); 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={ var fg_env_cli={
"--fg-env-help":{ "--fg-env-help":{
info:"get help", info:"get help",

View File

@ -287,6 +287,8 @@ var io=
fin: func(filename){return __fin(filename);}, fin: func(filename){return __fin(filename);},
# input a string as the content of a file. # input a string as the content of a file.
fout: func(filename,str){return __fout(filename,str);}, 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*. # same as C fopen. open file and get the FILE*.
open: func(filename,mode="r"){return __open(filename,mode);}, open: func(filename,mode="r"){return __open(filename,mode);},
# same as C fclose. close file by FILE*. # same as C fclose. close file by FILE*.
@ -378,6 +380,8 @@ var math=
{ {
e: 2.7182818284590452354, e: 2.7182818284590452354,
pi: 3.14159265358979323846264338327950288, pi: 3.14159265358979323846264338327950288,
D2R: 2.7182818284590452354/180,
R2D: 180/2.7182818284590452354,
inf: 1/0, inf: 1/0,
nan: 0/0, nan: 0/0,
abs: func(x) {return x>0?x:-x; }, abs: func(x) {return x>0?x:-x; },
@ -422,7 +426,22 @@ var unix=
var dylib= var dylib=
{ {
# open dynamic lib. # 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. # load symbol from an open dynamic lib.
dlsym: func(lib,sym){return __dlsym; }, dlsym: func(lib,sym){return __dlsym; },
# close dynamic lib, this operation will make all the symbols loaded from it invalid. # 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. # runtime gives us some functions that we could manage it manually.
var runtime= 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 # command line arguments
argv: func(){return __sysargv;} 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: # functions that not supported in this runtime:
var bind=func(function,locals,outer_scope=nil){ var bind=func(function,locals,outer_scope=nil){
die("this runtime does not support bind"); die("this runtime does not support bind");
@ -496,4 +493,4 @@ var coroutine={
yield: func(args...) {return __coyield; }, yield: func(args...) {return __coyield; },
status: func(co) {return __costatus;}, status: func(co) {return __costatus;},
running:func() {return __corun; } running:func() {return __corun; }
}; };