avoid unnecessary deep copy by using rvalue ref

and test file update.
bug fixed in test/lexer.nas
This commit is contained in:
ValKmjolnir 2021-06-24 22:10:08 +08:00
parent fd57e9a47c
commit 3c9a10d710
17 changed files with 212 additions and 311 deletions

View File

@ -1,7 +1,5 @@
#include "nasal.h" #include "nasal.h"
nasal_vm vm;
void help_interact() void help_interact()
{ {
std::cout std::cout
@ -31,7 +29,7 @@ void help_cmd()
void info() void info()
{ {
std::cout std::cout
<<">> Nasal interpreter ver 6.5 efficient gc test .\n" <<">> Nasal interpreter ver 6.5.\n"
<<">> Thanks to https://github.com/andyross/nasal\n" <<">> Thanks to https://github.com/andyross/nasal\n"
<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n" <<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<">> Code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n" <<">> Code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
@ -60,6 +58,7 @@ void execute(std::string& file,std::string& command)
nasal_parse parse; nasal_parse parse;
nasal_import import; nasal_import import;
nasal_codegen codegen; nasal_codegen codegen;
nasal_vm vm;
lexer.openfile(file); lexer.openfile(file);
lexer.scanner(); lexer.scanner();
if(lexer.get_error()) if(lexer.get_error())
@ -153,7 +152,7 @@ int main(int argc,const char* argv[])
else if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"-version"))) else if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"-version")))
{ {
logo(); logo();
std::cout<<"Nasal interpreter ver 6.5 efficient gc test\n"; std::cout<<"Nasal interpreter ver 6.5\n";
} }
else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"-help"))) else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"-help")))
help_cmd(); help_cmd();

View File

@ -57,10 +57,12 @@ public:
nasal_ast(){line=0;type=ast_null;} nasal_ast(){line=0;type=ast_null;}
nasal_ast(int l,int t){line=l;type=t;} nasal_ast(int l,int t){line=l;type=t;}
nasal_ast(const nasal_ast&); nasal_ast(const nasal_ast&);
nasal_ast& operator=(const nasal_ast&); nasal_ast(nasal_ast&&);
nasal_ast& operator=(const nasal_ast&);
nasal_ast& operator=(nasal_ast&&);
void print_ast(int); void print_ast(int);
void clear(); void clear();
void add_child(nasal_ast ast){children.push_back(ast);} void add_child(nasal_ast&& ast){children.push_back(std::move(ast));}
void set_line(int l){line=l;} void set_line(int l){line=l;}
void set_type(int t){type=t;} void set_type(int t){type=t;}
void set_str(std::string& s){str=s;} void set_str(std::string& s){str=s;}
@ -82,6 +84,16 @@ nasal_ast::nasal_ast(const nasal_ast& tmp)
return; return;
} }
nasal_ast::nasal_ast(nasal_ast&& tmp)
{
line=tmp.line;
type=tmp.type;
str.swap(tmp.str);
num =tmp.num;
children.swap(tmp.children);
return;
}
nasal_ast& nasal_ast::operator=(const nasal_ast& tmp) nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
{ {
line=tmp.line; line=tmp.line;
@ -92,6 +104,16 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
return *this; return *this;
} }
nasal_ast& nasal_ast::operator=(nasal_ast&& tmp)
{
line=tmp.line;
type=tmp.type;
str.swap(tmp.str);
num=tmp.num;
children.swap(tmp.children);
return *this;
}
void nasal_ast::clear() void nasal_ast::clear()
{ {
line=0; line=0;
@ -104,11 +126,10 @@ void nasal_ast::clear()
void nasal_ast::print_ast(int depth) void nasal_ast::print_ast(int depth)
{ {
std::string indentation="";
for(int i=0;i<depth;++i) for(int i=0;i<depth;++i)
indentation+="| "; std::cout<<"| ";
std::cout<<indentation<<ast_name[type]; std::cout<<ast_name[type];
if(type==ast_str || type==ast_id || type==ast_dynamic_id || type==ast_callh) if(type==ast_str || type==ast_id || type==ast_default_arg || type==ast_dynamic_id || type==ast_callh)
std::cout<<":"<<str; std::cout<<":"<<str;
else if(type==ast_num) else if(type==ast_num)
std::cout<<":"<<num; std::cout<<":"<<num;

View File

@ -365,8 +365,8 @@ void nasal_codegen::func_gen(nasal_ast& ast)
} }
else if(tmp.get_type()==ast_default_arg) else if(tmp.get_type()==ast_default_arg)
{ {
calc_gen(tmp.get_children()[1]); calc_gen(tmp.get_children()[0]);
std::string& str=tmp.get_children()[0].get_str(); std::string& str=tmp.get_str();
regist_string(str); regist_string(str);
add_sym(str); add_sym(str);
gen(op_defpara,string_table[str]); gen(op_defpara,string_table[str]);

View File

@ -12,7 +12,7 @@ private:
void die(std::string&,const char*); void die(std::string&,const char*);
bool check_import(nasal_ast&); bool check_import(nasal_ast&);
bool check_exist(std::string&); bool check_exist(std::string&);
void linker(nasal_ast&,nasal_ast&); void linker(nasal_ast&,nasal_ast&&);
nasal_ast file_import(nasal_ast&); nasal_ast file_import(nasal_ast&);
nasal_ast load(nasal_ast&); nasal_ast load(nasal_ast&);
public: public:
@ -51,21 +51,21 @@ only this kind of node can be recognized as 'import':
return true; return true;
} }
bool nasal_import::check_exist(std::string& filename) bool nasal_import::check_exist(std::string& file)
{ {
// avoid importing the same file // avoid importing the same file
for(auto& fname:filename_table) for(auto& fname:filename_table)
if(filename==fname) if(file==fname)
return true; return true;
filename_table.push_back(filename); filename_table.push_back(file);
return false; return false;
} }
void nasal_import::linker(nasal_ast& root,nasal_ast& add_root) void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root)
{ {
// add children of add_root to the back of root // add children of add_root to the back of root
for(auto& i:add_root.get_children()) for(auto& i:add_root.get_children())
root.add_child(i); root.add_child(std::move(i));
return; return;
} }
@ -75,7 +75,7 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
nasal_ast tmp(0,ast_root); nasal_ast tmp(0,ast_root);
// get filename and set node to ast_null // get filename and set node to ast_null
std::string& filename=node.get_children()[1].get_children()[0].get_str(); std::string filename=node.get_children()[1].get_children()[0].get_str();
node.clear(); node.clear();
// avoid infinite loading loop // avoid infinite loading loop
@ -98,7 +98,7 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
die(filename,"parser"); die(filename,"parser");
return tmp; return tmp;
} }
tmp=import_par.get_root(); tmp=std::move(import_par.get_root());
import_par.get_root().clear(); import_par.get_root().clear();
// check if tmp has 'import' // check if tmp has 'import'
return load(tmp); return load(tmp);
@ -109,14 +109,9 @@ nasal_ast nasal_import::load(nasal_ast& root)
nasal_ast new_root(0,ast_root); nasal_ast new_root(0,ast_root);
for(auto& i:root.get_children()) for(auto& i:root.get_children())
if(check_import(i)) if(check_import(i))
{ linker(new_root,file_import(i));
nasal_ast tmp=file_import(i);
// add tmp to the back of new_root
linker(new_root,tmp);
}
// add root to the back of new_root // add root to the back of new_root
linker(new_root,root); linker(new_root,std::move(root));
// oops,i think it is not efficient if the root is too ... large?
return new_root; return new_root;
} }

View File

@ -48,7 +48,7 @@ private:
std::vector<token> error_token; std::vector<token> error_token;
int in_function; // count when generating function block,used to check return-expression int in_function; // count when generating function block,used to check return-expression
int in_loop; // count when generating loop block,used to check break/continue-expression int in_loop; // count when generating loop block,used to check break/continue-expression
void die(int,std::string); void die(int,std::string&&);
void match(int type,const char* err_info=""); void match(int type,const char* err_info="");
bool check_comma(int*); bool check_comma(int*);
bool check_multi_def(); bool check_multi_def();
@ -140,7 +140,7 @@ void nasal_parse::main_process()
<<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n"; <<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
return; return;
} }
void nasal_parse::die(int line,std::string info) void nasal_parse::die(int line,std::string&& info)
{ {
++error; ++error;
std::cout<<">> [parse] line "<<line<<": "<<info<<".\n"; std::cout<<">> [parse] line "<<line<<": "<<info<<".\n";
@ -378,21 +378,21 @@ nasal_ast nasal_parse::args_gen()
nasal_ast special_arg(tok_list[ptr].line,ast_null); nasal_ast special_arg(tok_list[ptr].line,ast_null);
if(tok_list[ptr].type==tok_eq) if(tok_list[ptr].type==tok_eq)
{ {
special_arg.add_child(tmp);
match(tok_eq); match(tok_eq);
special_arg.add_child(calc()); special_arg=std::move(tmp);
special_arg.set_type(ast_default_arg); special_arg.set_type(ast_default_arg);
special_arg.add_child(calc());
} }
else else
{ {
match(tok_ellipsis); match(tok_ellipsis);
special_arg=tmp; special_arg=std::move(tmp);
special_arg.set_type(ast_dynamic_id); special_arg.set_type(ast_dynamic_id);
} }
node.add_child(special_arg); node.add_child(std::move(special_arg));
} }
else else
node.add_child(tmp); node.add_child(std::move(tmp));
if(tok_list[ptr].type==tok_comma) if(tok_list[ptr].type==tok_comma)
match(tok_comma); match(tok_comma);
else if(tok_list[ptr].type==tok_id)// first set of identifier else if(tok_list[ptr].type==tok_id)// first set of identifier
@ -407,9 +407,9 @@ nasal_ast nasal_parse::args_gen()
{ {
switch(tmp.get_type()) switch(tmp.get_type())
{ {
case ast_id: args_format+="val";break; case ast_id: args_format+=tmp.get_str();break;
case ast_default_arg: args_format+="val=scalar";break; case ast_default_arg: args_format+=tmp.get_str()+"=val";break;
case ast_dynamic_id: args_format+="val...";break; case ast_dynamic_id: args_format+=tmp.get_str()+"...";break;
} }
args_format+=",)"[&tmp==&node.get_children().back()]; args_format+=",)"[&tmp==&node.get_children().back()];
} }
@ -433,7 +433,7 @@ nasal_ast nasal_parse::args_gen()
{ {
case ast_dynamic_id: case ast_dynamic_id:
case ast_id: new_name=tmp.get_str();break; case ast_id: new_name=tmp.get_str();break;
case ast_default_arg:new_name=tmp.get_children()[0].get_str();break; case ast_default_arg:new_name=tmp.get_str();break;
} }
if(argname_table.count(new_name)) if(argname_table.count(new_name))
die(tmp.get_line(),"parameter's name repeats: "+new_name); die(tmp.get_line(),"parameter's name repeats: "+new_name);
@ -518,21 +518,21 @@ nasal_ast nasal_parse::calc()
// trinocular calculation // trinocular calculation
nasal_ast tmp(tok_list[ptr].line,ast_trino); nasal_ast tmp(tok_list[ptr].line,ast_trino);
match(tok_quesmark); match(tok_quesmark);
tmp.add_child(node); tmp.add_child(std::move(node));
tmp.add_child(calc()); tmp.add_child(calc());
match(tok_colon); match(tok_colon);
tmp.add_child(calc()); tmp.add_child(calc());
node=tmp; node=std::move(tmp);
} }
else if(tok_eq<=tok_list[ptr].type && tok_list[ptr].type<=tok_lnkeq) else if(tok_eq<=tok_list[ptr].type && tok_list[ptr].type<=tok_lnkeq)
{ {
check_memory_reachable(node); check_memory_reachable(node);
// tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26 // tok_eq~tok_lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_eq+ast_equal); nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_eq+ast_equal);
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_list[ptr].type); match(tok_list[ptr].type);
tmp.add_child(calc()); tmp.add_child(calc());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -542,10 +542,10 @@ nasal_ast nasal_parse::or_expr()
while(tok_list[ptr].type==tok_or) while(tok_list[ptr].type==tok_or)
{ {
nasal_ast tmp(tok_list[ptr].line,ast_or); nasal_ast tmp(tok_list[ptr].line,ast_or);
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_or); match(tok_or);
tmp.add_child(and_expr()); tmp.add_child(and_expr());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -555,10 +555,10 @@ nasal_ast nasal_parse::and_expr()
while(tok_list[ptr].type==tok_and) while(tok_list[ptr].type==tok_and)
{ {
nasal_ast tmp(tok_list[ptr].line,ast_and); nasal_ast tmp(tok_list[ptr].line,ast_and);
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_and); match(tok_and);
tmp.add_child(cmp_expr()); tmp.add_child(cmp_expr());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -569,10 +569,10 @@ nasal_ast nasal_parse::cmp_expr()
{ {
// tok_cmpeq~tok_geq is 43~48,ast_cmpeq~ast_geq is 27~32 // tok_cmpeq~tok_geq is 43~48,ast_cmpeq~ast_geq is 27~32
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_cmpeq+ast_cmpeq); nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_cmpeq+ast_cmpeq);
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_list[ptr].type); match(tok_list[ptr].type);
tmp.add_child(additive_expr()); tmp.add_child(additive_expr());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -588,10 +588,10 @@ nasal_ast nasal_parse::additive_expr()
case tok_sub: tmp.set_type(ast_sub); break; case tok_sub: tmp.set_type(ast_sub); break;
case tok_link: tmp.set_type(ast_link); break; case tok_link: tmp.set_type(ast_link); break;
} }
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_list[ptr].type); match(tok_list[ptr].type);
tmp.add_child(multive_expr()); tmp.add_child(multive_expr());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -601,10 +601,10 @@ nasal_ast nasal_parse::multive_expr()
while(tok_list[ptr].type==tok_mult || tok_list[ptr].type==tok_div) while(tok_list[ptr].type==tok_mult || tok_list[ptr].type==tok_div)
{ {
nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_mult+ast_mult); nasal_ast tmp(tok_list[ptr].line,tok_list[ptr].type-tok_mult+ast_mult);
tmp.add_child(node); tmp.add_child(std::move(node));
match(tok_list[ptr].type); match(tok_list[ptr].type);
tmp.add_child((tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not)?unary():scalar()); tmp.add_child((tok_list[ptr].type==tok_sub || tok_list[ptr].type==tok_not)?unary():scalar());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -667,11 +667,10 @@ nasal_ast nasal_parse::scalar()
} }
if(is_call(tok_list[ptr].type)) if(is_call(tok_list[ptr].type))
{ {
nasal_ast tmp=node; nasal_ast tmp=std::move(node);
node.clear();
node.set_line(tok_list[ptr].line); node.set_line(tok_list[ptr].line);
node.set_type(ast_call); node.set_type(ast_call);
node.add_child(tmp); node.add_child(std::move(tmp));
} }
while(is_call(tok_list[ptr].type)) while(is_call(tok_list[ptr].type))
node.add_child(call_scalar()); node.add_child(call_scalar());
@ -744,9 +743,9 @@ nasal_ast nasal_parse::subvec()
{ {
nasal_ast tmp(node.get_line(),ast_subvec); nasal_ast tmp(node.get_line(),ast_subvec);
match(tok_colon); match(tok_colon);
tmp.add_child(node); tmp.add_child(std::move(node));
tmp.add_child((tok_list[ptr].type==tok_comma || tok_list[ptr].type==tok_rbracket)?nil_gen():calc()); tmp.add_child((tok_list[ptr].type==tok_comma || tok_list[ptr].type==tok_rbracket)?nil_gen():calc());
node=tmp; node=std::move(tmp);
} }
return node; return node;
} }
@ -905,7 +904,7 @@ nasal_ast nasal_parse::for_loop()
match(tok_semi,"expected \';\' in for(;;)"); match(tok_semi,"expected \';\' in for(;;)");
// conditional expression // conditional expression
if(tok_list[ptr].type==tok_eof) if(tok_list[ptr].type==tok_eof)
die(error_line,"expected conditional expression"); die(error_line,"expected conditional expr");
if(tok_list[ptr].type==tok_semi) if(tok_list[ptr].type==tok_semi)
node.add_child(null_node_gen()); node.add_child(null_node_gen());
else else
@ -976,7 +975,7 @@ nasal_ast nasal_parse::conditional()
tmp.add_child(calc()); tmp.add_child(calc());
match(tok_rcurve); match(tok_rcurve);
tmp.add_child(exprs_gen()); tmp.add_child(exprs_gen());
node.add_child(tmp); node.add_child(std::move(tmp));
// end of if-expression // end of if-expression
while(tok_list[ptr].type==tok_elsif) while(tok_list[ptr].type==tok_elsif)
{ {
@ -986,14 +985,14 @@ nasal_ast nasal_parse::conditional()
tmp.add_child(calc()); tmp.add_child(calc());
match(tok_rcurve); match(tok_rcurve);
tmp.add_child(exprs_gen()); tmp.add_child(exprs_gen());
node.add_child(tmp); node.add_child(std::move(tmp));
} }
if(tok_list[ptr].type==tok_else) if(tok_list[ptr].type==tok_else)
{ {
nasal_ast tmp(tok_list[ptr].line,ast_else); nasal_ast tmp(tok_list[ptr].line,ast_else);
match(tok_else); match(tok_else);
tmp.add_child(exprs_gen()); tmp.add_child(exprs_gen());
node.add_child(tmp); node.add_child(std::move(tmp));
} }
return node; return node;
} }

View File

@ -53,9 +53,9 @@ var curve1=func()
var shadow=["░","▒","▓","█","▀","▄","▐","▌"]; var shadow=["░","▒","▓","█","▀","▄","▐","▌"];
rand(100); rand(100);
var s=""; var s="";
for(var i=0;i<25;i+=1) for(var i=0;i<10;i+=1)
{ {
for(var j=0;j<100;j+=1) for(var j=0;j<40;j+=1)
s~=shadow[int(8*rand())]; s~=shadow[int(8*rand())];
s~='\n'; s~='\n';
} }
@ -66,28 +66,15 @@ var curve2=func()
var table=["╚","═","╝","╔","║","╗"]; var table=["╚","═","╝","╔","║","╗"];
rand(100); rand(100);
var s=""; var s="";
for(var i=0;i<25;i+=1) for(var i=0;i<10;i+=1)
{ {
for(var j=0;j<100;j+=1) for(var j=0;j<40;j+=1)
s~=table[int(6*rand())]; s~=table[int(6*rand())];
s~='\n'; s~='\n';
} }
print(s); print(s);
} }
var curve3=func() var curve3=func()
{
var block=["░░","▒▒","▓▓","██","▀▀","▄▄","▄▀","▀▄","▐▐","▌▌"];
rand(100);
var s="";
for(var i=0;i<25;i+=1)
{
for(var j=0;j<50;j+=1)
s~=block[int(10*rand())];
s~='\n';
}
print(s);
}
var curve4=func()
{ {
var s=["","","","","",""]; var s=["","","","","",""];
var cnt=0; var cnt=0;
@ -108,12 +95,12 @@ var curve4=func()
} }
return; return;
} }
var curve5=func() var curve4=func()
{ {
for(var loop=0;loop<100;loop+=1) var arr=[0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8];
for(var loop=0;loop<10;loop+=1)
{ {
var arr=[0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8]; for(var i=26;i>=0;i-=1)
for(var i=17;i>=0;i-=1)
{ {
var rand_index=int(i*rand()); var rand_index=int(i*rand());
(arr[i],arr[rand_index])=(arr[rand_index],arr[i]); (arr[i],arr[rand_index])=(arr[rand_index],arr[i]);
@ -128,9 +115,8 @@ var curve5=func()
return; return;
} }
trans_ttf("just for test"); trans_ttf("just for test");
trans_ttf("ValKmjolnir"); trans_ttf(" ValKmjolnir ");
curve1(); curve1();
curve2(); curve2();
curve3(); curve3();
curve4(); curve4();
curve5();

View File

@ -1,4 +1,6 @@
# Road check and auto pilot by ValKmjolnir # Road check and auto pilot by ValKmjolnir
import("lib.nas");
import("props.nas");
var dt=0.01; var dt=0.01;
var intergral=0; var intergral=0;
var derivative=0; var derivative=0;

View File

@ -171,7 +171,7 @@ var bf=func(program)
var c=chr(program[i]); var c=chr(program[i]);
if(c=='+' or c=='-') if(c=='+' or c=='-')
{ {
append(code,add); append(code,func_table[add]);
append(inum,0); append(inum,0);
for(;i<len;i+=1) for(;i<len;i+=1)
{ {
@ -188,7 +188,7 @@ var bf=func(program)
} }
elsif(c=='<' or c=='>') elsif(c=='<' or c=='>')
{ {
append(code,mov); append(code,func_table[mov]);
append(inum,0); append(inum,0);
for(;i<len;i+=1) for(;i<len;i+=1)
{ {
@ -205,17 +205,17 @@ var bf=func(program)
} }
elsif(c==',') elsif(c==',')
{ {
append(code,in); append(code,func_table[in]);
append(inum,0); append(inum,0);
} }
elsif(c=='.') elsif(c=='.')
{ {
append(code,out); append(code,func_table[out]);
append(inum,0); append(inum,0);
} }
elsif(c=='[') elsif(c=='[')
{ {
append(code,jf); append(code,func_table[jf]);
append(inum,0); append(inum,0);
append(stack,size(code)-1); append(stack,size(code)-1);
} }
@ -224,7 +224,7 @@ var bf=func(program)
if(!size(stack)) if(!size(stack))
die("lack ["); die("lack [");
var label=pop(stack); var label=pop(stack);
append(code,jt); append(code,func_table[jt]);
append(inum,label-1); append(inum,label-1);
inum[label]=size(code)-2; inum[label]=size(code)-2;
} }
@ -233,7 +233,7 @@ var bf=func(program)
die("lack ]"); die("lack ]");
len=size(code); len=size(code);
for(pc=0;pc<len;pc+=1) for(pc=0;pc<len;pc+=1)
func_table[code[pc]](); code[pc]();
return; return;
} }

View File

@ -20,7 +20,8 @@ var prt=func()
s~=map[i][j]; s~=map[i][j];
s~='\n'; s~='\n';
} }
print(s,'\n'); s~='----------\n';
print(s);
} }
var bfs=func(begin,end) var bfs=func(begin,end)
@ -54,8 +55,4 @@ var bfs=func(begin,end)
return; return;
} }
prt(); bfs([0,0],[9,9]);
var begin=[input(),input()];
var end=[input(),input()];
bfs(begin,end);
prt();

View File

@ -1 +1 @@
for(var i=0;i<4000000;i+=1); for(var i=0;i<4e6;i+=1);

View File

@ -23,12 +23,9 @@ var diffsigmoid=func(x)
return x*(1-x); return x*(1-x);
} }
var inum=2; var (inum,hnum,onum,lr)=(2,4,1,0.1);
var hnum=4;
var onum=1;
var lr=0.1;
var training_set=[[0,0],[0,1],[1,0],[1,1]]; var training_set=[[0,0],[0,1],[1,0],[1,1]];
var expect=[[0],[1],[1],[0]]; var expect=[0,1,1,0];
var hidden=[]; var hidden=[];
for(var i=0;i<hnum;i+=1) for(var i=0;i<hnum;i+=1)
@ -88,19 +85,12 @@ var run=func(vec)
} }
var get_error=func(x) var get_error=func(x)
{ {
var error=0; return 0.5*(expect[x]-output[0].out)*(expect[x]-output[0].out);
var expect_set=expect[x];
for(var i=0;i<onum;i+=1)
error+=(expect_set[i]-output[i].out)*(expect_set[i]-output[i].out);
error*=0.5;
return error;
} }
var backward=func(x) var backward=func(x)
{ {
var input=training_set[x]; var input=training_set[x];
var expect_set=expect[x]; output[0].diff=(expect[x]-output[0].out)*diffsigmoid(output[0].in);
for(var i=0;i<onum;i+=1)
output[i].diff=(expect_set[i]-output[i].out)*diffsigmoid(output[i].in);
for(var i=0;i<hnum;i+=1) for(var i=0;i<hnum;i+=1)
{ {
hidden[i].diff=0; hidden[i].diff=0;

View File

@ -1,18 +1,32 @@
import("lib.nas"); import("lib.nas");
var filename=["main.cpp","nasal_ast.h","nasal_builtin.h","nasal_codegen.h","nasal_gc.h","nasal_import.h","nasal_lexer.h","nasal_parse.h","nasal_vm.h","nasal.h"]; var filename=["main.cpp","nasal_ast.h","nasal_builtin.h","nasal_codegen.h","nasal_gc.h","nasal_import.h","nasal_lexer.h","nasal_parse.h","nasal_vm.h","nasal.h"];
var space=[" "," ","",""," "," "," "," "," "," "]; var space=[" "," ","",""," "," "," "," "," "," "];
var enter_cnt=func(s)
{
var (cnt,len,enter)=(0,size(s),'\n'[0]);
for(var i=0;i<len;i+=1)
cnt+=(s[i]==enter);
return cnt;
}
var semic_cnt=func(s)
{
var (cnt,len,semi)=(0,size(s),';'[0]);
for(var i=0;i<len;i+=1)
cnt+=(s[i]==semi);
return cnt;
}
func(){ func(){
var (bytes,cnt,semi)=(0,0,0); var (bytes,line,semi)=(0,0,0);
forindex(var i;filename) forindex(var i;filename)
{ {
var s=io.fin(filename[i]); var s=io.fin(filename[i]);
bytes+=size(s); bytes+=size(s);
var line_cnt=size(split('\n',s)); var line_cnt=enter_cnt(s);
var semi_cnt=size(split(';' ,s))-1; var semi_cnt=semic_cnt(s);
println(filename[i],space[i],'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi'); println(filename[i],space[i],'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi');
cnt +=line_cnt; line+=line_cnt;
semi+=semi_cnt; semi+=semi_cnt;
} }
println('total: | ',cnt,' \tline | ',semi,' \tsemi'); println('total: | ',line,' \tline | ',semi,' \tsemi');
println('bytes: | ',bytes,' bytes| ',int(bytes/1024),' \tkb'); println('bytes: | ',bytes,' bytes| ',int(bytes/1024),' \tkb');
}(); }();

View File

@ -1,5 +1,5 @@
import("lib.nas"); import("lib.nas");
# 并查集 # union set
var n=4; var n=4;
var input=[[0,1],[0,2],[1,2]]; var input=[[0,1],[0,2],[1,2]];
@ -23,8 +23,8 @@ var makeConnect=func(n,connections)
var cnt=n-1; var cnt=n-1;
var parent=[]; var parent=[];
setsize(parent,n); setsize(parent,n);
for(var i=0;i<size(connections);i+=1) foreach(var i;connections)
if(union_root(connections[i][0],connections[i][1],parent)) if(union_root(i[0],i[1],parent))
cnt-=1; cnt-=1;
return cnt; return cnt;
} }

View File

@ -1,62 +1,8 @@
import("lib.nas"); import("lib.nas");
var tok_type= var lexer=func(file)
{ {
tok_null:0, var _={s:io.fin(file),len:0,ptr:0,token:[]};
tok_num:1,
tok_str:2,
tok_id:3,
tok_for:4,
tok_forindex:5,
tok_foreach:6,
tok_while:7,
tok_var:8,
tok_func:9,
tok_break:10,
tok_continue:11,
tok_ret:12,
tok_if:13,
tok_elsif:14,
tok_else:15,
tok_nil:16,
tok_lcurve:17,
tok_rcurve:18,
tok_lbracket:19,
tok_rbracket:20,
tok_lbrace:21,
tok_rbrace:22,
tok_semi:23,
tok_and:24,
tok_or:25,
tok_comma:26,
tok_dot:27,
tok_ellipsis:28,
tok_quesmark:29,
tok_colon:30,
tok_add:31,
tok_sub:32,
tok_mult:33,
tok_div:34,
tok_link:35,
tok_not:36,
tok_eq:37,
tok_addeq:38,
tok_subeq:39,
tok_multeq:40,
tok_diveq:41,
tok_lnkeq:42,
tok_cmpeq:43,
tok_neq:44,
tok_less:45,
tok_leq:46,
tok_grt:47,
tok_geq:48,
tok_eof:49
};
var lexer=func(filename)
{
var _={s:io.fin(filename),len:0,ptr:0,token:[]};
_.len=size(_.s); _.len=size(_.s);
return return
{ {
@ -66,23 +12,24 @@ var lexer=func(filename)
_.ptr+=1; _.ptr+=1;
_.ptr+=1; _.ptr+=1;
}, },
idgen:func() id_gen:func()
{ {
var tmp=""; var tmp="";
while(_.ptr<_.len) while(_.ptr<_.len)
{ {
if('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z' var c=_.s[_.ptr];
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z' if(('a'[0]<=c and c<='z'[0])
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9' or ('A'[0]<=c and c<='Z'[0])
or chr(_.s[_.ptr])=='_') or ('0'[0]<=c and c<='9'[0])
tmp~=chr(_.s[_.ptr]); or c=='_'[0])
tmp~=chr(c);
else else
break; break;
_.ptr+=1; _.ptr+=1;
} }
append(_.token,tmp); append(_.token,tmp);
}, },
strgen:func() str_gen:func()
{ {
var str=""; var str="";
var mark=chr(_.s[_.ptr]); var mark=chr(_.s[_.ptr]);
@ -92,19 +39,20 @@ var lexer=func(filename)
if(chr(_.s[_.ptr])=='\\') if(chr(_.s[_.ptr])=='\\')
{ {
_.ptr+=1; _.ptr+=1;
if (chr(_.s[_.ptr])=='a' ) str~='\a'; var c=chr(_.s[_.ptr]);
elsif(chr(_.s[_.ptr])=='b' ) str~='\b'; if (c=='a' ) str~='\a';
elsif(chr(_.s[_.ptr])=='f' ) str~='\f'; elsif(c=='b' ) str~='\b';
elsif(chr(_.s[_.ptr])=='n' ) str~='\n'; elsif(c=='f' ) str~='\f';
elsif(chr(_.s[_.ptr])=='r' ) str~='\r'; elsif(c=='n' ) str~='\n';
elsif(chr(_.s[_.ptr])=='t' ) str~='\t'; elsif(c=='r' ) str~='\r';
elsif(chr(_.s[_.ptr])=='v' ) str~='\v'; elsif(c=='t' ) str~='\t';
elsif(chr(_.s[_.ptr])=='?' ) str~='?'; elsif(c=='v' ) str~='\v';
elsif(chr(_.s[_.ptr])=='0' ) str~='\0'; elsif(c=='?' ) str~='?';
elsif(chr(_.s[_.ptr])=='\\') str~='\\'; elsif(c=='0' ) str~='\0';
elsif(chr(_.s[_.ptr])=='\'') str~='\''; elsif(c=='\\') str~='\\';
elsif(chr(_.s[_.ptr])=='\"') str~='\"'; elsif(c=='\'') str~='\'';
else str~=chr(_.s[_.ptr]); elsif(c=='\"') str~='\"';
else str~=c;
} }
else else
str~=chr(_.s[_.ptr]); str~=chr(_.s[_.ptr]);
@ -113,88 +61,77 @@ var lexer=func(filename)
if(_.ptr>=_.len) if(_.ptr>=_.len)
print("read eof when generating string.\n"); print("read eof when generating string.\n");
_.ptr+=1; _.ptr+=1;
append(_.token,[tok_type.tok_str,str]); append(_.token,str);
}, },
numgen:func() num_gen:func()
{ {
var number=chr(_.s[_.ptr]); var number=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
if(chr(_.s[_.ptr])=='x') if(_.ptr<_.len and chr(_.s[_.ptr])=='x')
{ {
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and while(_.ptr<_.len and
('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='f' ('a'[0]<=_.s[_.ptr] and _.s[_.ptr]<='f'[0]
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9')) or '0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
append(_.token,[tok_type.tok_num,num(number)]); append(_.token,num(number));
return; return;
} }
elsif(chr(_.s[_.ptr])=='o') elsif(_.ptr<_.len and chr(_.s[_.ptr])=='o')
{ {
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='7')) while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='7'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
append(_.token,[tok_type.tok_num,num(number)]); append(_.token,num(number));
return; return;
} }
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9')) while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
{ {
number~=chr(_.s[_.ptr]); number~=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
} }
if(chr(_.s[_.ptr])=='.') if(_.ptr<_.len and chr(_.s[_.ptr])=='.')
number~=chr(_.s[_.ptr]);
else
{
append(_.token,[tok_type.tok_num,num(number)]);
return;
}
_.ptr+=1;
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
{ {
number~=chr(_.s[_.ptr]); number~=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
{
number~=chr(_.s[_.ptr]);
_.ptr+=1;
}
} }
if(chr(_.s[_.ptr])=='e' or chr(_.s[_.ptr])=='E') if(chr(_.s[_.ptr])=='e' or chr(_.s[_.ptr])=='E')
number~=chr(_.s[_.ptr]);
else
{
append(_.token,[tok_type.tok_num,num(number)]);
return;
}
_.ptr+=1;
if(chr(_.s[_.ptr])=='-' or chr(_.s[_.ptr])=='+')
{ {
number~=chr(_.s[_.ptr]); number~=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
if(chr(_.s[_.ptr])=='-' or chr(_.s[_.ptr])=='+')
{
number~=chr(_.s[_.ptr]);
_.ptr+=1;
}
while(_.ptr<_.len and ('0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
{
number~=chr(_.s[_.ptr]);
_.ptr+=1;
}
} }
while(_.ptr<_.len and ('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9')) var last_c=chr(number[-1]);
{ if(last_c=='.' or last_c=='e' or last_c=='E' or last_c=='-' or last_c=='+')
number~=chr(_.s[_.ptr]); println("error number: ",number);
_.ptr+=1; append(_.token,num(number));
}
append(_.token,[tok_type.tok_num,num(number)]);
}, },
oprgen:func() opr_gen:func()
{ {
var tmp=""; var c=chr(_.s[_.ptr]);
if(chr(_.s[_.ptr])=='+' if(c=='+' or c=='-' or c=='~' or c=='/' or c=='*' or c=='>' or c=='<' or c=='!' or c=='=')
or chr(_.s[_.ptr])=='-'
or chr(_.s[_.ptr])=='~'
or chr(_.s[_.ptr])=='/'
or chr(_.s[_.ptr])=='*'
or chr(_.s[_.ptr])=='>'
or chr(_.s[_.ptr])=='<'
or chr(_.s[_.ptr])=='!'
or chr(_.s[_.ptr])=='=')
{ {
tmp=chr(_.s[_.ptr]); var tmp=c;
_.ptr+=1; _.ptr+=1;
if(_.ptr<_.len and chr(_.s[_.ptr])=='=') if(_.ptr<_.len and chr(_.s[_.ptr])=='=')
{ {
@ -204,49 +141,42 @@ var lexer=func(filename)
append(_.token,tmp); append(_.token,tmp);
return; return;
} }
elsif(chr(_.s[_.ptr])=='.') elsif(c=='.')
{ {
if(_.ptr+2<_.len and _.s[_.ptr+1]=='.' and _.s[_.ptr+2]=='.') if(_.ptr+2<_.len and chr(_.s[_.ptr+1])=='.' and chr(_.s[_.ptr+2])=='.')
{ {
tmp='...'; append(_.token,"...");
_.ptr+=3; _.ptr+=3;
} }
else else
{ {
tmp='.'; append(_.token,".");
_.ptr+=1; _.ptr+=1;
} }
append(_.token,tmp);
return; return;
} }
elsif(chr(_.s[_.ptr])!=' ' elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and _.s[_.ptr]>0)
and chr(_.s[_.ptr])!='\t' append(_.token,c);
and chr(_.s[_.ptr])!='\n'
and chr(_.s[_.ptr])!='\r'
and chr(_.s[_.ptr])[0]>0)
tmp=chr(_.s[_.ptr]);
_.ptr+=1; _.ptr+=1;
if(size(tmp)) return;
append(_.token,tmp);
}, },
main:func() main:func()
{ {
while(_.ptr<_.len) while(_.ptr<_.len)
{ {
if(chr(_.s[_.ptr])=='#') var c=_.s[_.ptr];
if(c=='#'[0])
me.jmp_note(); me.jmp_note();
elsif('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z' elsif('a'[0]<=c and c<='z'[0]
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z' or 'A'[0]<=c and c<='Z'[0]
or chr(_.s[_.ptr])=='_') or c=='_'[0])
me.idgen(); me.id_gen();
elsif(chr(_.s[_.ptr])=='\'' or chr(_.s[_.ptr])=='\"') elsif(c=='\''[0] or c=='\"'[0])
me.strgen(); me.str_gen();
elsif('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9') elsif('0'[0]<=c and c<='9'[0])
me.numgen(); me.num_gen();
else else
me.oprgen(); me.opr_gen();
if(_.ptr>=_.len)
break;
} }
return; return;
}, },
@ -254,33 +184,8 @@ var lexer=func(filename)
}; };
} }
var parse=func(token) var nasal_lexer=lexer("test/lexer.nas");
{
var _={error:0,size:0,token:token,ast:nil};
_.size=size(token);
return
{
die:func(info)
{
_.error+=1;
println(info);
}
};
}
var ast=func()
{
var _={type:nil,child:[]};
return
{
set_type:func(type){_.type=type;},
get_type:func(){return _.type;},
add_child:func(child){append(_.child,child);},
get_child:func(){return _.child;}
};
}
var nasal_lexer=lexer(input());
nasal_lexer.main(); nasal_lexer.main();
println(nasal_lexer.get_token()); foreach(var tok;nasal_lexer.get_token())
var nasal_parse=parse(nasal_lexer.get_token()); print(tok,' ');
println();

View File

@ -46,8 +46,8 @@ func()
{ {
prt(map); prt(map);
var tmp=new_map(); var tmp=new_map();
forindex(var i;map) for(var i=0;i<15;i+=1)
forindex(var j;map[i]) for(var j=0;j<20;j+=1)
{ {
var cnt=0; var cnt=0;
foreach(var k;calc) foreach(var k;calc)

View File

@ -1,11 +1,8 @@
import("lib.nas"); import("lib.nas");
rand(time(0));
var sort=func(vec,left,right) var sort=func(vec,left,right)
{ {
if(left>=right) return nil; if(left>=right) return;
var L=left; var (L,R,tmp)=(left,right,vec[left]);
var R=right;
var tmp=vec[L];
while(left<right) while(left<right)
{ {
while(left<right and tmp<=vec[right]) while(left<right and tmp<=vec[right])
@ -13,19 +10,15 @@ var sort=func(vec,left,right)
while(left<right and tmp>=vec[left]) while(left<right and tmp>=vec[left])
left+=1; left+=1;
if(left!=right) if(left!=right)
{ (vec[left],vec[right])=(vec[right],vec[left]);
var t=vec[left];
vec[left]=vec[right];
vec[right]=t;
}
} }
vec[L]=vec[left]; (vec[L],vec[left])=(vec[left],tmp);
vec[left]=tmp;
sort(vec,L,left-1); sort(vec,L,left-1);
sort(vec,left+1,R); sort(vec,left+1,R);
return nil; return;
} }
var vec=[]; var vec=[];
rand(time(0));
for(var i=0;i<200;i+=1) for(var i=0;i<200;i+=1)
append(vec,int(rand()*1000)); append(vec,int(rand()*1000));
sort(vec,0,size(vec)-1); sort(vec,0,size(vec)-1);