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"
nasal_vm vm;
void help_interact()
{
std::cout
@ -31,7 +29,7 @@ void help_cmd()
void info()
{
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"
<<">> Code: https://github.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_import import;
nasal_codegen codegen;
nasal_vm vm;
lexer.openfile(file);
lexer.scanner();
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")))
{
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")))
help_cmd();

View File

@ -57,10 +57,12 @@ public:
nasal_ast(){line=0;type=ast_null;}
nasal_ast(int l,int t){line=l;type=t;}
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 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_type(int t){type=t;}
void set_str(std::string& s){str=s;}
@ -82,6 +84,16 @@ nasal_ast::nasal_ast(const nasal_ast& tmp)
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)
{
line=tmp.line;
@ -92,6 +104,16 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
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()
{
line=0;
@ -104,11 +126,10 @@ void nasal_ast::clear()
void nasal_ast::print_ast(int depth)
{
std::string indentation="";
for(int i=0;i<depth;++i)
indentation+="| ";
std::cout<<indentation<<ast_name[type];
if(type==ast_str || type==ast_id || type==ast_dynamic_id || type==ast_callh)
std::cout<<"| ";
std::cout<<ast_name[type];
if(type==ast_str || type==ast_id || type==ast_default_arg || type==ast_dynamic_id || type==ast_callh)
std::cout<<":"<<str;
else if(type==ast_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)
{
calc_gen(tmp.get_children()[1]);
std::string& str=tmp.get_children()[0].get_str();
calc_gen(tmp.get_children()[0]);
std::string& str=tmp.get_str();
regist_string(str);
add_sym(str);
gen(op_defpara,string_table[str]);

View File

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

View File

@ -48,7 +48,7 @@ private:
std::vector<token> error_token;
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
void die(int,std::string);
void die(int,std::string&&);
void match(int type,const char* err_info="");
bool check_comma(int*);
bool check_multi_def();
@ -140,7 +140,7 @@ void nasal_parse::main_process()
<<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
return;
}
void nasal_parse::die(int line,std::string info)
void nasal_parse::die(int line,std::string&& info)
{
++error;
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);
if(tok_list[ptr].type==tok_eq)
{
special_arg.add_child(tmp);
match(tok_eq);
special_arg.add_child(calc());
special_arg=std::move(tmp);
special_arg.set_type(ast_default_arg);
special_arg.add_child(calc());
}
else
{
match(tok_ellipsis);
special_arg=tmp;
special_arg=std::move(tmp);
special_arg.set_type(ast_dynamic_id);
}
node.add_child(special_arg);
node.add_child(std::move(special_arg));
}
else
node.add_child(tmp);
node.add_child(std::move(tmp));
if(tok_list[ptr].type==tok_comma)
match(tok_comma);
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())
{
case ast_id: args_format+="val";break;
case ast_default_arg: args_format+="val=scalar";break;
case ast_dynamic_id: args_format+="val...";break;
case ast_id: args_format+=tmp.get_str();break;
case ast_default_arg: args_format+=tmp.get_str()+"=val";break;
case ast_dynamic_id: args_format+=tmp.get_str()+"...";break;
}
args_format+=",)"[&tmp==&node.get_children().back()];
}
@ -433,7 +433,7 @@ nasal_ast nasal_parse::args_gen()
{
case ast_dynamic_id:
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))
die(tmp.get_line(),"parameter's name repeats: "+new_name);
@ -518,21 +518,21 @@ nasal_ast nasal_parse::calc()
// trinocular calculation
nasal_ast tmp(tok_list[ptr].line,ast_trino);
match(tok_quesmark);
tmp.add_child(node);
tmp.add_child(std::move(node));
tmp.add_child(calc());
match(tok_colon);
tmp.add_child(calc());
node=tmp;
node=std::move(tmp);
}
else if(tok_eq<=tok_list[ptr].type && tok_list[ptr].type<=tok_lnkeq)
{
check_memory_reachable(node);
// 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);
tmp.add_child(node);
tmp.add_child(std::move(node));
match(tok_list[ptr].type);
tmp.add_child(calc());
node=tmp;
node=std::move(tmp);
}
return node;
}
@ -542,10 +542,10 @@ nasal_ast nasal_parse::or_expr()
while(tok_list[ptr].type==tok_or)
{
nasal_ast tmp(tok_list[ptr].line,ast_or);
tmp.add_child(node);
tmp.add_child(std::move(node));
match(tok_or);
tmp.add_child(and_expr());
node=tmp;
node=std::move(tmp);
}
return node;
}
@ -555,10 +555,10 @@ nasal_ast nasal_parse::and_expr()
while(tok_list[ptr].type==tok_and)
{
nasal_ast tmp(tok_list[ptr].line,ast_and);
tmp.add_child(node);
tmp.add_child(std::move(node));
match(tok_and);
tmp.add_child(cmp_expr());
node=tmp;
node=std::move(tmp);
}
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
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);
tmp.add_child(additive_expr());
node=tmp;
node=std::move(tmp);
}
return node;
}
@ -588,10 +588,10 @@ nasal_ast nasal_parse::additive_expr()
case tok_sub: tmp.set_type(ast_sub); 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);
tmp.add_child(multive_expr());
node=tmp;
node=std::move(tmp);
}
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)
{
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);
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;
}
@ -667,11 +667,10 @@ nasal_ast nasal_parse::scalar()
}
if(is_call(tok_list[ptr].type))
{
nasal_ast tmp=node;
node.clear();
nasal_ast tmp=std::move(node);
node.set_line(tok_list[ptr].line);
node.set_type(ast_call);
node.add_child(tmp);
node.add_child(std::move(tmp));
}
while(is_call(tok_list[ptr].type))
node.add_child(call_scalar());
@ -744,9 +743,9 @@ nasal_ast nasal_parse::subvec()
{
nasal_ast tmp(node.get_line(),ast_subvec);
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());
node=tmp;
node=std::move(tmp);
}
return node;
}
@ -905,7 +904,7 @@ nasal_ast nasal_parse::for_loop()
match(tok_semi,"expected \';\' in for(;;)");
// conditional expression
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)
node.add_child(null_node_gen());
else
@ -976,7 +975,7 @@ nasal_ast nasal_parse::conditional()
tmp.add_child(calc());
match(tok_rcurve);
tmp.add_child(exprs_gen());
node.add_child(tmp);
node.add_child(std::move(tmp));
// end of if-expression
while(tok_list[ptr].type==tok_elsif)
{
@ -986,14 +985,14 @@ nasal_ast nasal_parse::conditional()
tmp.add_child(calc());
match(tok_rcurve);
tmp.add_child(exprs_gen());
node.add_child(tmp);
node.add_child(std::move(tmp));
}
if(tok_list[ptr].type==tok_else)
{
nasal_ast tmp(tok_list[ptr].line,ast_else);
match(tok_else);
tmp.add_child(exprs_gen());
node.add_child(tmp);
node.add_child(std::move(tmp));
}
return node;
}

View File

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

View File

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

View File

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

View File

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

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

View File

@ -1,18 +1,32 @@
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 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(){
var (bytes,cnt,semi)=(0,0,0);
var (bytes,line,semi)=(0,0,0);
forindex(var i;filename)
{
var s=io.fin(filename[i]);
bytes+=size(s);
var line_cnt=size(split('\n',s));
var semi_cnt=size(split(';' ,s))-1;
var line_cnt=enter_cnt(s);
var semi_cnt=semic_cnt(s);
println(filename[i],space[i],'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi');
cnt +=line_cnt;
line+=line_cnt;
semi+=semi_cnt;
}
println('total: | ',cnt,' \tline | ',semi,' \tsemi');
println('total: | ',line,' \tline | ',semi,' \tsemi');
println('bytes: | ',bytes,' bytes| ',int(bytes/1024),' \tkb');
}();

View File

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

View File

@ -1,62 +1,8 @@
import("lib.nas");
var tok_type=
var lexer=func(file)
{
tok_null:0,
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:[]};
var _={s:io.fin(file),len:0,ptr:0,token:[]};
_.len=size(_.s);
return
{
@ -66,23 +12,24 @@ var lexer=func(filename)
_.ptr+=1;
_.ptr+=1;
},
idgen:func()
id_gen:func()
{
var tmp="";
while(_.ptr<_.len)
{
if('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z'
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z'
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'
or chr(_.s[_.ptr])=='_')
tmp~=chr(_.s[_.ptr]);
var c=_.s[_.ptr];
if(('a'[0]<=c and c<='z'[0])
or ('A'[0]<=c and c<='Z'[0])
or ('0'[0]<=c and c<='9'[0])
or c=='_'[0])
tmp~=chr(c);
else
break;
_.ptr+=1;
}
append(_.token,tmp);
},
strgen:func()
str_gen:func()
{
var str="";
var mark=chr(_.s[_.ptr]);
@ -92,19 +39,20 @@ var lexer=func(filename)
if(chr(_.s[_.ptr])=='\\')
{
_.ptr+=1;
if (chr(_.s[_.ptr])=='a' ) str~='\a';
elsif(chr(_.s[_.ptr])=='b' ) str~='\b';
elsif(chr(_.s[_.ptr])=='f' ) str~='\f';
elsif(chr(_.s[_.ptr])=='n' ) str~='\n';
elsif(chr(_.s[_.ptr])=='r' ) str~='\r';
elsif(chr(_.s[_.ptr])=='t' ) str~='\t';
elsif(chr(_.s[_.ptr])=='v' ) str~='\v';
elsif(chr(_.s[_.ptr])=='?' ) str~='?';
elsif(chr(_.s[_.ptr])=='0' ) str~='\0';
elsif(chr(_.s[_.ptr])=='\\') str~='\\';
elsif(chr(_.s[_.ptr])=='\'') str~='\'';
elsif(chr(_.s[_.ptr])=='\"') str~='\"';
else str~=chr(_.s[_.ptr]);
var c=chr(_.s[_.ptr]);
if (c=='a' ) str~='\a';
elsif(c=='b' ) str~='\b';
elsif(c=='f' ) str~='\f';
elsif(c=='n' ) str~='\n';
elsif(c=='r' ) str~='\r';
elsif(c=='t' ) str~='\t';
elsif(c=='v' ) str~='\v';
elsif(c=='?' ) str~='?';
elsif(c=='0' ) str~='\0';
elsif(c=='\\') str~='\\';
elsif(c=='\'') str~='\'';
elsif(c=='\"') str~='\"';
else str~=c;
}
else
str~=chr(_.s[_.ptr]);
@ -113,88 +61,77 @@ var lexer=func(filename)
if(_.ptr>=_.len)
print("read eof when generating string.\n");
_.ptr+=1;
append(_.token,[tok_type.tok_str,str]);
append(_.token,str);
},
numgen:func()
num_gen:func()
{
var number=chr(_.s[_.ptr]);
_.ptr+=1;
if(chr(_.s[_.ptr])=='x')
if(_.ptr<_.len and chr(_.s[_.ptr])=='x')
{
_.ptr+=1;
while(_.ptr<_.len and
('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='f'
or '0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9'))
('a'[0]<=_.s[_.ptr] and _.s[_.ptr]<='f'[0]
or '0'[0]<=_.s[_.ptr] and _.s[_.ptr]<='9'[0]))
{
number~=chr(_.s[_.ptr]);
_.ptr+=1;
}
append(_.token,[tok_type.tok_num,num(number)]);
append(_.token,num(number));
return;
}
elsif(chr(_.s[_.ptr])=='o')
elsif(_.ptr<_.len and chr(_.s[_.ptr])=='o')
{
_.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]);
_.ptr+=1;
}
append(_.token,[tok_type.tok_num,num(number)]);
append(_.token,num(number));
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]);
_.ptr+=1;
}
if(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'))
if(_.ptr<_.len and 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;
}
}
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]);
_.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'))
{
number~=chr(_.s[_.ptr]);
_.ptr+=1;
}
append(_.token,[tok_type.tok_num,num(number)]);
var last_c=chr(number[-1]);
if(last_c=='.' or last_c=='e' or last_c=='E' or last_c=='-' or last_c=='+')
println("error number: ",number);
append(_.token,num(number));
},
oprgen:func()
opr_gen:func()
{
var tmp="";
if(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])=='!'
or chr(_.s[_.ptr])=='=')
var c=chr(_.s[_.ptr]);
if(c=='+' or c=='-' or c=='~' or c=='/' or c=='*' or c=='>' or c=='<' or c=='!' or c=='=')
{
tmp=chr(_.s[_.ptr]);
var tmp=c;
_.ptr+=1;
if(_.ptr<_.len and chr(_.s[_.ptr])=='=')
{
@ -204,49 +141,42 @@ var lexer=func(filename)
append(_.token,tmp);
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;
}
else
{
tmp='.';
append(_.token,".");
_.ptr+=1;
}
append(_.token,tmp);
return;
}
elsif(chr(_.s[_.ptr])!=' '
and chr(_.s[_.ptr])!='\t'
and chr(_.s[_.ptr])!='\n'
and chr(_.s[_.ptr])!='\r'
and chr(_.s[_.ptr])[0]>0)
tmp=chr(_.s[_.ptr]);
elsif(c!=' ' and c!='\t' and c!='\n' and c!='\r' and _.s[_.ptr]>0)
append(_.token,c);
_.ptr+=1;
if(size(tmp))
append(_.token,tmp);
return;
},
main:func()
{
while(_.ptr<_.len)
{
if(chr(_.s[_.ptr])=='#')
var c=_.s[_.ptr];
if(c=='#'[0])
me.jmp_note();
elsif('a'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='z'
or 'A'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='Z'
or chr(_.s[_.ptr])=='_')
me.idgen();
elsif(chr(_.s[_.ptr])=='\'' or chr(_.s[_.ptr])=='\"')
me.strgen();
elsif('0'<=chr(_.s[_.ptr]) and chr(_.s[_.ptr])<='9')
me.numgen();
elsif('a'[0]<=c and c<='z'[0]
or 'A'[0]<=c and c<='Z'[0]
or c=='_'[0])
me.id_gen();
elsif(c=='\''[0] or c=='\"'[0])
me.str_gen();
elsif('0'[0]<=c and c<='9'[0])
me.num_gen();
else
me.oprgen();
if(_.ptr>=_.len)
break;
me.opr_gen();
}
return;
},
@ -254,33 +184,8 @@ var lexer=func(filename)
};
}
var parse=func(token)
{
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());
var nasal_lexer=lexer("test/lexer.nas");
nasal_lexer.main();
println(nasal_lexer.get_token());
var nasal_parse=parse(nasal_lexer.get_token());
foreach(var tok;nasal_lexer.get_token())
print(tok,' ');
println();

View File

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

View File

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