🚀 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);},
# 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; }
};
};

View File

@ -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<string>& 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;

View File

@ -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)

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);
{
auto& vals=ast[1].child();
for(int i=0;i<size;++i)
for(usize i=0;i<size;++i)
{
calc_gen(vals[i]);
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];
{
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());
const string& str=ids[i].str();

View File

@ -8,6 +8,7 @@
class nasal_import
{
private:
bool show_path;
bool lib_loaded;
nasal_err& nerr;
std::vector<string> 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<string>& 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<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)
{
// 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<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_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

View File

@ -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",

View File

@ -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; }
};
};