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.
# 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

View File

@ -26,7 +26,7 @@ void help()
<<"nasal <file>\n"
<<"file:\n"
<<" input file name to execute script file.\n\n"
<<"nasal [options...] <file>\n"
<<"nasal [option...] <file> [argv...]\n"
<<"option:\n"
<<" -l, --lex | view token info.\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"
<<" -dbg, --debug | debug mode (this will ignore -t -o -d -e).\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()
@ -68,7 +70,7 @@ void err()
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
nasal_err nerr;
@ -103,18 +105,18 @@ void execute(const std::string& file,const uint32_t cmd)
if(cmd&VM_DEBUG)
{
nasal_dbg debugger;
debugger.run(gen,linker);
debugger.run(gen,linker,argv);
}
else if(cmd&VM_EXECTIME)
{
timeb begin,end;
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);
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)
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[])
@ -132,7 +134,7 @@ int main(int argc,const char* argv[])
else if(s=="-h" || s=="--help")
help();
else if(s[0]!='-')
execute(s,VM_EXEC);
execute(s,{},VM_EXEC);
else
err();
return 0;
@ -149,13 +151,25 @@ int main(int argc,const char* argv[])
{"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}
};
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]))
cmd|=cmdlst[argv[i]];
else
err();
else if(!recog_file)
{
filename=argv[i];
recog_file=true;
}
execute(argv[argc-1],cmd);
else
vm_argv.push_back(argv[i]);
}
if(!recog_file)
err();
if(!cmd)
cmd|=VM_EXEC;
execute(filename,vm_argv,cmd);
return 0;
}

View File

@ -39,7 +39,7 @@ test:nasal
@ ./nasal -op -t -d test/prime.nas
@ ./nasal -op -e test/qrcode.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 -e test/trait.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_corun);
nas_native(builtin_millisec);
nas_native(builtin_sysargv);
nasal_ref builtin_err(const char* func_name,const std::string& info)
{
@ -204,6 +205,7 @@ struct
{"__builtin_costatus",builtin_costatus},
{"__builtin_corun" ,builtin_corun },
{"__builtin_millisec",builtin_millisec},
{"__builtin_sysargv", builtin_sysargv },
{nullptr, nullptr }
};
@ -1446,4 +1448,10 @@ nasal_ref builtin_millisec(nasal_ref* local,nasal_gc& gc)
ftime(&now);
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

View File

@ -23,7 +23,8 @@ public:
bk_fidx(0),bk_line(0){}
void run(
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(
const nasal_codegen& gen,
const nasal_import& linker)
const nasal_import& linker,
const std::vector<std::string>& argv)
{
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[]=
{
&&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_val*> memory; // gc memory
std::queue<nasal_val*> free_list[vm_type_size]; // gc free list
std::vector<nasal_ref> env_argv; // command line arguments
/* values for analysis */
uint64_t size[vm_type_size];
@ -500,7 +501,7 @@ struct nasal_gc
stack(_stk){}
void mark();
void sweep();
void init(const std::vector<std::string>&);
void init(const std::vector<std::string>&,const std::vector<std::string>&);
void clear();
void info();
nasal_ref alloc(const uint8_t);
@ -588,7 +589,7 @@ void nasal_gc::sweep()
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
funcr=nil;
@ -611,6 +612,14 @@ void nasal_gc::init(const std::vector<std::string>& s)
strs[i].value.gcobj->unmut=1;
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()
{
@ -623,6 +632,7 @@ void nasal_gc::clear()
for(auto& i:strs)
delete i.value.gcobj;
strs.clear();
env_argv.clear();
}
void nasal_gc::info()
{

View File

@ -32,6 +32,7 @@ protected:
const std::vector<std::string>&,
const std::vector<double>&,
const std::vector<opcode>&,
const std::vector<std::string>&,
const std::vector<std::string>&);
/* debug functions */
bool detail_info;
@ -130,6 +131,7 @@ public:
void run(
const nasal_codegen&,
const nasal_import&,
const std::vector<std::string>&,
const bool,
const bool);
};
@ -138,9 +140,10 @@ void nasal_vm::init(
const std::vector<std::string>& strs,
const std::vector<double>& nums,
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();
str_table=strs.data();
bytecode=code.data();
@ -1002,11 +1005,12 @@ inline void nasal_vm::opr_ret()
void nasal_vm::run(
const nasal_codegen& gen,
const nasal_import& linker,
const std::vector<std::string>& argv,
const bool opcnt,
const bool 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};
const void* opr_table[]=
{

View File

@ -448,7 +448,10 @@ var runtime=
{
# do garbage collection manually.
# 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

View File

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