add native function runtime.argv() to get command line arguments

This commit is contained in:
ValKmjolnir 2022-06-04 20:12:00 +08:00
parent cb0fee04a9
commit a2e2d5d8f6
9 changed files with 67 additions and 22 deletions

View File

@ -448,7 +448,10 @@ var runtime=
{ {
# do garbage collection manually. # do garbage collection manually.
# carefully use it because using it frequently may make program running slower. # carefully use it because using it frequently may make program running slower.
gc: func(){return __builtin_gc;} gc: func(){return __builtin_gc;},
# command line arguments
argv: func(){return __builtin_sysargv;}
}; };
# important global constants # important global constants

View File

@ -26,7 +26,7 @@ void help()
<<"nasal <file>\n" <<"nasal <file>\n"
<<"file:\n" <<"file:\n"
<<" input file name to execute script file.\n\n" <<" input file name to execute script file.\n\n"
<<"nasal [options...] <file>\n" <<"nasal [option...] <file> [argv...]\n"
<<"option:\n" <<"option:\n"
<<" -l, --lex | view token info.\n" <<" -l, --lex | view token info.\n"
<<" -a, --ast | view abstract syntax tree.\n" <<" -a, --ast | view abstract syntax tree.\n"
@ -40,7 +40,9 @@ void help()
<<" | 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/-o/-d.\n"
<<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\n" <<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\n"
<<"file:\n" <<"file:\n"
<<" input file name to execute script file.\n"; <<" input file name to execute script file.\n"
<<"argv:\n"
<<" command line arguments used in program.\n";
} }
void logo() void logo()
@ -68,7 +70,7 @@ void err()
std::exit(1); std::exit(1);
} }
void execute(const std::string& file,const uint32_t cmd) void execute(const std::string& file,const std::vector<std::string>& argv,const uint32_t cmd)
{ {
// front end use the same error module // front end use the same error module
nasal_err nerr; nasal_err nerr;
@ -103,18 +105,18 @@ void execute(const std::string& file,const uint32_t cmd)
if(cmd&VM_DEBUG) if(cmd&VM_DEBUG)
{ {
nasal_dbg debugger; nasal_dbg debugger;
debugger.run(gen,linker); debugger.run(gen,linker,argv);
} }
else if(cmd&VM_EXECTIME) else if(cmd&VM_EXECTIME)
{ {
timeb begin,end; timeb begin,end;
ftime(&begin); ftime(&begin);
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO); vm.run(gen,linker,argv,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
ftime(&end); ftime(&end);
std::cout<<"process exited after "<<((end.time-begin.time)*1.0+end.millitm/1000.0-begin.millitm/1000.0)<<"s.\n"; std::cout<<"process exited after "<<((end.time-begin.time)*1.0+end.millitm/1000.0-begin.millitm/1000.0)<<"s.\n";
} }
else if(cmd&VM_EXEC) else if(cmd&VM_EXEC)
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO); vm.run(gen,linker,argv,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
} }
int main(int argc,const char* argv[]) int main(int argc,const char* argv[])
@ -132,7 +134,7 @@ int main(int argc,const char* argv[])
else if(s=="-h" || s=="--help") else if(s=="-h" || s=="--help")
help(); help();
else if(s[0]!='-') else if(s[0]!='-')
execute(s,VM_EXEC); execute(s,{},VM_EXEC);
else else
err(); err();
return 0; return 0;
@ -149,13 +151,25 @@ int main(int argc,const char* argv[])
{"--debug",VM_DEBUG},{"-dbg",VM_DEBUG} {"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}
}; };
uint32_t cmd=0; uint32_t cmd=0;
for(int i=1;i<argc-1;++i) bool recog_file=false;
std::string filename;
std::vector<std::string> vm_argv;
for(int i=1;i<argc;++i)
{ {
if(cmdlst.count(argv[i])) if(cmdlst.count(argv[i]))
cmd|=cmdlst[argv[i]]; cmd|=cmdlst[argv[i]];
else if(!recog_file)
{
filename=argv[i];
recog_file=true;
}
else else
err(); vm_argv.push_back(argv[i]);
} }
execute(argv[argc-1],cmd); if(!recog_file)
err();
if(!cmd)
cmd|=VM_EXEC;
execute(filename,vm_argv,cmd);
return 0; return 0;
} }

View File

@ -39,7 +39,7 @@ test:nasal
@ ./nasal -op -t -d test/prime.nas @ ./nasal -op -t -d test/prime.nas
@ ./nasal -op -e test/qrcode.nas @ ./nasal -op -e test/qrcode.nas
@ ./nasal -op -t -d test/quick_sort.nas @ ./nasal -op -t -d test/quick_sort.nas
@ ./nasal -op -e test/scalar.nas @ ./nasal -op -e test/scalar.nas hello world
-@ ./nasal -op -c -t test/snake.nas -@ ./nasal -op -c -t test/snake.nas
@ ./nasal -op -c -e test/trait.nas @ ./nasal -op -c -e test/trait.nas
-@ ./nasal -op -c -t test/tetris.nas -@ ./nasal -op -c -t test/tetris.nas

View File

@ -99,6 +99,7 @@ nas_native(builtin_coyield);
nas_native(builtin_costatus); nas_native(builtin_costatus);
nas_native(builtin_corun); nas_native(builtin_corun);
nas_native(builtin_millisec); nas_native(builtin_millisec);
nas_native(builtin_sysargv);
nasal_ref builtin_err(const char* func_name,const std::string& info) nasal_ref builtin_err(const char* func_name,const std::string& info)
{ {
@ -204,6 +205,7 @@ struct
{"__builtin_costatus",builtin_costatus}, {"__builtin_costatus",builtin_costatus},
{"__builtin_corun" ,builtin_corun }, {"__builtin_corun" ,builtin_corun },
{"__builtin_millisec",builtin_millisec}, {"__builtin_millisec",builtin_millisec},
{"__builtin_sysargv", builtin_sysargv },
{nullptr, nullptr } {nullptr, nullptr }
}; };
@ -1446,4 +1448,10 @@ nasal_ref builtin_millisec(nasal_ref* local,nasal_gc& gc)
ftime(&now); ftime(&now);
return {vm_num,(double)(now.time*1000+now.millitm)}; return {vm_num,(double)(now.time*1000+now.millitm)};
} }
nasal_ref builtin_sysargv(nasal_ref* local,nasal_gc& gc)
{
nasal_ref res=gc.alloc(vm_vec);
res.vec().elems=gc.env_argv;
return res;
}
#endif #endif

View File

@ -23,7 +23,8 @@ public:
bk_fidx(0),bk_line(0){} bk_fidx(0),bk_line(0){}
void run( void run(
const nasal_codegen&, const nasal_codegen&,
const nasal_import& const nasal_import&,
const std::vector<std::string>&
); );
}; };
@ -176,10 +177,11 @@ void nasal_dbg::interact()
void nasal_dbg::run( void nasal_dbg::run(
const nasal_codegen& gen, const nasal_codegen& gen,
const nasal_import& linker) const nasal_import& linker,
const std::vector<std::string>& argv)
{ {
detail_info=true; detail_info=true;
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file()); init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv);
const void* opr_table[]= const void* opr_table[]=
{ {
&&vmexit, &&intg, &&intl, &&loadg, &&vmexit, &&intg, &&intl, &&loadg,

View File

@ -477,6 +477,7 @@ struct nasal_gc
std::vector<nasal_ref> strs; // reserved address for const vm_str std::vector<nasal_ref> strs; // reserved address for const vm_str
std::vector<nasal_val*> memory; // gc memory std::vector<nasal_val*> memory; // gc memory
std::queue<nasal_val*> free_list[vm_type_size]; // gc free list std::queue<nasal_val*> free_list[vm_type_size]; // gc free list
std::vector<nasal_ref> env_argv; // command line arguments
/* values for analysis */ /* values for analysis */
uint64_t size[vm_type_size]; uint64_t size[vm_type_size];
@ -500,7 +501,7 @@ struct nasal_gc
stack(_stk){} stack(_stk){}
void mark(); void mark();
void sweep(); void sweep();
void init(const std::vector<std::string>&); void init(const std::vector<std::string>&,const std::vector<std::string>&);
void clear(); void clear();
void info(); void info();
nasal_ref alloc(const uint8_t); nasal_ref alloc(const uint8_t);
@ -588,7 +589,7 @@ void nasal_gc::sweep()
i->mark=GC_UNCOLLECTED; i->mark=GC_UNCOLLECTED;
} }
} }
void nasal_gc::init(const std::vector<std::string>& s) void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::string>& argv)
{ {
// initiaize function register // initiaize function register
funcr=nil; funcr=nil;
@ -611,6 +612,14 @@ void nasal_gc::init(const std::vector<std::string>& s)
strs[i].value.gcobj->unmut=1; strs[i].value.gcobj->unmut=1;
strs[i].str()=s[i]; strs[i].str()=s[i];
} }
// record arguments
env_argv.resize(argv.size());
for(size_t i=0;i<argv.size();++i)
{
env_argv[i]={vm_str,new nasal_val(vm_str)};
env_argv[i].value.gcobj->unmut=1;
env_argv[i].str()=argv[i];
}
} }
void nasal_gc::clear() void nasal_gc::clear()
{ {
@ -623,6 +632,7 @@ void nasal_gc::clear()
for(auto& i:strs) for(auto& i:strs)
delete i.value.gcobj; delete i.value.gcobj;
strs.clear(); strs.clear();
env_argv.clear();
} }
void nasal_gc::info() void nasal_gc::info()
{ {

View File

@ -32,6 +32,7 @@ protected:
const std::vector<std::string>&, const std::vector<std::string>&,
const std::vector<double>&, const std::vector<double>&,
const std::vector<opcode>&, const std::vector<opcode>&,
const std::vector<std::string>&,
const std::vector<std::string>&); const std::vector<std::string>&);
/* debug functions */ /* debug functions */
bool detail_info; bool detail_info;
@ -130,6 +131,7 @@ public:
void run( void run(
const nasal_codegen&, const nasal_codegen&,
const nasal_import&, const nasal_import&,
const std::vector<std::string>&,
const bool, const bool,
const bool); const bool);
}; };
@ -138,9 +140,10 @@ void nasal_vm::init(
const std::vector<std::string>& strs, const std::vector<std::string>& strs,
const std::vector<double>& nums, const std::vector<double>& nums,
const std::vector<opcode>& code, const std::vector<opcode>& code,
const std::vector<std::string>& filenames) const std::vector<std::string>& filenames,
const std::vector<std::string>& argv)
{ {
gc.init(strs); gc.init(strs,argv);
num_table=nums.data(); num_table=nums.data();
str_table=strs.data(); str_table=strs.data();
bytecode=code.data(); bytecode=code.data();
@ -1002,11 +1005,12 @@ inline void nasal_vm::opr_ret()
void nasal_vm::run( void nasal_vm::run(
const nasal_codegen& gen, const nasal_codegen& gen,
const nasal_import& linker, const nasal_import& linker,
const std::vector<std::string>& argv,
const bool opcnt, const bool opcnt,
const bool detail) const bool detail)
{ {
detail_info=detail; detail_info=detail;
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file()); init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file(),argv);
uint64_t count[op_ret+1]={0}; uint64_t count[op_ret+1]={0};
const void* opr_table[]= const void* opr_table[]=
{ {

View File

@ -448,7 +448,10 @@ var runtime=
{ {
# do garbage collection manually. # do garbage collection manually.
# carefully use it because using it frequently may make program running slower. # carefully use it because using it frequently may make program running slower.
gc: func(){return __builtin_gc;} gc: func(){return __builtin_gc;},
# command line arguments
argv: func(){return __builtin_sysargv;}
}; };
# important global constants # important global constants

View File

@ -200,4 +200,5 @@ foreach(var i;a){
} }
foreach(i;a){ foreach(i;a){
; ;
} }
println(runtime.argv());