🚀 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:
parent
33e584ab5c
commit
006ed644e6
45
lib.nas
45
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; }
|
||||
};
|
||||
};
|
||||
|
|
11
main.cpp
11
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<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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
|
@ -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",
|
||||
|
|
45
stl/lib.nas
45
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; }
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue