optimize codes
This commit is contained in:
parent
46716620e3
commit
630c99c39a
118
nasal_ast.h
118
nasal_ast.h
|
@ -4,63 +4,63 @@
|
||||||
enum ast_node
|
enum ast_node
|
||||||
{
|
{
|
||||||
ast_null=0,
|
ast_null=0,
|
||||||
ast_root, // mark the root node of ast
|
ast_root, // mark the root node of ast
|
||||||
ast_block, // expression block
|
ast_block, // expression block
|
||||||
ast_file, // used to store which file the sub-tree is on
|
ast_file, // used to store which file the sub-tree is on, only used in main block
|
||||||
ast_nil, // nil keyword
|
ast_nil, // nil keyword
|
||||||
ast_num, // number, basic value type
|
ast_num, // number, basic value type
|
||||||
ast_str, // string, basic value type
|
ast_str, // string, basic value type
|
||||||
ast_id, // identifier
|
ast_id, // identifier
|
||||||
ast_func, // func keyword
|
ast_func, // func keyword
|
||||||
ast_hash, // hash, basic value type
|
ast_hash, // hash, basic value type
|
||||||
ast_vec, // vector, basic value type
|
ast_vec, // vector, basic value type
|
||||||
ast_hashmember,// elements in hashmap
|
ast_hashmember, // elements in hashmap
|
||||||
ast_call, // mark a sub-tree of calling an identifier
|
ast_call, // mark a sub-tree of calling an identifier
|
||||||
ast_callh, // id.name
|
ast_callh, // id.name
|
||||||
ast_callv, // id[index]
|
ast_callv, // id[index]
|
||||||
ast_callf, // id()
|
ast_callf, // id()
|
||||||
ast_subvec, // id[index:index]
|
ast_subvec, // id[index:index]
|
||||||
ast_args, // mark a sub-tree of function parameters
|
ast_args, // mark a sub-tree of function parameters
|
||||||
ast_default, // default parameter
|
ast_default, // default parameter
|
||||||
ast_dynamic, // dynamic parameter
|
ast_dynamic, // dynamic parameter
|
||||||
ast_and, // and keyword
|
ast_and, // and keyword
|
||||||
ast_or, // or keyword
|
ast_or, // or keyword
|
||||||
ast_equal, // =
|
ast_equal, // =
|
||||||
ast_addeq, // +=
|
ast_addeq, // +=
|
||||||
ast_subeq, // -=
|
ast_subeq, // -=
|
||||||
ast_multeq, // *=
|
ast_multeq, // *=
|
||||||
ast_diveq, // /=
|
ast_diveq, // /=
|
||||||
ast_lnkeq, // ~=
|
ast_lnkeq, // ~=
|
||||||
ast_cmpeq, // ==
|
ast_cmpeq, // ==
|
||||||
ast_neq, // !=
|
ast_neq, // !=
|
||||||
ast_less, // <
|
ast_less, // <
|
||||||
ast_leq, // <=
|
ast_leq, // <=
|
||||||
ast_grt, // >
|
ast_grt, // >
|
||||||
ast_geq, // >=
|
ast_geq, // >=
|
||||||
ast_add, // +
|
ast_add, // +
|
||||||
ast_sub, // -
|
ast_sub, // -
|
||||||
ast_mult, // *
|
ast_mult, // *
|
||||||
ast_div, // /
|
ast_div, // /
|
||||||
ast_link, // ~
|
ast_link, // ~
|
||||||
ast_neg, // -
|
ast_neg, // -
|
||||||
ast_not, // ~
|
ast_not, // ~
|
||||||
ast_trino, // ?:
|
ast_trino, // ?:
|
||||||
ast_for, // for keyword
|
ast_for, // for keyword
|
||||||
ast_forindex,// forindex keyword
|
ast_forindex, // forindex keyword
|
||||||
ast_foreach, // foreach keyword
|
ast_foreach, // foreach keyword
|
||||||
ast_while, // while
|
ast_while, // while
|
||||||
ast_new_iter,// iterator, used in forindex/foreach
|
ast_new_iter, // iterator, used in forindex/foreach
|
||||||
ast_conditional,// mark a sub-tree of conditional expression
|
ast_conditional, // mark a sub-tree of conditional expression
|
||||||
ast_if, // if keyword
|
ast_if, // if keyword
|
||||||
ast_elsif, // elsif keyword
|
ast_elsif, // elsif keyword
|
||||||
ast_else, // else keyword
|
ast_else, // else keyword
|
||||||
ast_multi_id,// multi identifiers sub-tree
|
ast_multi_id, // multi identifiers sub-tree
|
||||||
ast_multi_scalar,// multi value sub-tree
|
ast_multi_scalar,// multi value sub-tree
|
||||||
ast_def, // definition
|
ast_def, // definition
|
||||||
ast_multi_assign,// multi assignment sub-tree
|
ast_multi_assign,// multi assignment sub-tree
|
||||||
ast_continue,// continue keyword
|
ast_continue, // continue keyword, only used in loop
|
||||||
ast_break, // break keyword
|
ast_break, // break keyword, only used in loop
|
||||||
ast_ret // return keyword
|
ast_ret // return keyword, only used in function block
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* ast_name[]=
|
const char* ast_name[]=
|
||||||
|
@ -228,10 +228,18 @@ void nasal_ast::print(int depth,bool last=false)
|
||||||
if(last && depth)
|
if(last && depth)
|
||||||
intentation.back()=" ";
|
intentation.back()=" ";
|
||||||
else if(!last && depth)
|
else if(!last && depth)
|
||||||
|
#ifdef _WIN32
|
||||||
|
intentation.back()="| ";
|
||||||
|
#else
|
||||||
intentation.back()="│ ";
|
intentation.back()="│ ";
|
||||||
|
#endif
|
||||||
for(uint32_t i=0;i<_child.size();++i)
|
for(uint32_t i=0;i<_child.size();++i)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
intentation.push_back(i==_child.size()-1?"`-":"|-");
|
||||||
|
#else
|
||||||
intentation.push_back(i==_child.size()-1?"└─":"├─");
|
intentation.push_back(i==_child.size()-1?"└─":"├─");
|
||||||
|
#endif
|
||||||
_child[i].print(depth+1,i==_child.size()-1);
|
_child[i].print(depth+1,i==_child.size()-1);
|
||||||
intentation.pop_back();
|
intentation.pop_back();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ nas_native(builtin_platform);
|
||||||
|
|
||||||
nasal_ref builtin_err(const char* func_name,std::string info)
|
nasal_ref builtin_err(const char* func_name,std::string info)
|
||||||
{
|
{
|
||||||
std::cout<<"[vm] "<<func_name<<": "<<info<<".\n";
|
std::cerr<<"[vm] "<<func_name<<": "<<info<<".\n";
|
||||||
return {vm_none,nullptr};
|
return {vm_none,nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +574,7 @@ nasal_ref builtin_die(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
if(str.type!=vm_str)
|
if(str.type!=vm_str)
|
||||||
return builtin_err("die","\"str\" must be string");
|
return builtin_err("die","\"str\" must be string");
|
||||||
std::cout<<"[vm] error: "<<*str.str()<<'\n';
|
std::cerr<<"[vm] error: "<<*str.str()<<'\n';
|
||||||
return nasal_ref(vm_none);
|
return nasal_ref(vm_none);
|
||||||
}
|
}
|
||||||
nasal_ref builtin_type(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_type(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
|
|
|
@ -205,7 +205,7 @@ private:
|
||||||
std::vector<std::string> global; // global : max 4095 values
|
std::vector<std::string> global; // global : max 4095 values
|
||||||
std::list<std::vector<std::string>> local; // local : max 32768 upvalues 65536 values
|
std::list<std::vector<std::string>> local; // local : max 32768 upvalues 65536 values
|
||||||
|
|
||||||
void die(const std::string&,const uint32_t);
|
void die(std::string,const uint32_t);
|
||||||
void regist_number(const double);
|
void regist_number(const double);
|
||||||
void regist_string(const std::string&);
|
void regist_string(const std::string&);
|
||||||
void find_symbol(const nasal_ast&);
|
void find_symbol(const nasal_ast&);
|
||||||
|
@ -255,10 +255,10 @@ public:
|
||||||
const std::vector<opcode>& get_code() const {return code;}
|
const std::vector<opcode>& get_code() const {return code;}
|
||||||
};
|
};
|
||||||
|
|
||||||
void nasal_codegen::die(const std::string& info,const uint32_t line)
|
void nasal_codegen::die(std::string info,const uint32_t line)
|
||||||
{
|
{
|
||||||
nerr.load(file[fileindex]);
|
nerr.load(file[fileindex]);
|
||||||
nerr.err("code",line,info.c_str());
|
nerr.err("code",line,info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::regist_number(const double num)
|
void nasal_codegen::regist_number(const double num)
|
||||||
|
@ -455,8 +455,6 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
|
||||||
void nasal_codegen::call_gen(const nasal_ast& ast)
|
void nasal_codegen::call_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
if(code.empty())
|
|
||||||
std::cout<<"warning\n";
|
|
||||||
if(code.back().op==op_callb)
|
if(code.back().op==op_callb)
|
||||||
return;
|
return;
|
||||||
int child_size=ast.size();
|
int child_size=ast.size();
|
||||||
|
@ -1068,6 +1066,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
switch(tmp.type())
|
switch(tmp.type())
|
||||||
{
|
{
|
||||||
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
||||||
|
case ast_file:fileindex=tmp.num();break; // special node type in main block
|
||||||
case ast_def:def_gen(tmp);break;
|
case ast_def:def_gen(tmp);break;
|
||||||
case ast_multi_assign:multi_assign_gen(tmp);break;
|
case ast_multi_assign:multi_assign_gen(tmp);break;
|
||||||
case ast_conditional:conditional_gen(tmp);break;
|
case ast_conditional:conditional_gen(tmp);break;
|
||||||
|
@ -1151,68 +1150,9 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
||||||
file=import.get_file().data();
|
file=import.get_file().data();
|
||||||
in_iterloop.push(0);
|
in_iterloop.push(0);
|
||||||
|
|
||||||
// search symbols first
|
find_symbol(parse.ast()); // search symbols first
|
||||||
find_symbol(parse.ast());
|
|
||||||
gen(op_intg,global.size(),0);
|
gen(op_intg,global.size(),0);
|
||||||
for(auto& tmp:parse.ast().child())
|
block_gen(parse.ast()); // generate main block
|
||||||
{
|
|
||||||
switch(tmp.type())
|
|
||||||
{
|
|
||||||
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
|
|
||||||
case ast_file:fileindex=tmp.num();break;
|
|
||||||
case ast_def:def_gen(tmp);break;
|
|
||||||
case ast_multi_assign:multi_assign_gen(tmp);break;
|
|
||||||
case ast_conditional:conditional_gen(tmp);break;
|
|
||||||
case ast_while:
|
|
||||||
case ast_for:
|
|
||||||
case ast_forindex:
|
|
||||||
case ast_foreach:loop_gen(tmp);break;
|
|
||||||
case ast_equal:
|
|
||||||
if(tmp[0].type()==ast_id)
|
|
||||||
{
|
|
||||||
calc_gen(tmp[1]);
|
|
||||||
mcall_id(tmp[0]);
|
|
||||||
// only the first mcall_id can use load
|
|
||||||
if(code.back().op==op_mcalll)
|
|
||||||
code.back().op=op_loadl;
|
|
||||||
else if(code.back().op==op_mupval)
|
|
||||||
code.back().op=op_loadu;
|
|
||||||
else
|
|
||||||
code.back().op=op_loadg;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
calc_gen(tmp);
|
|
||||||
gen(op_pop,0,tmp.line());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ast_id:
|
|
||||||
case ast_vec:
|
|
||||||
case ast_hash:
|
|
||||||
case ast_call:
|
|
||||||
case ast_addeq:
|
|
||||||
case ast_subeq:
|
|
||||||
case ast_multeq:
|
|
||||||
case ast_diveq:
|
|
||||||
case ast_lnkeq:
|
|
||||||
case ast_neg:
|
|
||||||
case ast_not:
|
|
||||||
case ast_add:
|
|
||||||
case ast_sub:
|
|
||||||
case ast_mult:
|
|
||||||
case ast_div:
|
|
||||||
case ast_link:
|
|
||||||
case ast_cmpeq:
|
|
||||||
case ast_neq:
|
|
||||||
case ast_leq:
|
|
||||||
case ast_less:
|
|
||||||
case ast_geq:
|
|
||||||
case ast_grt:
|
|
||||||
case ast_or:
|
|
||||||
case ast_and:
|
|
||||||
case ast_trino:calc_gen(tmp);gen(op_pop,0,tmp.line());break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gen(op_exit,0,0);
|
gen(op_exit,0,0);
|
||||||
if(global.size()>=STACK_MAX_DEPTH)
|
if(global.size()>=STACK_MAX_DEPTH)
|
||||||
die("too many global variants: "+std::to_string(global.size())+".",0);
|
die("too many global variants: "+std::to_string(global.size())+".",0);
|
||||||
|
|
|
@ -56,7 +56,7 @@ uint16_t nasal_dbg::get_fileindex(const std::string& filename)
|
||||||
|
|
||||||
void nasal_dbg::err()
|
void nasal_dbg::err()
|
||||||
{
|
{
|
||||||
std::cout
|
std::cerr
|
||||||
<<"incorrect command\n"
|
<<"incorrect command\n"
|
||||||
<<"input \'h\' to get help\n";
|
<<"input \'h\' to get help\n";
|
||||||
}
|
}
|
||||||
|
|
17
nasal_err.h
17
nasal_err.h
|
@ -13,7 +13,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
void load(const std::string& f)
|
void load(const std::string& f)
|
||||||
{
|
{
|
||||||
if(file==f)
|
if(file==f) // don't need to load a loaded file
|
||||||
return;
|
return;
|
||||||
file=f;
|
file=f;
|
||||||
res.clear();
|
res.clear();
|
||||||
|
@ -48,33 +48,32 @@ public:
|
||||||
void err(const char* stage,const std::string& info)
|
void err(const char* stage,const std::string& info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
std::cout<<"["<<stage<<"] "<<info<<'\n';
|
std::cerr<<"["<<stage<<"] "<<info<<'\n';
|
||||||
}
|
}
|
||||||
void err(const char* stage,uint32_t line,uint32_t column,const std::string& info)
|
void err(const char* stage,uint32_t line,uint32_t column,const std::string& info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
if(!line)
|
if(!line)
|
||||||
{
|
{
|
||||||
std::cout<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
std::cerr<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout<<"["<<stage<<"] "<<file<<":"<<line<<":"<<column<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<":"<<column<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
||||||
for(int i=0;i<(int)column-1;++i)
|
for(int i=0;i<(int)column-1;++i)
|
||||||
std::cout<<char(" \t"[res[line-1][i]=='\t']);
|
std::cerr<<char(" \t"[res[line-1][i]=='\t']);
|
||||||
std::cout<<"^\n";
|
std::cerr<<"^\n";
|
||||||
}
|
}
|
||||||
void err(const char* stage,uint32_t line,const std::string& info)
|
void err(const char* stage,uint32_t line,const std::string& info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
if(!line)
|
if(!line)
|
||||||
{
|
{
|
||||||
std::cout<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
std::cerr<<"["<<stage<<"] "<<file<<": "<<info<<'\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout<<"["<<stage<<"] "<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
||||||
}
|
}
|
||||||
void chkerr(){if(error)std::exit(1);}
|
void chkerr(){if(error)std::exit(1);}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -295,12 +295,9 @@ nasal_val::~nasal_val()
|
||||||
}
|
}
|
||||||
type=vm_nil;
|
type=vm_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
double nasal_ref::to_number()
|
double nasal_ref::to_number()
|
||||||
{
|
{
|
||||||
if(type==vm_str)
|
return type!=vm_str?value.num:str2num(str()->c_str());
|
||||||
return str2num(str()->c_str());
|
|
||||||
return value.num;
|
|
||||||
}
|
}
|
||||||
std::string nasal_ref::to_string()
|
std::string nasal_ref::to_string()
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,7 +113,7 @@ private:
|
||||||
std::vector<token> tokens;
|
std::vector<token> tokens;
|
||||||
|
|
||||||
uint32_t get_type(const std::string&);
|
uint32_t get_type(const std::string&);
|
||||||
void die(const char* info){nerr.err("lexer",line,column,info);};
|
void die(std::string info){nerr.err("lexer",line,column,info);};
|
||||||
void open(const std::string&);
|
void open(const std::string&);
|
||||||
std::string id_gen();
|
std::string id_gen();
|
||||||
std::string num_gen();
|
std::string num_gen();
|
||||||
|
@ -165,7 +165,7 @@ std::string nasal_lexer::num_gen()
|
||||||
str+=res[ptr++];
|
str+=res[ptr++];
|
||||||
column+=str.length();
|
column+=str.length();
|
||||||
if(str.length()<3)// "0x"
|
if(str.length()<3)// "0x"
|
||||||
die("invalid number.");
|
die("invalid number:"+str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
// generate oct number
|
// generate oct number
|
||||||
|
@ -177,7 +177,7 @@ std::string nasal_lexer::num_gen()
|
||||||
str+=res[ptr++];
|
str+=res[ptr++];
|
||||||
column+=str.length();
|
column+=str.length();
|
||||||
if(str.length()<3)// "0o"
|
if(str.length()<3)// "0o"
|
||||||
die("invalid number.");
|
die("invalid number:"+str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
// generate dec number
|
// generate dec number
|
||||||
|
@ -194,7 +194,7 @@ std::string nasal_lexer::num_gen()
|
||||||
if(str.back()=='.')
|
if(str.back()=='.')
|
||||||
{
|
{
|
||||||
column+=str.length();
|
column+=str.length();
|
||||||
die("invalid number.");
|
die("invalid number:"+str);
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ std::string nasal_lexer::num_gen()
|
||||||
if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+')
|
if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+')
|
||||||
{
|
{
|
||||||
column+=str.length();
|
column+=str.length();
|
||||||
die("invalid number.");
|
die("invalid number:"+str);
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ void nasal_lexer::scan(const std::string& file)
|
||||||
++column;
|
++column;
|
||||||
uint32_t type=get_type(str);
|
uint32_t type=get_type(str);
|
||||||
if(!type)
|
if(!type)
|
||||||
die("invalid operator.");
|
die("invalid operator:"+str);
|
||||||
tokens.push_back({line,column,type,str});
|
tokens.push_back({line,column,type,str});
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ private:
|
||||||
nasal_ast root;
|
nasal_ast root;
|
||||||
nasal_err& nerr;
|
nasal_err& nerr;
|
||||||
|
|
||||||
void die(uint32_t,const std::string&);
|
void die(uint32_t,std::string);
|
||||||
void match(uint32_t type,const char* info=nullptr);
|
void match(uint32_t type,const char* info=nullptr);
|
||||||
bool check_comma(const uint32_t*);
|
bool check_comma(const uint32_t*);
|
||||||
bool check_multi_scalar();
|
bool check_multi_scalar();
|
||||||
|
@ -121,7 +121,7 @@ void nasal_parse::compile(const nasal_lexer& lexer)
|
||||||
}
|
}
|
||||||
nerr.chkerr();
|
nerr.chkerr();
|
||||||
}
|
}
|
||||||
void nasal_parse::die(uint32_t line,const std::string& info)
|
void nasal_parse::die(uint32_t line,std::string info)
|
||||||
{
|
{
|
||||||
int col=(int)tokens[ptr].column-(int)tokens[ptr].str.length();
|
int col=(int)tokens[ptr].column-(int)tokens[ptr].str.length();
|
||||||
if(tokens[ptr].type==tok_str)
|
if(tokens[ptr].type==tok_str)
|
||||||
|
@ -434,9 +434,9 @@ nasal_ast nasal_parse::expr()
|
||||||
{
|
{
|
||||||
uint32_t tok_type=tokens[ptr].type;
|
uint32_t tok_type=tokens[ptr].type;
|
||||||
if((tok_type==tok_break || tok_type==tok_continue) && !in_loop)
|
if((tok_type==tok_break || tok_type==tok_continue) && !in_loop)
|
||||||
die(error_line,"use break/continue in the loop");
|
die(error_line,"should use break/continue in loops");
|
||||||
if(tok_type==tok_ret && !in_func)
|
if(tok_type==tok_ret && !in_func)
|
||||||
die(error_line,"use return in the function");
|
die(error_line,"should use return in functions");
|
||||||
switch(tok_type)
|
switch(tok_type)
|
||||||
{
|
{
|
||||||
case tok_nil:
|
case tok_nil:
|
||||||
|
|
|
@ -1,29 +1,45 @@
|
||||||
import("lib.nas");
|
import("lib.nas");
|
||||||
var filename=["main.cpp","nasal_err.h","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_dbg.h","nasal.h"];
|
var filename=[
|
||||||
var space=[" "," "," ","",""," "," "," "," "," "," "," "];
|
"main.cpp",
|
||||||
var enter_cnt=func(s)
|
"nasal_err.h",
|
||||||
{
|
"nasal_ast.h",
|
||||||
var (cnt,len,enter)=(0,size(s),'\n'[0]);
|
"nasal_builtin.h",
|
||||||
|
"nasal_codegen.h",
|
||||||
|
"nasal_gc.h",
|
||||||
|
"nasal_import.h",
|
||||||
|
"nasal_lexer.h",
|
||||||
|
"nasal_parse.h",
|
||||||
|
"nasal_vm.h",
|
||||||
|
"nasal_dbg.h",
|
||||||
|
"nasal.h"
|
||||||
|
];
|
||||||
|
var space=[
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" "
|
||||||
|
];
|
||||||
|
var count=func(s,c){
|
||||||
|
var (cnt,len,ch)=(0,size(s),c[0]);
|
||||||
for(var i=0;i<len;i+=1)
|
for(var i=0;i<len;i+=1)
|
||||||
cnt+=(s[i]==enter);
|
cnt+=(s[i]==ch);
|
||||||
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;
|
return cnt;
|
||||||
}
|
}
|
||||||
func(){
|
func(){
|
||||||
var (bytes,line,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);
|
var (line_cnt,semi_cnt)=(count(s,'\n'),count(s,';'));
|
||||||
var line_cnt=enter_cnt(s);
|
|
||||||
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');
|
||||||
|
bytes+=size(s);
|
||||||
line+=line_cnt;
|
line+=line_cnt;
|
||||||
semi+=semi_cnt;
|
semi+=semi_cnt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ var table=[
|
||||||
['q1','1','1','R','q1'],
|
['q1','1','1','R','q1'],
|
||||||
['q1','0','0','S','q2'],
|
['q1','0','0','S','q2'],
|
||||||
['q2','0','1','R','q3'],
|
['q2','0','1','R','q3'],
|
||||||
['q3',' ',' ','S','q3']
|
['q3',nil,nil,'S','q3']
|
||||||
];
|
];
|
||||||
var prt=func(state,pointer,paper,act=nil){
|
var prt=func(state,pointer,paper,act=nil){
|
||||||
print(state,':',pointer,':',act!=nil?act:'','\n\t');
|
print(state,':',pointer,':',act!=nil?act:'','\n\t');
|
||||||
|
@ -19,7 +19,7 @@ var prt=func(state,pointer,paper,act=nil){
|
||||||
print(s,'^\n');
|
print(s,'^\n');
|
||||||
}
|
}
|
||||||
var run=func(table,node,start,stop){
|
var run=func(table,node,start,stop){
|
||||||
var paper=['0','1','0','1','0','a'];
|
var paper=['0','1','1','1','0','1','0','a'];
|
||||||
var pointer=0;
|
var pointer=0;
|
||||||
foreach(var action;table){
|
foreach(var action;table){
|
||||||
if(!contains(node,action[0]))
|
if(!contains(node,action[0]))
|
||||||
|
@ -37,7 +37,7 @@ var run=func(table,node,start,stop){
|
||||||
while(state!=stop){
|
while(state!=stop){
|
||||||
foreach(var action;table)
|
foreach(var action;table)
|
||||||
if(action[0]==state and (action[1]==paper[pointer] or action[1]==' ')){
|
if(action[0]==state and (action[1]==paper[pointer] or action[1]==' ')){
|
||||||
paper[pointer]=action[2]==' '?paper[pointer]:action[2];
|
paper[pointer]=action[2]==nil?paper[pointer]:action[2];
|
||||||
if(action[3]=='L') pointer-=1;
|
if(action[3]=='L') pointer-=1;
|
||||||
elsif(action[3]=='R') pointer+=1;
|
elsif(action[3]=='R') pointer+=1;
|
||||||
elsif(action[3]!='S') die("invalid action <"~action[3]~'>');
|
elsif(action[3]!='S') die("invalid action <"~action[3]~'>');
|
||||||
|
|
Loading…
Reference in New Issue