Add command line parameters & chr supports extended ASCII
This commit is contained in:
parent
3deea632f8
commit
1ae47807eb
25
README.md
25
README.md
|
@ -34,7 +34,28 @@ Better choose the latest update of the interpreter.
|
|||
|
||||
MUST USE -O2 ! pragma gcc optimize(2) seems useless when using g++
|
||||
|
||||
> g++ -std=c++11 -O2 main.cpp -o main.exe
|
||||
> g++ -std=c++11 -O2 main.cpp -o nasal.exe
|
||||
|
||||
Or use this in linux/macOS/Unix
|
||||
|
||||
> g++ -std=c++11 -O2 main.cpp -o nasal
|
||||
|
||||
## How to Use?
|
||||
|
||||
Input this command to use interactive interpreter mode:
|
||||
|
||||
> ./nasal
|
||||
|
||||
Input this command to run scripts directly:
|
||||
|
||||
> ./nasal filename
|
||||
|
||||
Use these commands to get some information of interpreter:
|
||||
|
||||
> ./nasal -v
|
||||
> ./nasal -version
|
||||
> ./nasal -h
|
||||
> ./nasal -help
|
||||
|
||||
## Parser
|
||||
|
||||
|
@ -471,7 +492,7 @@ After that, write the built-in function's name(in nasal) and the function's poin
|
|||
```C++
|
||||
struct FUNC_TABLE
|
||||
{
|
||||
std::string name;
|
||||
const char* name;
|
||||
nasal_val* (*func)(std::vector<nasal_val*>&,nasal_gc&);
|
||||
} builtin_func[]=
|
||||
{
|
||||
|
|
83
lib.nas
83
lib.nas
|
@ -1,28 +1,23 @@
|
|||
var import=func(filename)
|
||||
{
|
||||
__builtin_import(filename);
|
||||
return nil;
|
||||
return __builtin_import(filename);
|
||||
}
|
||||
var print=func(elements...)
|
||||
var print=func(elems...)
|
||||
{
|
||||
__builtin_std_cout(elements);
|
||||
return nil;
|
||||
return __builtin_std_cout(elems);
|
||||
};
|
||||
var println=func(elements...)
|
||||
var println=func(elems...)
|
||||
{
|
||||
__builtin_std_cout(elements);
|
||||
print('\n');
|
||||
return nil;
|
||||
__builtin_std_cout(elems);
|
||||
return print('\n');
|
||||
}
|
||||
var append=func(vector,elements...)
|
||||
var append=func(vec,elems...)
|
||||
{
|
||||
__builtin_push_back(vector,elements);
|
||||
return nil;
|
||||
return __builtin_push_back(vec,elems);
|
||||
}
|
||||
var setsize=func(vector,size)
|
||||
var setsize=func(vec,size)
|
||||
{
|
||||
__builtin_set_size(vector,size);
|
||||
return nil;
|
||||
return __builtin_set_size(vec,size);
|
||||
}
|
||||
var system=func(str)
|
||||
{
|
||||
|
@ -34,36 +29,35 @@ var input=func()
|
|||
}
|
||||
var sleep=func(duration)
|
||||
{
|
||||
__builtin_sleep(duration);
|
||||
return;
|
||||
return __builtin_sleep(duration);
|
||||
}
|
||||
var split=func(delimeter,string)
|
||||
var split=func(deli,str)
|
||||
{
|
||||
return __builtin_split(delimeter,string);
|
||||
return __builtin_split(deli,str);
|
||||
}
|
||||
var rand=func(seed=nil)
|
||||
{
|
||||
return __builtin_rand(seed);
|
||||
}
|
||||
var id=func(thing)
|
||||
var id=func(object)
|
||||
{
|
||||
return __builtin_get_id(thing);
|
||||
return __builtin_get_id(object);
|
||||
}
|
||||
var int=func(value)
|
||||
var int=func(val)
|
||||
{
|
||||
return __builtin_int(value);
|
||||
return __builtin_int(val);
|
||||
}
|
||||
var num=func(value)
|
||||
var num=func(val)
|
||||
{
|
||||
return __builtin_num(value);
|
||||
return __builtin_num(val);
|
||||
}
|
||||
var pop=func(vector)
|
||||
var pop=func(vec)
|
||||
{
|
||||
return __builtin_pop_back(vector);
|
||||
return __builtin_pop_back(vec);
|
||||
}
|
||||
var str=func(number)
|
||||
var str=func(num)
|
||||
{
|
||||
return __builtin_str(number);
|
||||
return __builtin_str(num);
|
||||
}
|
||||
var size=func(object)
|
||||
{
|
||||
|
@ -75,8 +69,7 @@ var contains=func(hash,key)
|
|||
}
|
||||
var delete=func(hash,key)
|
||||
{
|
||||
__builtin_delete(hash,key);
|
||||
return;
|
||||
return __builtin_delete(hash,key);
|
||||
}
|
||||
var keys=func(hash)
|
||||
{
|
||||
|
@ -88,49 +81,41 @@ var time=func(begin_time)
|
|||
}
|
||||
var die=func(str)
|
||||
{
|
||||
__builtin_die(str);
|
||||
return nil;
|
||||
return __builtin_die(str);
|
||||
}
|
||||
var typeof=func(object)
|
||||
{
|
||||
return __builtin_type(object);
|
||||
}
|
||||
var substr=func(str,begin,length)
|
||||
var substr=func(str,begin,len)
|
||||
{
|
||||
return __builtin_substr(str,begin,length);
|
||||
return __builtin_substr(str,begin,len);
|
||||
}
|
||||
var streq=func(a,b)
|
||||
{
|
||||
return __builtin_streq(a,b);
|
||||
}
|
||||
var left=func(string,length)
|
||||
var left=func(str,len)
|
||||
{
|
||||
return __builtin_left(string,length);
|
||||
return __builtin_left(str,len);
|
||||
}
|
||||
var right=func(string,length)
|
||||
var right=func(str,len)
|
||||
{
|
||||
return __builtin_right(string,length);
|
||||
return __builtin_right(str,len);
|
||||
}
|
||||
var cmp=func(a,b)
|
||||
{
|
||||
return __builtin_cmp(a,b);
|
||||
}
|
||||
var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII
|
||||
var chr=func(code)
|
||||
{
|
||||
return __builtin_chr(code);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
fin:func(filename)
|
||||
{
|
||||
return __builtin_fin(filename);
|
||||
},
|
||||
fout:func(filename,str)
|
||||
{
|
||||
__builtin_fout(filename,str);
|
||||
return;
|
||||
}
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);}
|
||||
};
|
||||
|
||||
var bits=
|
||||
|
|
68
main.cpp
68
main.cpp
|
@ -2,10 +2,10 @@
|
|||
|
||||
nasal_vm vm;
|
||||
|
||||
void help()
|
||||
void help_interact()
|
||||
{
|
||||
std::cout
|
||||
<<">> [\"file\"] input file name. \n"
|
||||
<<">> [ ] input a file name to execute. \n"
|
||||
<<">> [help ] show help. \n"
|
||||
<<">> [clear] clear the screen. \n"
|
||||
<<">> [lex ] view tokens. \n"
|
||||
|
@ -16,7 +16,25 @@ void help()
|
|||
<<">> [exit ] quit nasal interpreter. \n";
|
||||
return;
|
||||
}
|
||||
|
||||
void help_cmd()
|
||||
{
|
||||
std::cout
|
||||
<<"nasal -h -help | get help.\n"
|
||||
<<"nasal -v -version | get version of nasal interpreter.\n"
|
||||
<<"nasal filename | execute script file.\n";
|
||||
return;
|
||||
}
|
||||
void info()
|
||||
{
|
||||
std::cout
|
||||
<<">> Nasal interpreter ver 6.5 efficient gc test .\n"
|
||||
<<">> Thanks to https://github.com/andyross/nasal\n"
|
||||
<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
||||
<<">> Code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
||||
<<">> Info: http://wiki.flightgear.org/Nasal_scripting_language\n"
|
||||
<<">> Input \"help\" to get help .\n";
|
||||
return;
|
||||
}
|
||||
void logo()
|
||||
{
|
||||
std::cout
|
||||
|
@ -27,13 +45,11 @@ void logo()
|
|||
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void die(const char* stage,std::string& filename)
|
||||
{
|
||||
std::cout<<">> ["<<stage<<"] in <\""<<filename<<"\">: error(s) occurred,stop.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void execute(std::string& file,std::string& command)
|
||||
{
|
||||
nasal_lexer lexer;
|
||||
|
@ -92,31 +108,21 @@ void execute(std::string& file,std::string& command)
|
|||
vm.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
void interact()
|
||||
{
|
||||
std::string command;
|
||||
std::string file="null";
|
||||
#ifdef _WIN32
|
||||
// use chcp 65001 to use unicode io
|
||||
system("chcp 65001");
|
||||
system("cls");
|
||||
#else
|
||||
int rs=system("clear");// avoid annoying warning of high version gcc/g++
|
||||
#endif
|
||||
std::string command,file="null";
|
||||
logo();
|
||||
std::cout<<">> Nasal interpreter ver 6.5 efficient gc test .\n";
|
||||
std::cout<<">> Thanks to https://github.com/andyross/nasal\n";
|
||||
std::cout<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n";
|
||||
std::cout<<">> Code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n";
|
||||
std::cout<<">> Info: http://wiki.flightgear.org/Nasal_scripting_language\n";
|
||||
std::cout<<">> Input \"help\" to get help .\n";
|
||||
info();
|
||||
while(1)
|
||||
{
|
||||
std::cout<<">> ";
|
||||
std::cin>>command;
|
||||
if(command=="help")
|
||||
help();
|
||||
help_interact();
|
||||
else if(command=="clear")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -128,11 +134,33 @@ int main()
|
|||
else if(command=="logo")
|
||||
logo();
|
||||
else if(command=="exit")
|
||||
break;
|
||||
return;
|
||||
else if(command=="lex" || command=="ast" || command=="code" || command=="exec")
|
||||
execute(file,command);
|
||||
else
|
||||
file=command;
|
||||
}
|
||||
}
|
||||
int main(int argc,const char* argv[])
|
||||
{
|
||||
std::string command,file="null";
|
||||
if(argc==1)
|
||||
interact();
|
||||
else if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"-version")))
|
||||
{
|
||||
logo();
|
||||
std::cout<<"Nasal interpreter ver 6.5 efficient gc test\n";
|
||||
}
|
||||
else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"-help")))
|
||||
help_cmd();
|
||||
else if(argc==2)
|
||||
{
|
||||
file=argv[1];
|
||||
command="exec";
|
||||
execute(file,command);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
help_cmd();
|
||||
return 0;
|
||||
}
|
6
nasal.h
6
nasal.h
|
@ -113,11 +113,9 @@ double str2num(const char* str)
|
|||
*/
|
||||
std::string num2str(double number)
|
||||
{
|
||||
std::string res;
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss<<number;
|
||||
ss>>res;
|
||||
return res;
|
||||
return ss.str();
|
||||
}
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_ast.h"
|
||||
|
|
|
@ -199,7 +199,7 @@ nasal_val* builtin_sleep(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
|||
return nullptr;
|
||||
}
|
||||
// sleep in unistd.h will make this progress sleep sleep_time seconds.
|
||||
sleep((unsigned long)val_addr->ptr.num);
|
||||
sleep((unsigned int)val_addr->ptr.num);
|
||||
return gc.nil_addr;
|
||||
}
|
||||
|
||||
|
@ -628,9 +628,7 @@ nasal_val* builtin_contains(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
|||
builtin_err("contains","\"key\" must be string");
|
||||
return nullptr;
|
||||
}
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_num);
|
||||
ret_addr->ptr.num=hash_addr->ptr.hash->elems.count(*key_addr->ptr.str);
|
||||
return ret_addr;
|
||||
return hash_addr->ptr.hash->elems.count(*key_addr->ptr.str)?gc.one_addr:gc.zero_addr;
|
||||
}
|
||||
nasal_val* builtin_delete(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
|
@ -810,6 +808,24 @@ nasal_val* builtin_cmp(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
|||
}
|
||||
nasal_val* builtin_chr(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
||||
{
|
||||
const char* extend[]={
|
||||
"€"," ","‚","ƒ","„","…","†","‡",
|
||||
"ˆ","‰","Š","‹","Œ"," ","Ž"," ",
|
||||
" ","‘","’","“","”","•","–","—",
|
||||
"˜","™","š","›","œ"," ","ž","Ÿ",
|
||||
" ","¡","¢","£","¤","¥","¦","§",
|
||||
"¨","©","ª","«","¬"," ","®","¯",
|
||||
"°","±","²","³","´","µ","¶","·",
|
||||
"¸","¹","º","»","¼","½","¾","¿",
|
||||
"À","Á","Â","Ã","Ä","Å","Æ","Ç",
|
||||
"È","É","Ê","Ë","Ì","Í","Î","Ï",
|
||||
"Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×",
|
||||
"Ø","Ù","Ú","Û","Ü","Ý","Þ","ß",
|
||||
"à","á","â","ã","ä","å","æ","ç",
|
||||
"è","é","ê","ë","ì","í","î","ï",
|
||||
"ð","ñ","ò","ó","ô","õ","ö","÷",
|
||||
"ø","ù","ú","û","ü","ý","þ","ÿ"
|
||||
};
|
||||
nasal_val* code_addr=local_scope[1];
|
||||
if(code_addr->type!=vm_num)
|
||||
{
|
||||
|
@ -817,7 +833,13 @@ nasal_val* builtin_chr(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
|
|||
return nullptr;
|
||||
}
|
||||
nasal_val* ret_addr=gc.gc_alloc(vm_str);
|
||||
*ret_addr->ptr.str=(char)code_addr->ptr.num;
|
||||
int num=code_addr->ptr.num;
|
||||
if(0<=num && num<128)
|
||||
*ret_addr->ptr.str=(char)num;
|
||||
else if(128<=num && num<256)
|
||||
*ret_addr->ptr.str=extend[num-128];
|
||||
else
|
||||
*ret_addr->ptr.str=" ";
|
||||
return ret_addr;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,12 +161,8 @@ void nasal_parse::match(int type,std::string err_info)
|
|||
return;
|
||||
}
|
||||
std::string s="";
|
||||
for(int i=0;token_table[i].str;++i)
|
||||
if(token_table[i].tok_type==type)
|
||||
{
|
||||
s=token_table[i].str;
|
||||
break;
|
||||
}
|
||||
if(type>=tok_for)// token_table begins at tok_for
|
||||
s=token_table[type-tok_for].str;
|
||||
switch(type)
|
||||
{
|
||||
case tok_num:die(error_line,"expected number"); break;
|
||||
|
@ -391,8 +387,7 @@ nasal_ast nasal_parse::args_gen()
|
|||
match(tok_lcurve);
|
||||
while(tok_list[ptr].type!=tok_rcurve)
|
||||
{
|
||||
nasal_ast tmp;
|
||||
tmp=id_gen();
|
||||
nasal_ast tmp=id_gen();
|
||||
match(tok_id);
|
||||
if(tok_list[ptr].type==tok_eq || tok_list[ptr].type==tok_ellipsis)
|
||||
{
|
||||
|
|
83
stl/lib.nas
83
stl/lib.nas
|
@ -1,28 +1,23 @@
|
|||
var import=func(filename)
|
||||
{
|
||||
__builtin_import(filename);
|
||||
return nil;
|
||||
return __builtin_import(filename);
|
||||
}
|
||||
var print=func(elements...)
|
||||
var print=func(elems...)
|
||||
{
|
||||
__builtin_std_cout(elements);
|
||||
return nil;
|
||||
return __builtin_std_cout(elems);
|
||||
};
|
||||
var println=func(elements...)
|
||||
var println=func(elems...)
|
||||
{
|
||||
__builtin_std_cout(elements);
|
||||
print('\n');
|
||||
return nil;
|
||||
__builtin_std_cout(elems);
|
||||
return print('\n');
|
||||
}
|
||||
var append=func(vector,elements...)
|
||||
var append=func(vec,elems...)
|
||||
{
|
||||
__builtin_push_back(vector,elements);
|
||||
return nil;
|
||||
return __builtin_push_back(vec,elems);
|
||||
}
|
||||
var setsize=func(vector,size)
|
||||
var setsize=func(vec,size)
|
||||
{
|
||||
__builtin_set_size(vector,size);
|
||||
return nil;
|
||||
return __builtin_set_size(vec,size);
|
||||
}
|
||||
var system=func(str)
|
||||
{
|
||||
|
@ -34,36 +29,35 @@ var input=func()
|
|||
}
|
||||
var sleep=func(duration)
|
||||
{
|
||||
__builtin_sleep(duration);
|
||||
return;
|
||||
return __builtin_sleep(duration);
|
||||
}
|
||||
var split=func(delimeter,string)
|
||||
var split=func(deli,str)
|
||||
{
|
||||
return __builtin_split(delimeter,string);
|
||||
return __builtin_split(deli,str);
|
||||
}
|
||||
var rand=func(seed=nil)
|
||||
{
|
||||
return __builtin_rand(seed);
|
||||
}
|
||||
var id=func(thing)
|
||||
var id=func(object)
|
||||
{
|
||||
return __builtin_get_id(thing);
|
||||
return __builtin_get_id(object);
|
||||
}
|
||||
var int=func(value)
|
||||
var int=func(val)
|
||||
{
|
||||
return __builtin_int(value);
|
||||
return __builtin_int(val);
|
||||
}
|
||||
var num=func(value)
|
||||
var num=func(val)
|
||||
{
|
||||
return __builtin_num(value);
|
||||
return __builtin_num(val);
|
||||
}
|
||||
var pop=func(vector)
|
||||
var pop=func(vec)
|
||||
{
|
||||
return __builtin_pop_back(vector);
|
||||
return __builtin_pop_back(vec);
|
||||
}
|
||||
var str=func(number)
|
||||
var str=func(num)
|
||||
{
|
||||
return __builtin_str(number);
|
||||
return __builtin_str(num);
|
||||
}
|
||||
var size=func(object)
|
||||
{
|
||||
|
@ -75,8 +69,7 @@ var contains=func(hash,key)
|
|||
}
|
||||
var delete=func(hash,key)
|
||||
{
|
||||
__builtin_delete(hash,key);
|
||||
return;
|
||||
return __builtin_delete(hash,key);
|
||||
}
|
||||
var keys=func(hash)
|
||||
{
|
||||
|
@ -88,49 +81,41 @@ var time=func(begin_time)
|
|||
}
|
||||
var die=func(str)
|
||||
{
|
||||
__builtin_die(str);
|
||||
return nil;
|
||||
return __builtin_die(str);
|
||||
}
|
||||
var typeof=func(object)
|
||||
{
|
||||
return __builtin_type(object);
|
||||
}
|
||||
var substr=func(str,begin,length)
|
||||
var substr=func(str,begin,len)
|
||||
{
|
||||
return __builtin_substr(str,begin,length);
|
||||
return __builtin_substr(str,begin,len);
|
||||
}
|
||||
var streq=func(a,b)
|
||||
{
|
||||
return __builtin_streq(a,b);
|
||||
}
|
||||
var left=func(string,length)
|
||||
var left=func(str,len)
|
||||
{
|
||||
return __builtin_left(string,length);
|
||||
return __builtin_left(str,len);
|
||||
}
|
||||
var right=func(string,length)
|
||||
var right=func(str,len)
|
||||
{
|
||||
return __builtin_right(string,length);
|
||||
return __builtin_right(str,len);
|
||||
}
|
||||
var cmp=func(a,b)
|
||||
{
|
||||
return __builtin_cmp(a,b);
|
||||
}
|
||||
var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII
|
||||
var chr=func(code)
|
||||
{
|
||||
return __builtin_chr(code);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
fin:func(filename)
|
||||
{
|
||||
return __builtin_fin(filename);
|
||||
},
|
||||
fout:func(filename,str)
|
||||
{
|
||||
__builtin_fout(filename,str);
|
||||
return;
|
||||
}
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);}
|
||||
};
|
||||
|
||||
var bits=
|
||||
|
|
21
test/bf.nas
21
test/bf.nas
|
@ -146,16 +146,13 @@ var mandelbrot=
|
|||
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
|
||||
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
|
||||
<<<<<]]>>>]";
|
||||
var hello=
|
||||
"++[>++<-]>[>++<-]>[>++<-]>[>++<-]>[>++<-]>+++++++++++++++++++++++++++++++++++++
|
||||
+++.---.+++++++..+++.<.>++++++++.--------.+++.------.--------.";
|
||||
|
||||
var bf=func(program)
|
||||
{
|
||||
var paper=[];
|
||||
setsize(paper,131072);
|
||||
for(var i=0;i<131072;i+=1)
|
||||
paper[i]=0;
|
||||
#for(var i=0;i<131072;i+=1)
|
||||
# paper[i]=0;
|
||||
var ptr=0;
|
||||
var s=program;
|
||||
var len=size(s);
|
||||
|
@ -243,16 +240,10 @@ var bf=func(program)
|
|||
paper[ptr]=input()[0];
|
||||
elsif(code[i][0]==out)
|
||||
print(chr(paper[ptr]));
|
||||
elsif(code[i][0]==jt)
|
||||
{
|
||||
if(paper[ptr])
|
||||
i=code[i][1]-1;
|
||||
}
|
||||
elsif(code[i][0]==jf)
|
||||
{
|
||||
if(!paper[ptr])
|
||||
i=code[i][1]-1;
|
||||
}
|
||||
elsif(code[i][0]==jt and paper[ptr])
|
||||
i=code[i][1]-1;
|
||||
elsif(code[i][0]==jf and !paper[ptr])
|
||||
i=code[i][1]-1;
|
||||
}
|
||||
print('\n');
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue