add debugger framework
with function:backtrace,run,help,show global/local/upvalue,exit
This commit is contained in:
parent
6a543f2aa7
commit
189d49fa4a
|
@ -49,7 +49,7 @@ Also remember to use g++ or clang++.(mingw-w64 in Windows)
|
||||||
|
|
||||||
Or use this in linux/macOS/Unix
|
Or use this in linux/macOS/Unix
|
||||||
|
|
||||||
> [cpp compiler] -std=c++11 -O3 main.cpp -o nasal -fno-exceptions
|
> [cpp compiler] -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl
|
||||||
|
|
||||||
## How to Use?
|
## How to Use?
|
||||||
|
|
||||||
|
|
17
main.cpp
17
main.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
constexpr uint32_t VM_LEXINFO =1;
|
constexpr uint32_t VM_LEXINFO =1;
|
||||||
constexpr uint32_t VM_ASTINFO =2;
|
constexpr uint32_t VM_ASTINFO =2;
|
||||||
constexpr uint32_t VM_CODEINFO =4;
|
constexpr uint32_t VM_CODEINFO =4;
|
||||||
|
@ -6,6 +7,8 @@ constexpr uint32_t VM_EXECTIME =8;
|
||||||
constexpr uint32_t VM_OPCALLNUM=16;
|
constexpr uint32_t VM_OPCALLNUM=16;
|
||||||
constexpr uint32_t VM_EXEC =32;
|
constexpr uint32_t VM_EXEC =32;
|
||||||
constexpr uint32_t VM_DBGINFO =64;
|
constexpr uint32_t VM_DBGINFO =64;
|
||||||
|
constexpr uint32_t VM_DEBUG =128;
|
||||||
|
|
||||||
void help()
|
void help()
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
|
@ -25,8 +28,9 @@ void help()
|
||||||
<<" -a, --ast | view abstract syntax tree.\n"
|
<<" -a, --ast | view abstract syntax tree.\n"
|
||||||
<<" -c, --code | view bytecode.\n"
|
<<" -c, --code | view bytecode.\n"
|
||||||
<<" -t, --time | execute and get the running time.\n"
|
<<" -t, --time | execute and get the running time.\n"
|
||||||
<<" -o, --opcnt | count operands while running.\n"
|
<<" -o, --opcnt | execute and count used operands.\n"
|
||||||
<<" -d, --detail | get detail crash info.\n"
|
<<" -d, --detail| execute and get detail crash info.\n"
|
||||||
|
<<" -dbg, --debug | debug mode (this will ignore -t -o -d).\n"
|
||||||
<<"file:\n"
|
<<"file:\n"
|
||||||
<<" input file name to execute script file.\n";
|
<<" input file name to execute script file.\n";
|
||||||
}
|
}
|
||||||
|
@ -95,7 +99,12 @@ void execute(const std::string& file,const uint32_t cmd)
|
||||||
parse.print();
|
parse.print();
|
||||||
if(cmd&VM_CODEINFO)
|
if(cmd&VM_CODEINFO)
|
||||||
gen.print();
|
gen.print();
|
||||||
if(cmd&VM_EXECTIME)
|
if(cmd&VM_DEBUG)
|
||||||
|
{
|
||||||
|
nasal_dbg dbg;
|
||||||
|
dbg.run(gen,linker);
|
||||||
|
}
|
||||||
|
else if(cmd&VM_EXECTIME)
|
||||||
{
|
{
|
||||||
clock_t t=clock();
|
clock_t t=clock();
|
||||||
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
|
vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO);
|
||||||
|
@ -141,6 +150,8 @@ int main(int argc,const char* argv[])
|
||||||
cmd|=VM_EXECTIME;
|
cmd|=VM_EXECTIME;
|
||||||
else if(s=="--detail" || s=="-d")
|
else if(s=="--detail" || s=="-d")
|
||||||
cmd|=VM_DBGINFO|VM_EXEC;
|
cmd|=VM_DBGINFO|VM_EXEC;
|
||||||
|
else if(s=="--debug" || s=="-dbg")
|
||||||
|
cmd|=VM_DEBUG;
|
||||||
else
|
else
|
||||||
err();
|
err();
|
||||||
}
|
}
|
||||||
|
|
2
makefile
2
makefile
|
@ -1,5 +1,5 @@
|
||||||
.PHONY=test
|
.PHONY=test
|
||||||
nasal: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
|
nasal: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_dbg.h nasal.h
|
||||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
||||||
test:nasal
|
test:nasal
|
||||||
./nasal test/ascii-art.nas
|
./nasal test/ascii-art.nas
|
||||||
|
|
1
nasal.h
1
nasal.h
|
@ -135,5 +135,6 @@ std::string rawstr(const std::string& str)
|
||||||
#include "nasal_builtin.h"
|
#include "nasal_builtin.h"
|
||||||
#include "nasal_codegen.h"
|
#include "nasal_codegen.h"
|
||||||
#include "nasal_vm.h"
|
#include "nasal_vm.h"
|
||||||
|
#include "nasal_dbg.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1059,7 +1059,6 @@ nasal_ref builtin_platform(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
#elif defined __APPLE__
|
#elif defined __APPLE__
|
||||||
*ret.str()="macOS";
|
*ret.str()="macOS";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -430,7 +430,7 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
|
||||||
|
|
||||||
code[newfunc_label].num=code.size()+1;
|
code[newfunc_label].num=code.size()+1;
|
||||||
int jmp_ptr=code.size();
|
int jmp_ptr=code.size();
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,ast.line());
|
||||||
|
|
||||||
const nasal_ast& block=ast[1];
|
const nasal_ast& block=ast[1];
|
||||||
// search symbols first, must use after loading parameters
|
// search symbols first, must use after loading parameters
|
||||||
|
@ -722,13 +722,13 @@ void nasal_codegen::conditional_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
calc_gen(tmp[0]);
|
calc_gen(tmp[0]);
|
||||||
int ptr=code.size();
|
int ptr=code.size();
|
||||||
gen(op_jf,0,0);
|
gen(op_jf,0,tmp.line());
|
||||||
block_gen(tmp[1]);
|
block_gen(tmp[1]);
|
||||||
// without 'else' the last condition doesn't need to jmp
|
// without 'else' the last condition doesn't need to jmp
|
||||||
if(&tmp!=&ast.child().back())
|
if(&tmp!=&ast.child().back())
|
||||||
{
|
{
|
||||||
jmp_label.push_back(code.size());
|
jmp_label.push_back(code.size());
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,tmp.line());
|
||||||
}
|
}
|
||||||
code[ptr].num=code.size();
|
code[ptr].num=code.size();
|
||||||
}
|
}
|
||||||
|
@ -770,10 +770,10 @@ void nasal_codegen::while_gen(const nasal_ast& ast)
|
||||||
int loop_ptr=code.size();
|
int loop_ptr=code.size();
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
int condition_ptr=code.size();
|
int condition_ptr=code.size();
|
||||||
gen(op_jf,0,0);
|
gen(op_jf,0,ast[0].line());
|
||||||
|
|
||||||
block_gen(ast[1]);
|
block_gen(ast[1]);
|
||||||
gen(op_jmp,loop_ptr,0);
|
gen(op_jmp,loop_ptr,ast[1].line());
|
||||||
code[condition_ptr].num=code.size();
|
code[condition_ptr].num=code.size();
|
||||||
load_continue_break(code.size()-1,code.size());
|
load_continue_break(code.size()-1,code.size());
|
||||||
}
|
}
|
||||||
|
@ -813,7 +813,7 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
case ast_grt:
|
case ast_grt:
|
||||||
case ast_trino:
|
case ast_trino:
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[0].line());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int jmp_place=code.size();
|
int jmp_place=code.size();
|
||||||
|
@ -822,7 +822,7 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
else
|
else
|
||||||
calc_gen(ast[1]);
|
calc_gen(ast[1]);
|
||||||
int label_exit=code.size();
|
int label_exit=code.size();
|
||||||
gen(op_jf,0,0);
|
gen(op_jf,0,ast[1].line());
|
||||||
|
|
||||||
block_gen(ast[3]);
|
block_gen(ast[3]);
|
||||||
int continue_place=code.size();
|
int continue_place=code.size();
|
||||||
|
@ -844,10 +844,10 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||||
case ast_less:case ast_geq:case ast_grt:
|
case ast_less:case ast_geq:case ast_grt:
|
||||||
case ast_trino:
|
case ast_trino:
|
||||||
calc_gen(ast[2]);
|
calc_gen(ast[2]);
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[2].line());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gen(op_jmp,jmp_place,0);
|
gen(op_jmp,jmp_place,ast[2].line());
|
||||||
code[label_exit].num=code.size();
|
code[label_exit].num=code.size();
|
||||||
|
|
||||||
load_continue_break(continue_place,code.size());
|
load_continue_break(continue_place,code.size());
|
||||||
|
@ -869,16 +869,16 @@ void nasal_codegen::forindex_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
mcall(ast[0]);
|
mcall(ast[0]);
|
||||||
gen(op_meq,0,ast[0].line());
|
gen(op_meq,0,ast[0].line());
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[0].line());
|
||||||
}
|
}
|
||||||
++in_iterloop.top();
|
++in_iterloop.top();
|
||||||
block_gen(ast[2]);
|
block_gen(ast[2]);
|
||||||
--in_iterloop.top();
|
--in_iterloop.top();
|
||||||
gen(op_jmp,ptr,0);
|
gen(op_jmp,ptr,ast.line());
|
||||||
code[ptr].num=code.size();
|
code[ptr].num=code.size();
|
||||||
load_continue_break(code.size()-1,code.size());
|
load_continue_break(code.size()-1,code.size());
|
||||||
gen(op_pop,0,0);// pop vector
|
gen(op_pop,0,ast[1].line());// pop vector
|
||||||
gen(op_pop,0,0);// pop iterator
|
gen(op_pop,0,ast.line());// pop iterator
|
||||||
}
|
}
|
||||||
void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
|
@ -897,31 +897,31 @@ void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
mcall(ast[0]);
|
mcall(ast[0]);
|
||||||
gen(op_meq,0,ast[0].line());
|
gen(op_meq,0,ast[0].line());
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[0].line());
|
||||||
}
|
}
|
||||||
++in_iterloop.top();
|
++in_iterloop.top();
|
||||||
block_gen(ast[2]);
|
block_gen(ast[2]);
|
||||||
--in_iterloop.top();
|
--in_iterloop.top();
|
||||||
gen(op_jmp,ptr,0);
|
gen(op_jmp,ptr,ast.line());
|
||||||
code[ptr].num=code.size();
|
code[ptr].num=code.size();
|
||||||
load_continue_break(code.size()-1,code.size());
|
load_continue_break(code.size()-1,code.size());
|
||||||
gen(op_pop,0,0);// pop vector
|
gen(op_pop,0,ast[1].line());// pop vector
|
||||||
gen(op_pop,0,0);// pop iterator
|
gen(op_pop,0,ast.line());// pop iterator
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::or_gen(const nasal_ast& ast)
|
void nasal_codegen::or_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
int l1=code.size();
|
int l1=code.size();
|
||||||
gen(op_jt,0,0);
|
gen(op_jt,0,ast[0].line());
|
||||||
|
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[0].line());
|
||||||
calc_gen(ast[1]);
|
calc_gen(ast[1]);
|
||||||
int l2=code.size();
|
int l2=code.size();
|
||||||
gen(op_jt,0,0);
|
gen(op_jt,0,ast[1].line());
|
||||||
|
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[1].line());
|
||||||
gen(op_pnil,0,0);
|
gen(op_pnil,0,ast[1].line());
|
||||||
|
|
||||||
code[l1].num=code[l2].num=code.size();
|
code[l1].num=code[l2].num=code.size();
|
||||||
}
|
}
|
||||||
|
@ -929,18 +929,18 @@ void nasal_codegen::or_gen(const nasal_ast& ast)
|
||||||
void nasal_codegen::and_gen(const nasal_ast& ast)
|
void nasal_codegen::and_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
gen(op_jt,code.size()+2,0);
|
gen(op_jt,code.size()+2,ast[0].line());
|
||||||
|
|
||||||
int lfalse=code.size();
|
int lfalse=code.size();
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,ast[0].line());
|
||||||
gen(op_pop,0,0);// jt jumps here
|
gen(op_pop,0,ast[1].line());// jt jumps here
|
||||||
|
|
||||||
calc_gen(ast[1]);
|
calc_gen(ast[1]);
|
||||||
gen(op_jt,code.size()+3,0);
|
gen(op_jt,code.size()+3,ast[1].line());
|
||||||
|
|
||||||
code[lfalse].num=code.size();
|
code[lfalse].num=code.size();
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast[1].line());
|
||||||
gen(op_pnil,0,0);
|
gen(op_pnil,0,ast[1].line());
|
||||||
//jt jumps here
|
//jt jumps here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,10 +948,10 @@ void nasal_codegen::trino_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
int lfalse=code.size();
|
int lfalse=code.size();
|
||||||
gen(op_jf,0,0);
|
gen(op_jf,0,ast[0].line());
|
||||||
calc_gen(ast[1]);
|
calc_gen(ast[1]);
|
||||||
int lexit=code.size();
|
int lexit=code.size();
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,ast[1].line());
|
||||||
code[lfalse].num=code.size();
|
code[lfalse].num=code.size();
|
||||||
calc_gen(ast[2]);
|
calc_gen(ast[2]);
|
||||||
code[lexit].num=code.size();
|
code[lexit].num=code.size();
|
||||||
|
@ -1073,11 +1073,11 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
case ast_conditional:conditional_gen(tmp);break;
|
case ast_conditional:conditional_gen(tmp);break;
|
||||||
case ast_continue:
|
case ast_continue:
|
||||||
continue_ptr.front().push_back(code.size());
|
continue_ptr.front().push_back(code.size());
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,tmp.line());
|
||||||
break;
|
break;
|
||||||
case ast_break:
|
case ast_break:
|
||||||
break_ptr.front().push_back(code.size());
|
break_ptr.front().push_back(code.size());
|
||||||
gen(op_jmp,0,0);
|
gen(op_jmp,0,tmp.line());
|
||||||
break;
|
break;
|
||||||
case ast_while:
|
case ast_while:
|
||||||
case ast_for:
|
case ast_for:
|
||||||
|
@ -1126,7 +1126,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
case ast_grt:
|
case ast_grt:
|
||||||
case ast_or:
|
case ast_or:
|
||||||
case ast_and:
|
case ast_and:
|
||||||
case ast_trino:calc_gen(tmp);gen(op_pop,0,0);break;
|
case ast_trino:calc_gen(tmp);gen(op_pop,0,tmp.line());break;
|
||||||
case ast_ret:ret_gen(tmp);break;
|
case ast_ret:ret_gen(tmp);break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1135,8 +1135,8 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;i<in_iterloop.top();++i)
|
for(uint32_t i=0;i<in_iterloop.top();++i)
|
||||||
{
|
{
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast.line());
|
||||||
gen(op_pop,0,0);
|
gen(op_pop,0,ast.line());
|
||||||
}
|
}
|
||||||
if(ast.size())
|
if(ast.size())
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
|
@ -1231,25 +1231,26 @@ void nasal_codegen::print_op(uint32_t index)
|
||||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||||
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||||
case op_pnum:
|
case op_pnum:
|
||||||
printf("0x%x (",c.num);std::cout<<num_res[c.num]<<")\n";break;
|
printf("0x%x (",c.num);std::cout<<num_res[c.num]<<")";break;
|
||||||
case op_callvi:case op_newv: case op_callfv:
|
case op_callvi:case op_newv: case op_callfv:
|
||||||
case op_intg: case op_intl:
|
case op_intg: case op_intl:
|
||||||
case op_newf: case op_jmp: case op_jt: case op_jf:
|
case op_newf: case op_jmp: case op_jt: case op_jf:
|
||||||
printf("0x%x\n",c.num);break;
|
printf("0x%x",c.num);break;
|
||||||
case op_callb:
|
case op_callb:
|
||||||
printf("0x%x <%s@0x%lx>\n",c.num,builtin[c.num].name,(uint64_t)builtin[c.num].func);break;
|
printf("0x%x <%s@0x%lx>",c.num,builtin[c.num].name,(uint64_t)builtin[c.num].func);break;
|
||||||
case op_callg: case op_mcallg: case op_loadg:
|
case op_callg: case op_mcallg: case op_loadg:
|
||||||
case op_calll: case op_mcalll: case op_loadl:
|
case op_calll: case op_mcalll: case op_loadl:
|
||||||
printf("0x%x\n",c.num);break;
|
printf("0x%x",c.num);break;
|
||||||
case op_upval:case op_mupval: case op_loadu:
|
case op_upval:case op_mupval: case op_loadu:
|
||||||
printf("0x%x[0x%x]\n",(c.num>>16)&0xffff,c.num&0xffff);break;
|
printf("0x%x[0x%x]",(c.num>>16)&0xffff,c.num&0xffff);break;
|
||||||
case op_happ: case op_pstr:
|
case op_happ: case op_pstr:
|
||||||
case op_lnkc: case op_lnkeqc:
|
case op_lnkc: case op_lnkeqc:
|
||||||
case op_callh: case op_mcallh:
|
case op_callh: case op_mcallh:
|
||||||
case op_para: case op_defpara:case op_dynpara:
|
case op_para: case op_defpara:case op_dynpara:
|
||||||
printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num]).c_str());break;
|
printf("0x%x (\"%s\")",c.num,rawstr(str_res[c.num]).c_str());break;
|
||||||
default:printf("\n");break;
|
default:break;
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::print()
|
void nasal_codegen::print()
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
#ifndef __NASAL_DBG_H__
|
||||||
|
#define __NASAL_DBG_H__
|
||||||
|
|
||||||
|
#include "nasal_vm.h"
|
||||||
|
|
||||||
|
class nasal_dbg:public nasal_vm
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<std::string> parse(std::string&);
|
||||||
|
uint16_t get_fileindex(std::string);
|
||||||
|
void err();
|
||||||
|
void help();
|
||||||
|
void interact();
|
||||||
|
public:
|
||||||
|
void run(
|
||||||
|
const nasal_codegen&,
|
||||||
|
const nasal_import&
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> nasal_dbg::parse(std::string& cmd)
|
||||||
|
{
|
||||||
|
std::vector<std::string> res;
|
||||||
|
std::string tmp="";
|
||||||
|
for(uint32_t i=0;i<cmd.length();++i)
|
||||||
|
{
|
||||||
|
if(cmd[i]==' ' && tmp.length())
|
||||||
|
{
|
||||||
|
res.push_back(tmp);
|
||||||
|
tmp="";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp+=cmd[i];
|
||||||
|
}
|
||||||
|
if(tmp.length())
|
||||||
|
res.push_back(tmp);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t nasal_dbg::get_fileindex(std::string filename)
|
||||||
|
{
|
||||||
|
for(uint16_t i=0;i<files_size;++i)
|
||||||
|
if(filename==files[i])
|
||||||
|
return i;
|
||||||
|
return 65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_dbg::err()
|
||||||
|
{
|
||||||
|
std::cout
|
||||||
|
<<"incorrect command\n"
|
||||||
|
<<"input \'h\' to get help\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_dbg::help()
|
||||||
|
{
|
||||||
|
std::cout
|
||||||
|
<<"<option>\n"
|
||||||
|
<<"\th, help | get help\n"
|
||||||
|
<<"\tbt, backtrace | get function call trace\n"
|
||||||
|
<<"\tr, run | run program until break point or exit\n"
|
||||||
|
<<"\tg, global | see global values\n"
|
||||||
|
<<"\tl, local | see local values\n"
|
||||||
|
<<"\tu, upval | see upvalue\n"
|
||||||
|
<<"\tquit, exit | exit debugger\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_dbg::interact()
|
||||||
|
{
|
||||||
|
static uint16_t last_fidx=0;
|
||||||
|
static uint32_t last_line=0;
|
||||||
|
|
||||||
|
if(bytecode[pc].op==op_intg)
|
||||||
|
{
|
||||||
|
std::cout
|
||||||
|
<<"nasal debug mode\n"
|
||||||
|
<<"input \'h\' to get help\n";
|
||||||
|
}
|
||||||
|
else if(bytecode[pc].op==op_exit)
|
||||||
|
{
|
||||||
|
std::cout<<"debugger exited successfully\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(bytecode[pc].op==op_nop)
|
||||||
|
return;
|
||||||
|
if(bytecode[pc].fidx!=last_fidx || bytecode[pc].line!=last_line)
|
||||||
|
return;
|
||||||
|
|
||||||
|
last_fidx=0;
|
||||||
|
last_line=0;
|
||||||
|
std::string cmd;
|
||||||
|
bytecodeinfo("->\t",pc);
|
||||||
|
for(uint32_t i=1;i<5 && bytecode[pc+i].op!=op_exit;++i)
|
||||||
|
bytecodeinfo(" \t",pc+i);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
printf(">> ");
|
||||||
|
std::getline(std::cin,cmd);
|
||||||
|
auto res=parse(cmd);
|
||||||
|
switch(res.size())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if(res[0]=="h" || res[0]=="help")
|
||||||
|
help();
|
||||||
|
else if(res[0]=="bt" || res[0]=="backtrace")
|
||||||
|
traceback();
|
||||||
|
else if(res[0]=="r" || res[0]=="run")
|
||||||
|
return;
|
||||||
|
else if(res[0]=="g" || res[0]=="global")
|
||||||
|
global_state();
|
||||||
|
else if(res[0]=="l" || res[0]=="local")
|
||||||
|
local_state();
|
||||||
|
else if(res[0]=="u" || res[0]=="upval")
|
||||||
|
upval_state();
|
||||||
|
else if(res[0]=="quit" || res[0]=="exit")
|
||||||
|
std::exit(0);
|
||||||
|
else
|
||||||
|
err();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
std::cout<<"unfinished\n";
|
||||||
|
break;
|
||||||
|
default:err();break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_dbg::run(
|
||||||
|
const nasal_codegen& gen,
|
||||||
|
const nasal_import& linker)
|
||||||
|
{
|
||||||
|
detail_info=true;
|
||||||
|
init(gen.get_strs(),gen.get_nums(),linker.get_file());
|
||||||
|
const void* opr_table[]=
|
||||||
|
{
|
||||||
|
&&nop, &&intg, &&intl, &&loadg,
|
||||||
|
&&loadl, &&loadu, &&pnum, &&pone,
|
||||||
|
&&pzero, &&pnil, &&pstr, &&newv,
|
||||||
|
&&newh, &&newf, &&happ, &¶,
|
||||||
|
&&defpara, &&dynpara, &&unot, &&usub,
|
||||||
|
&&add, &&sub, &&mul, &&div,
|
||||||
|
&&lnk, &&addc, &&subc, &&mulc,
|
||||||
|
&&divc, &&lnkc, &&addeq, &&subeq,
|
||||||
|
&&muleq, &&diveq, &&lnkeq, &&addeqc,
|
||||||
|
&&subeqc, &&muleqc, &&diveqc, &&lnkeqc,
|
||||||
|
&&meq, &&eq, &&neq, &&less,
|
||||||
|
&&leq, &&grt, &&geq, &&lessc,
|
||||||
|
&&leqc, &&grtc, &&geqc, &&pop,
|
||||||
|
&&jmp, &&jt, &&jf, &&counter,
|
||||||
|
&&findex, &&feach, &&callg, &&calll,
|
||||||
|
&&upval, &&callv, &&callvi, &&callh,
|
||||||
|
&&callfv, &&callfh, &&callb, &&slcbegin,
|
||||||
|
&&slcend, &&slc, &&slc2, &&mcallg,
|
||||||
|
&&mcalll, &&mupval, &&mcallv, &&mcallh,
|
||||||
|
&&ret, &&vmexit
|
||||||
|
};
|
||||||
|
bytecode=gen.get_code().data();
|
||||||
|
std::vector<const void*> code;
|
||||||
|
for(auto& i:gen.get_code())
|
||||||
|
{
|
||||||
|
code.push_back(opr_table[i.op]);
|
||||||
|
imm.push_back(i.num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set canary and program counter
|
||||||
|
auto canary=gc.stack+STACK_MAX_DEPTH-1;
|
||||||
|
pc=0;
|
||||||
|
// goto the first operand
|
||||||
|
goto *code[pc];
|
||||||
|
|
||||||
|
vmexit:
|
||||||
|
if(gc.top>=canary)
|
||||||
|
die("stack overflow");
|
||||||
|
gc.clear();
|
||||||
|
imm.clear();
|
||||||
|
return;
|
||||||
|
#define dbg(op) {interact();op();if(gc.top<canary)goto *code[++pc];goto vmexit;}
|
||||||
|
|
||||||
|
nop: dbg(opr_nop );
|
||||||
|
intg: dbg(opr_intg );
|
||||||
|
intl: dbg(opr_intl );
|
||||||
|
loadg: dbg(opr_loadg );
|
||||||
|
loadl: dbg(opr_loadl );
|
||||||
|
loadu: dbg(opr_loadu );
|
||||||
|
pnum: dbg(opr_pnum );
|
||||||
|
pone: dbg(opr_pone );
|
||||||
|
pzero: dbg(opr_pzero );
|
||||||
|
pnil: dbg(opr_pnil );
|
||||||
|
pstr: dbg(opr_pstr );
|
||||||
|
newv: dbg(opr_newv );
|
||||||
|
newh: dbg(opr_newh );
|
||||||
|
newf: dbg(opr_newf );
|
||||||
|
happ: dbg(opr_happ );
|
||||||
|
para: dbg(opr_para );
|
||||||
|
defpara: dbg(opr_defpara );
|
||||||
|
dynpara: dbg(opr_dynpara );
|
||||||
|
unot: dbg(opr_unot );
|
||||||
|
usub: dbg(opr_usub );
|
||||||
|
add: dbg(opr_add );
|
||||||
|
sub: dbg(opr_sub );
|
||||||
|
mul: dbg(opr_mul );
|
||||||
|
div: dbg(opr_div );
|
||||||
|
lnk: dbg(opr_lnk );
|
||||||
|
addc: dbg(opr_addc );
|
||||||
|
subc: dbg(opr_subc );
|
||||||
|
mulc: dbg(opr_mulc );
|
||||||
|
divc: dbg(opr_divc );
|
||||||
|
lnkc: dbg(opr_lnkc );
|
||||||
|
addeq: dbg(opr_addeq );
|
||||||
|
subeq: dbg(opr_subeq );
|
||||||
|
muleq: dbg(opr_muleq );
|
||||||
|
diveq: dbg(opr_diveq );
|
||||||
|
lnkeq: dbg(opr_lnkeq );
|
||||||
|
addeqc: dbg(opr_addeqc );
|
||||||
|
subeqc: dbg(opr_subeqc );
|
||||||
|
muleqc: dbg(opr_muleqc );
|
||||||
|
diveqc: dbg(opr_diveqc );
|
||||||
|
lnkeqc: dbg(opr_lnkeqc );
|
||||||
|
meq: dbg(opr_meq );
|
||||||
|
eq: dbg(opr_eq );
|
||||||
|
neq: dbg(opr_neq );
|
||||||
|
less: dbg(opr_less );
|
||||||
|
leq: dbg(opr_leq );
|
||||||
|
grt: dbg(opr_grt );
|
||||||
|
geq: dbg(opr_geq );
|
||||||
|
lessc: dbg(opr_lessc );
|
||||||
|
leqc: dbg(opr_leqc );
|
||||||
|
grtc: dbg(opr_grtc );
|
||||||
|
geqc: dbg(opr_geqc );
|
||||||
|
pop: dbg(opr_pop );
|
||||||
|
jmp: dbg(opr_jmp );
|
||||||
|
jt: dbg(opr_jt );
|
||||||
|
jf: dbg(opr_jf );
|
||||||
|
counter: dbg(opr_counter );
|
||||||
|
findex: dbg(opr_findex );
|
||||||
|
feach: dbg(opr_feach );
|
||||||
|
callg: dbg(opr_callg );
|
||||||
|
calll: dbg(opr_calll );
|
||||||
|
upval: dbg(opr_upval );
|
||||||
|
callv: dbg(opr_callv );
|
||||||
|
callvi: dbg(opr_callvi );
|
||||||
|
callh: dbg(opr_callh );
|
||||||
|
callfv: dbg(opr_callfv );
|
||||||
|
callfh: dbg(opr_callfh );
|
||||||
|
callb: dbg(opr_callb );
|
||||||
|
slcbegin:dbg(opr_slcbegin);
|
||||||
|
slcend: dbg(opr_slcend );
|
||||||
|
slc: dbg(opr_slc );
|
||||||
|
slc2: dbg(opr_slc2 );
|
||||||
|
mcallg: dbg(opr_mcallg );
|
||||||
|
mcalll: dbg(opr_mcalll );
|
||||||
|
mupval: dbg(opr_mupval );
|
||||||
|
mcallv: dbg(opr_mcallv );
|
||||||
|
mcallh: dbg(opr_mcallh );
|
||||||
|
ret: dbg(opr_ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
103
nasal_vm.h
103
nasal_vm.h
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
class nasal_vm
|
class nasal_vm
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
/* values of nasal_vm */
|
/* values of nasal_vm */
|
||||||
uint32_t pc; // program counter
|
uint32_t pc; // program counter
|
||||||
uint32_t offset; // used to load default parameters to a new function
|
uint32_t offset; // used to load default parameters to a new function
|
||||||
|
@ -15,8 +15,9 @@ private:
|
||||||
/* garbage collector */
|
/* garbage collector */
|
||||||
nasal_gc gc;
|
nasal_gc gc;
|
||||||
/* values used for debug */
|
/* values used for debug */
|
||||||
const opcode* bytecode; // ref from nasal_codegen
|
size_t files_size;
|
||||||
const std::string* files; // ref from nasal_import
|
const std::string* files; // ref from nasal_import
|
||||||
|
const opcode* bytecode; // ref from nasal_codegen
|
||||||
|
|
||||||
void init(
|
void init(
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
|
@ -25,9 +26,12 @@ private:
|
||||||
/* debug functions */
|
/* debug functions */
|
||||||
bool detail_info;
|
bool detail_info;
|
||||||
void valinfo(nasal_ref&);
|
void valinfo(nasal_ref&);
|
||||||
void bytecodeinfo(const uint32_t);
|
void bytecodeinfo(const char*,const uint32_t);
|
||||||
void traceback();
|
void traceback();
|
||||||
void stackinfo(const uint32_t);
|
void stackinfo(const uint32_t);
|
||||||
|
void global_state();
|
||||||
|
void local_state();
|
||||||
|
void upval_state();
|
||||||
void detail();
|
void detail();
|
||||||
void opcallsort(const uint64_t*);
|
void opcallsort(const uint64_t*);
|
||||||
void die(std::string);
|
void die(std::string);
|
||||||
|
@ -116,6 +120,7 @@ public:
|
||||||
const nasal_import&,
|
const nasal_import&,
|
||||||
const bool,
|
const bool,
|
||||||
const bool);
|
const bool);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void nasal_vm::init(
|
void nasal_vm::init(
|
||||||
|
@ -127,32 +132,50 @@ void nasal_vm::init(
|
||||||
num_table=nums.data();
|
num_table=nums.data();
|
||||||
str_table=strs.data();
|
str_table=strs.data();
|
||||||
files=filenames.data();
|
files=filenames.data();
|
||||||
|
files_size=filenames.size();
|
||||||
}
|
}
|
||||||
void nasal_vm::valinfo(nasal_ref& val)
|
void nasal_vm::valinfo(nasal_ref& val)
|
||||||
{
|
{
|
||||||
const nasal_val* p=val.value.gcobj;
|
const nasal_val* p=val.value.gcobj;
|
||||||
|
printf("\t");
|
||||||
switch(val.type)
|
switch(val.type)
|
||||||
{
|
{
|
||||||
case vm_none: printf("\t| null |\n");break;
|
case vm_none: printf("| null |\n");break;
|
||||||
case vm_ret: printf("\t| addr | pc=0x%x\n",val.ret());break;
|
case vm_ret: printf("| addr | pc=0x%x\n",val.ret());break;
|
||||||
case vm_cnt: printf("\t| cnt | %ld\n",val.cnt());break;
|
case vm_cnt: printf("| cnt | %ld\n",val.cnt());break;
|
||||||
case vm_nil: printf("\t| nil |\n");break;
|
case vm_nil: printf("| nil |\n");break;
|
||||||
case vm_num: printf("\t| num | %lf\n",val.num());break;
|
case vm_num: printf("| num | ");std::cout<<val.num()<<'\n';break;
|
||||||
case vm_str: printf("\t| str | <0x%lx> %s\n",(uint64_t)p,rawstr(*val.str()).c_str());break;
|
case vm_str: printf("| str | <0x%lx> %s\n",(uint64_t)p,rawstr(*val.str()).c_str());break;
|
||||||
case vm_func: printf("\t| func | <0x%lx> entry=0x%x\n",(uint64_t)p,val.func()->entry);break;
|
case vm_func: printf("| func | <0x%lx> entry=0x%x\n",(uint64_t)p,val.func()->entry);break;
|
||||||
case vm_vec: printf("\t| vec | <0x%lx> [%lu val]\n",(uint64_t)p,val.vec()->elems.size());break;
|
case vm_vec: printf("| vec | <0x%lx> [%lu val]\n",(uint64_t)p,val.vec()->elems.size());break;
|
||||||
case vm_hash: printf("\t| hash | <0x%lx> {%lu member}\n",(uint64_t)p,val.hash()->elems.size());break;
|
case vm_hash: printf("| hash | <0x%lx> {%lu member}\n",(uint64_t)p,val.hash()->elems.size());break;
|
||||||
case vm_obj: printf("\t| obj | <0x%lx> object=0x%lx\n",(uint64_t)p,(uint64_t)val.obj()->ptr);break;
|
case vm_obj: printf("| obj | <0x%lx> object=0x%lx\n",(uint64_t)p,(uint64_t)val.obj()->ptr);break;
|
||||||
default: printf("\t| ??? | <0x%lx>\n",(uint64_t)p);break;
|
default: printf("| ??? | <0x%lx>\n",(uint64_t)p);break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void nasal_vm::bytecodeinfo(const uint32_t p)
|
void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
|
||||||
{
|
{
|
||||||
const opcode& code=bytecode[p];
|
const opcode& c=bytecode[p];
|
||||||
printf("\t0x%.8x: %s 0x%x",p,code_table[code.op].name,code.num);
|
printf("%s0x%.8x: %s 0x%x",header,p,code_table[c.op].name,c.num);
|
||||||
if(code.op==op_callb)
|
switch(c.op)
|
||||||
printf(" <%s@0x%lx>",builtin[code.num].name,(uint64_t)builtin[code.num].func);
|
{
|
||||||
printf(" (<%s> line %d)\n",files[code.fidx].c_str(),code.line);
|
case op_addc: case op_subc: case op_mulc: case op_divc:
|
||||||
|
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||||
|
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||||
|
case op_pnum:
|
||||||
|
std::cout<<" ("<<num_table[c.num]<<")";break;
|
||||||
|
case op_callb:
|
||||||
|
printf(" <%s@0x%lx>",builtin[c.num].name,(uint64_t)builtin[c.num].func);break;
|
||||||
|
case op_happ: case op_pstr:
|
||||||
|
case op_lnkc: case op_lnkeqc:
|
||||||
|
case op_callh: case op_mcallh:
|
||||||
|
case op_para: case op_defpara:case op_dynpara:
|
||||||
|
printf(" (\"%s\")",rawstr(str_table[c.num]).c_str());break;
|
||||||
|
case op_upval:case op_mupval: case op_loadu:
|
||||||
|
printf(" (0x%x[0x%x])",(c.num>>16)&0xffff,c.num&0xffff);break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
printf(" (<%s> line %d)\n",files[c.fidx].c_str(),c.line);
|
||||||
}
|
}
|
||||||
void nasal_vm::traceback()
|
void nasal_vm::traceback()
|
||||||
{
|
{
|
||||||
|
@ -177,7 +200,7 @@ void nasal_vm::traceback()
|
||||||
if(same)
|
if(same)
|
||||||
printf("\t0x%.8x: %d same call(s)\n",last,same);
|
printf("\t0x%.8x: %d same call(s)\n",last,same);
|
||||||
same=0;
|
same=0;
|
||||||
bytecodeinfo(point);
|
bytecodeinfo("\t",point);
|
||||||
}
|
}
|
||||||
if(same)
|
if(same)
|
||||||
printf("\t0x%.8x: %d same call(s)\n",last,same);
|
printf("\t0x%.8x: %d same call(s)\n",last,same);
|
||||||
|
@ -191,20 +214,27 @@ void nasal_vm::stackinfo(const uint32_t limit=10)
|
||||||
for(uint32_t i=0;i<limit && top>=bottom;++i,--top)
|
for(uint32_t i=0;i<limit && top>=bottom;++i,--top)
|
||||||
valinfo(top[0]);
|
valinfo(top[0]);
|
||||||
}
|
}
|
||||||
void nasal_vm::detail()
|
void nasal_vm::global_state()
|
||||||
{
|
{
|
||||||
printf("mcall address: 0x%lx\n",(uint64_t)mem_addr);
|
if(!bytecode[0].num) // bytecode[0].op is op_intg
|
||||||
if(bytecode[0].num) // bytecode[0] is op_intg
|
|
||||||
{
|
{
|
||||||
|
printf("no global value exists\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
printf("global:\n");
|
printf("global:\n");
|
||||||
for(uint32_t i=0;i<bytecode[0].num;++i)
|
for(uint32_t i=0;i<bytecode[0].num;++i)
|
||||||
{
|
{
|
||||||
printf("[0x%.8x]",i);
|
printf("[0x%.8x]",i);
|
||||||
valinfo(gc.stack[i]);
|
valinfo(gc.stack[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!gc.local.empty())
|
void nasal_vm::local_state()
|
||||||
|
{
|
||||||
|
if(gc.local.empty() || !gc.local.back().vec()->elems.size())
|
||||||
{
|
{
|
||||||
|
printf("no local value exists\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
printf("local:\n");
|
printf("local:\n");
|
||||||
auto& vec=gc.local.back().vec()->elems;
|
auto& vec=gc.local.back().vec()->elems;
|
||||||
for(uint32_t i=0;i<vec.size();++i)
|
for(uint32_t i=0;i<vec.size();++i)
|
||||||
|
@ -212,9 +242,14 @@ void nasal_vm::detail()
|
||||||
printf("[0x%.8x]",i);
|
printf("[0x%.8x]",i);
|
||||||
valinfo(vec[i]);
|
valinfo(vec[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!func_stk.empty() && !func_stk.top()->upvalue.empty())
|
void nasal_vm::upval_state()
|
||||||
|
{
|
||||||
|
if(func_stk.empty() || func_stk.top()->upvalue.empty())
|
||||||
{
|
{
|
||||||
|
printf("no upvalue exists\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
printf("upvalue:\n");
|
printf("upvalue:\n");
|
||||||
auto& upval=func_stk.top()->upvalue;
|
auto& upval=func_stk.top()->upvalue;
|
||||||
for(uint32_t i=0;i<upval.size();++i)
|
for(uint32_t i=0;i<upval.size();++i)
|
||||||
|
@ -226,7 +261,13 @@ void nasal_vm::detail()
|
||||||
valinfo(vec[j]);
|
valinfo(vec[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void nasal_vm::detail()
|
||||||
|
{
|
||||||
|
printf("mcall address: 0x%lx\n",(uint64_t)mem_addr);
|
||||||
|
global_state();
|
||||||
|
local_state();
|
||||||
|
upval_state();
|
||||||
}
|
}
|
||||||
void nasal_vm::opcallsort(const uint64_t* arr)
|
void nasal_vm::opcallsort(const uint64_t* arr)
|
||||||
{
|
{
|
||||||
|
@ -804,9 +845,9 @@ void nasal_vm::run(
|
||||||
const nasal_codegen& gen,
|
const nasal_codegen& gen,
|
||||||
const nasal_import& linker,
|
const nasal_import& linker,
|
||||||
const bool opcnt,
|
const bool opcnt,
|
||||||
const bool debug)
|
const bool detail)
|
||||||
{
|
{
|
||||||
detail_info=debug;
|
detail_info=detail;
|
||||||
init(gen.get_strs(),gen.get_nums(),linker.get_file());
|
init(gen.get_strs(),gen.get_nums(),linker.get_file());
|
||||||
uint64_t count[op_exit+1]={0};
|
uint64_t count[op_exit+1]={0};
|
||||||
const void* opr_table[]=
|
const void* opr_table[]=
|
||||||
|
|
|
@ -94,6 +94,7 @@ var math=
|
||||||
atan2: func(x,y){return __builtin_atan2(x,y);},
|
atan2: func(x,y){return __builtin_atan2(x,y);},
|
||||||
isnan: func(x) {return __builtin_isnan(x); }
|
isnan: func(x) {return __builtin_isnan(x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
var D2R=math.pi/180;
|
var D2R=math.pi/180;
|
||||||
var FPS2KT=0.5925;
|
var FPS2KT=0.5925;
|
||||||
var FT2M=0.3048;
|
var FT2M=0.3048;
|
||||||
|
@ -138,3 +139,8 @@ var dylib=
|
||||||
dlclose: func(lib){return __builtin_dlclose; },
|
dlclose: func(lib){return __builtin_dlclose; },
|
||||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var os=
|
||||||
|
{
|
||||||
|
platform: func(){return __builtin_platform;}
|
||||||
|
};
|
20
test/bfs.nas
20
test/bfs.nas
|
@ -8,20 +8,25 @@ var map=[];
|
||||||
for(var i=0;i<10;i+=1)
|
for(var i=0;i<10;i+=1)
|
||||||
{
|
{
|
||||||
append(map,[]);
|
append(map,[]);
|
||||||
for(var j=0;j<10;j+=1)
|
for(var j=0;j<20;j+=1)
|
||||||
append(map[i],(rand()>0.7));
|
append(map[i],(rand()>0.7));
|
||||||
}
|
}
|
||||||
|
|
||||||
var prt=func()
|
var prt=func()
|
||||||
{
|
{
|
||||||
var s="";
|
if(os.platform()=="windows")
|
||||||
|
system("cls");
|
||||||
|
else
|
||||||
|
system("clear");
|
||||||
|
var s="+--------------------+\n";
|
||||||
for(var i=0;i<10;i+=1)
|
for(var i=0;i<10;i+=1)
|
||||||
{
|
{
|
||||||
for(var j=0;j<10;j+=1)
|
s~="|";
|
||||||
|
for(var j=0;j<20;j+=1)
|
||||||
s~=pixel[map[i][j]];
|
s~=pixel[map[i][j]];
|
||||||
s~='\n';
|
s~='|\n';
|
||||||
}
|
}
|
||||||
s~='----------\n';
|
s~='+--------------------+\n';
|
||||||
print(s);
|
print(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +36,7 @@ var bfs=func(begin,end)
|
||||||
var que=queue();
|
var que=queue();
|
||||||
que.push(begin);
|
que.push(begin);
|
||||||
map[begin[0]][begin[1]]=2;
|
map[begin[0]][begin[1]]=2;
|
||||||
|
map[end[0]][end[1]]=0;
|
||||||
while(!que.empty())
|
while(!que.empty())
|
||||||
{
|
{
|
||||||
var vertex=que.front();
|
var vertex=que.front();
|
||||||
|
@ -45,7 +51,7 @@ var bfs=func(begin,end)
|
||||||
prt();
|
prt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(0<=x and x<10 and 0<=y and y<10 and map[x][y]==0)
|
if(0<=x and x<10 and 0<=y and y<20 and map[x][y]==0)
|
||||||
{
|
{
|
||||||
que.push([x,y]);
|
que.push([x,y]);
|
||||||
map[x][y]=2;
|
map[x][y]=2;
|
||||||
|
@ -57,4 +63,4 @@ var bfs=func(begin,end)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bfs([0,0],[9,9]);
|
bfs([0,0],[9,19]);
|
|
@ -1,6 +1,6 @@
|
||||||
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_dbg.h","nasal.h"];
|
||||||
var space=[" "," ","",""," "," "," "," "," "," "];
|
var space=[" "," ","",""," "," "," "," "," "," "," "];
|
||||||
var enter_cnt=func(s)
|
var enter_cnt=func(s)
|
||||||
{
|
{
|
||||||
var (cnt,len,enter)=(0,size(s),'\n'[0]);
|
var (cnt,len,enter)=(0,size(s),'\n'[0]);
|
||||||
|
|
Loading…
Reference in New Issue