🚀 import information output of dbg, vm and codegen
This commit is contained in:
parent
6a6eab8db5
commit
aa5b1d3d66
132
nasal_ast.h
132
nasal_ast.h
|
@ -1,6 +1,9 @@
|
|||
#ifndef __NASAL_AST_H__
|
||||
#define __NASAL_AST_H__
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
enum ast_node:u32
|
||||
{
|
||||
ast_null=0, // null node
|
||||
|
@ -128,14 +131,15 @@ const char* ast_name[]=
|
|||
class nasal_ast
|
||||
{
|
||||
private:
|
||||
u32 _line;
|
||||
u32 _column;
|
||||
u32 _type;
|
||||
f64 _num;
|
||||
string _str;
|
||||
std::vector<nasal_ast> _child;
|
||||
u32 node_line;
|
||||
u32 node_col;
|
||||
u32 node_type;
|
||||
f64 node_num;
|
||||
string node_str;
|
||||
std::vector<nasal_ast> node_child;
|
||||
public:
|
||||
nasal_ast(const u32 l,const u32 c,const u32 t):_line(l),_column(c),_type(t),_num(0){}
|
||||
nasal_ast(const u32 l,const u32 c,const u32 t):
|
||||
node_line(l),node_col(c),node_type(t),node_num(0){}
|
||||
nasal_ast(const nasal_ast&);
|
||||
nasal_ast(nasal_ast&&);
|
||||
void tree();
|
||||
|
@ -144,74 +148,74 @@ public:
|
|||
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast& operator=(nasal_ast&&);
|
||||
nasal_ast& operator[](usize n){return _child[n];}
|
||||
const nasal_ast& operator[](usize n) const {return _child[n];}
|
||||
usize size() const {return _child.size();}
|
||||
nasal_ast& operator[](usize n){return node_child[n];}
|
||||
const nasal_ast& operator[](usize n) const {return node_child[n];}
|
||||
usize size() const {return node_child.size();}
|
||||
|
||||
void add(nasal_ast&& ast){_child.push_back(std::move(ast));}
|
||||
void add(const nasal_ast& ast){_child.push_back(ast);}
|
||||
void set_line(const u32 l){_line=l;}
|
||||
void set_type(const u32 t){_type=t;}
|
||||
void set_str(const string& s){_str=s;}
|
||||
void set_num(const f64 n){_num=n;}
|
||||
void add(nasal_ast&& ast){node_child.push_back(std::move(ast));}
|
||||
void add(const nasal_ast& ast){node_child.push_back(ast);}
|
||||
void set_line(const u32 l){node_line=l;}
|
||||
void set_type(const u32 t){node_type=t;}
|
||||
void set_str(const string& s){node_str=s;}
|
||||
void set_num(const f64 n){node_num=n;}
|
||||
|
||||
inline u32 line() const {return _line;}
|
||||
inline u32 col() const {return _column;}
|
||||
inline u32 type() const {return _type;}
|
||||
inline f64 num() const {return _num;}
|
||||
inline const string& str() const {return _str;}
|
||||
inline const std::vector<nasal_ast>& child() const {return _child;}
|
||||
inline std::vector<nasal_ast>& child(){return _child;}
|
||||
inline u32 line() const {return node_line;}
|
||||
inline u32 col() const {return node_col;}
|
||||
inline u32 type() const {return node_type;}
|
||||
inline f64 num() const {return node_num;}
|
||||
inline const string& str() const {return node_str;}
|
||||
inline const std::vector<nasal_ast>& child() const {return node_child;}
|
||||
inline std::vector<nasal_ast>& child(){return node_child;}
|
||||
};
|
||||
|
||||
nasal_ast::nasal_ast(const nasal_ast& tmp):
|
||||
_str(tmp._str),_child(tmp._child)
|
||||
node_str(tmp.node_str),node_child(tmp.node_child)
|
||||
{
|
||||
_line=tmp._line;
|
||||
_column=tmp._column;
|
||||
_type=tmp._type;
|
||||
_num =tmp._num;
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num =tmp.node_num;
|
||||
}
|
||||
|
||||
nasal_ast::nasal_ast(nasal_ast&& tmp)
|
||||
{
|
||||
_line=tmp._line;
|
||||
_column=tmp._column;
|
||||
_type=tmp._type;
|
||||
_num =tmp._num;
|
||||
_str.swap(tmp._str);
|
||||
_child.swap(tmp._child);
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num =tmp.node_num;
|
||||
node_str.swap(tmp.node_str);
|
||||
node_child.swap(tmp.node_child);
|
||||
}
|
||||
|
||||
nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
|
||||
{
|
||||
_line=tmp._line;
|
||||
_column=tmp._column;
|
||||
_type=tmp._type;
|
||||
_num=tmp._num;
|
||||
_str=tmp._str;
|
||||
_child=tmp._child;
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num=tmp.node_num;
|
||||
node_str=tmp.node_str;
|
||||
node_child=tmp.node_child;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nasal_ast& nasal_ast::operator=(nasal_ast&& tmp)
|
||||
{
|
||||
_line=tmp._line;
|
||||
_column=tmp._column;
|
||||
_type=tmp._type;
|
||||
_num=tmp._num;
|
||||
_str.swap(tmp._str);
|
||||
_child.swap(tmp._child);
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num=tmp.node_num;
|
||||
node_str.swap(tmp.node_str);
|
||||
node_child.swap(tmp.node_child);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void nasal_ast::clear()
|
||||
{
|
||||
_line=_column=0;
|
||||
_num=0;
|
||||
_str="";
|
||||
_type=ast_null;
|
||||
_child.clear();
|
||||
node_line=node_col=0;
|
||||
node_num=0;
|
||||
node_str.clear();
|
||||
node_type=ast_null;
|
||||
node_child.clear();
|
||||
}
|
||||
|
||||
void nasal_ast::tree()
|
||||
|
@ -224,14 +228,16 @@ void nasal_ast::print(u32 depth,bool last,std::vector<string>& indent)
|
|||
{
|
||||
for(auto& i:indent)
|
||||
std::cout<<i;
|
||||
std::cout<<ast_name[_type];
|
||||
if(_type==ast_str || _type==ast_id ||
|
||||
_type==ast_default || _type==ast_dynamic ||
|
||||
_type==ast_callh)
|
||||
std::cout<<":"<<rawstr(_str);
|
||||
else if(_type==ast_num || _type==ast_file)
|
||||
std::cout<<":"<<_num;
|
||||
std::cout<<'\n';
|
||||
std::cout<<ast_name[node_type];
|
||||
if(node_type==ast_str ||
|
||||
node_type==ast_id ||
|
||||
node_type==ast_default ||
|
||||
node_type==ast_dynamic ||
|
||||
node_type==ast_callh)
|
||||
std::cout<<":"<<rawstr(node_str);
|
||||
else if(node_type==ast_num || node_type==ast_file)
|
||||
std::cout<<":"<<node_num;
|
||||
std::cout<<"\n";
|
||||
if(last && depth)
|
||||
indent.back()=" ";
|
||||
else if(!last && depth)
|
||||
|
@ -240,14 +246,14 @@ void nasal_ast::print(u32 depth,bool last,std::vector<string>& indent)
|
|||
#else
|
||||
indent.back()="│ ";
|
||||
#endif
|
||||
for(u32 i=0;i<_child.size();++i)
|
||||
for(u32 i=0;i<node_child.size();++i)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
indent.push_back(i==_child.size()-1?"+-":"|-");
|
||||
indent.push_back(i==node_child.size()-1?"+-":"|-");
|
||||
#else
|
||||
indent.push_back(i==_child.size()-1?"└─":"├─");
|
||||
indent.push_back(i==node_child.size()-1?"└─":"├─");
|
||||
#endif
|
||||
_child[i].print(depth+1,i==_child.size()-1,indent);
|
||||
node_child[i].print(depth+1,i==node_child.size()-1,indent);
|
||||
indent.pop_back();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -386,13 +386,7 @@ nas_ref builtin_keys(nas_ref* local,nasal_gc& gc)
|
|||
}
|
||||
nas_ref builtin_die(nas_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nas_ref str=local[1];
|
||||
if(str.type!=vm_str)
|
||||
return nas_err("die","\"str\" must be string");
|
||||
std::cerr<<bold_red<<"[vm] error: "
|
||||
<<bold_white<<str.str()<<'\n'
|
||||
<<reset;
|
||||
return {vm_none};
|
||||
return nas_err("error",local[1].tostr());
|
||||
}
|
||||
nas_ref builtin_find(nas_ref* local,nasal_gc& gc)
|
||||
{
|
||||
|
|
|
@ -125,66 +125,78 @@ struct opcode
|
|||
line=tmp.line;
|
||||
return *this;
|
||||
}
|
||||
void print(const char*,
|
||||
const f64*,
|
||||
const string*,
|
||||
const u32,bool) const;
|
||||
};
|
||||
|
||||
void opcode::print(const char* header,
|
||||
const f64* constnum,
|
||||
const string* conststr,
|
||||
const u32 index,
|
||||
bool deftnum=false) const
|
||||
class codestream
|
||||
{
|
||||
std::cout<<bold_cyan<<header<<reset<<std::hex<<"0x"
|
||||
<<std::setw(8)<<std::setfill('0')<<index<<": "
|
||||
private:
|
||||
opcode code;
|
||||
const u32 index;
|
||||
const f64* nums;
|
||||
const string* strs;
|
||||
const string* files;
|
||||
public:
|
||||
codestream(const opcode& c,const u32 i,const f64* n,const string* s,const string* f=nullptr):
|
||||
code(c.op,c.fidx,c.num,c.line),index(i),nums(n),strs(s),files(f){}
|
||||
friend std::ostream& operator<<(std::ostream& out,const codestream& ins)
|
||||
{
|
||||
u8 op=ins.code.op;
|
||||
u32 num=ins.code.num;
|
||||
out<<std::hex<<"0x"
|
||||
<<std::setw(8)<<std::setfill('0')<<ins.index<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<(u32)op<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>24)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>16)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>8)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<(num&0xff)
|
||||
<<" "<<code_table[op]<<" "<<std::dec;
|
||||
<<std::setw(2)<<std::setfill('0')<<(num&0xff)<<" "
|
||||
<<code_table[op]<<" "<<std::dec;
|
||||
switch(op)
|
||||
{
|
||||
case op_addeq: case op_subeq: case op_muleq: case op_diveq:
|
||||
case op_lnkeq: case op_meq:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec
|
||||
out<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" sp-"<<num;break;
|
||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||
std::cout<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec
|
||||
<<" ("<<constnum[num&0x7fffffff]<<") sp-"
|
||||
out<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec
|
||||
<<" ("<<ins.nums[num&0x7fffffff]<<") sp-"
|
||||
<<(num>>31);break;
|
||||
case op_lnkeqc:
|
||||
std::cout<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec<<" (\""
|
||||
<<rawstr(conststr[num&0x7fffffff],16)<<"\") sp-"
|
||||
out<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec<<" (\""
|
||||
<<rawstr(ins.strs[num&0x7fffffff],16)<<"\") sp-"
|
||||
<<(num>>31);break;
|
||||
case op_addc: case op_subc: case op_mulc: case op_divc:
|
||||
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||
case op_pnum:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec<<" ("
|
||||
<<constnum[num]<<")";break;
|
||||
out<<std::hex<<"0x"<<num<<std::dec<<" ("
|
||||
<<ins.nums[num]<<")";break;
|
||||
case op_callvi:case op_newv: case op_callfv:
|
||||
case op_intg: case op_intl:
|
||||
case op_newf: case op_jmp: case op_jt: case op_jf:
|
||||
case op_callg: case op_mcallg: case op_loadg:
|
||||
case op_calll: case op_mcalll: case op_loadl:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec;break;
|
||||
out<<std::hex<<"0x"<<num<<std::dec;break;
|
||||
case op_callb:
|
||||
std::cout<<std::hex<<"0x"<<num<<" <"<<builtin[num].name
|
||||
out<<std::hex<<"0x"<<num<<" <"<<builtin[num].name
|
||||
<<"@0x"<<(u64)builtin[num].func<<std::dec<<">";break;
|
||||
case op_upval: case op_mupval: case op_loadu:
|
||||
std::cout<<std::hex<<"0x"<<((num>>16)&0xffff)
|
||||
out<<std::hex<<"0x"<<((num>>16)&0xffff)
|
||||
<<"[0x"<<(num&0xffff)<<"]"<<std::dec;break;
|
||||
case op_happ: case op_pstr:
|
||||
case op_lnkc:
|
||||
case op_callh: case op_mcallh:
|
||||
case op_para: case op_deft: case op_dyn:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" (\""<<rawstr(conststr[num],16)<<"\")";break;
|
||||
default:if(deftnum)std::cout<<std::hex<<"0x"<<num<<std::dec;break;
|
||||
out<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" (\""<<rawstr(ins.strs[num],16)<<"\")";break;
|
||||
default:
|
||||
if(ins.files)
|
||||
out<<std::hex<<"0x"<<num<<std::dec;
|
||||
break;
|
||||
}
|
||||
if(ins.files)
|
||||
out<<" ("<<ins.files[ins.code.fidx]<<":"<<ins.code.line<<")";
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
class nasal_codegen
|
||||
{
|
||||
|
@ -1265,8 +1277,7 @@ void nasal_codegen::singleop(const u32 index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
c.print(" ",num_res.data(),str_res.data(),index);
|
||||
std::cout<<"\n";
|
||||
std::cout<<" "<<codestream(c,index,num_res.data(),str_res.data())<<"\n";
|
||||
}
|
||||
|
||||
void nasal_codegen::print()
|
||||
|
|
12
nasal_dbg.h
12
nasal_dbg.h
|
@ -113,19 +113,21 @@ void nasal_dbg::callsort(const u64* arr)
|
|||
|
||||
void nasal_dbg::stepinfo()
|
||||
{
|
||||
u32 begin,end;
|
||||
u32 line=bytecode[pc].line==0?0:bytecode[pc].line-1;
|
||||
u32 begin=(line>>3)==0?0:((line>>3)<<3);
|
||||
u32 end=(1+(line>>3))<<3;
|
||||
src.load(files[bytecode[pc].fidx]);
|
||||
std::cout<<"\nsource code:\n";
|
||||
begin=(line>>3)==0?0:((line>>3)<<3);
|
||||
end=(1+(line>>3))<<3;
|
||||
for(u32 i=begin;i<end && i<src.size();++i)
|
||||
std::cout<<bold_cyan<<(i==line?"--> ":" ")<<reset<<src[i]<<"\n";
|
||||
std::cout<<(i==line?back_white:reset)<<(i==line?"--> ":" ")<<src[i]<<reset<<"\n";
|
||||
std::cout<<"next bytecode:\n";
|
||||
begin=(pc>>3)==0?0:((pc>>3)<<3);
|
||||
end=(1+(pc>>3))<<3;
|
||||
for(u32 i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
||||
bytecodeinfo(i==pc?"--> ":" ",i);
|
||||
std::cout
|
||||
<<(i==pc?back_white:reset)<<(i==pc?"--> ":" ")
|
||||
<<codestream(bytecode[i],i,num_table,str_table,files)
|
||||
<<reset<<"\n";
|
||||
stackinfo(10);
|
||||
}
|
||||
|
||||
|
|
22
nasal_err.h
22
nasal_err.h
|
@ -17,6 +17,15 @@ struct for_reset
|
|||
}reset_ter_color;
|
||||
#endif
|
||||
|
||||
std::ostream& back_white(std::ostream& s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xf0);
|
||||
#else
|
||||
s<<"\033[7m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
std::ostream& bold_red(std::ostream& s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -74,24 +83,19 @@ public:
|
|||
if(file==f) return; // don't need to load a loaded file
|
||||
file=f;
|
||||
res.clear();
|
||||
std::ifstream fin(f,std::ios::binary);
|
||||
if(fin.fail())
|
||||
std::ifstream in(f,std::ios::binary);
|
||||
if(in.fail())
|
||||
{
|
||||
std::cerr<<bold_red<<"src: "<<reset<<"cannot open <"<<f<<">\n";
|
||||
std::exit(1);
|
||||
}
|
||||
string line;
|
||||
while(!fin.eof())
|
||||
while(!in.eof())
|
||||
{
|
||||
std::getline(fin,line);
|
||||
std::getline(in,line);
|
||||
res.push_back(line);
|
||||
}
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
std::vector<string> tmp;
|
||||
res.swap(tmp);
|
||||
}
|
||||
const string& operator[](usize n){return res[n];}
|
||||
const string& name(){return file;}
|
||||
usize size(){return res.size();}
|
||||
|
|
|
@ -723,9 +723,7 @@ void nasal_gc::ctxreserve()
|
|||
// use to print error log and return error value
|
||||
nas_ref nas_err(const string& err_f,const string& info)
|
||||
{
|
||||
std::cerr<<bold_red<<"[vm] "<<err_f<<": "
|
||||
<<bold_white<<info<<"\n"
|
||||
<<reset;
|
||||
std::cerr<<"[vm] "<<err_f<<": "<<info<<"\n";
|
||||
return {vm_none};
|
||||
}
|
||||
#endif
|
29
nasal_vm.h
29
nasal_vm.h
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include <iomanip>
|
||||
#include <stack>
|
||||
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_codegen.h"
|
||||
|
||||
class nasal_vm
|
||||
{
|
||||
|
@ -39,7 +38,6 @@ protected:
|
|||
/* debug functions */
|
||||
bool detail_info;
|
||||
void valinfo(nas_ref&);
|
||||
void bytecodeinfo(const char*,const u32);
|
||||
void traceback();
|
||||
void stackinfo(const u32);
|
||||
void reginfo();
|
||||
|
@ -200,22 +198,17 @@ void nasal_vm::valinfo(nas_ref& val)
|
|||
}
|
||||
std::cout<<"\n";
|
||||
}
|
||||
void nasal_vm::bytecodeinfo(const char* header,const u32 p)
|
||||
{
|
||||
const opcode& c=bytecode[p];
|
||||
c.print(header,num_table,str_table,p,true);
|
||||
std::cout<<" ("<<files[c.fidx]<<":"<<c.line<<")\n";
|
||||
}
|
||||
void nasal_vm::traceback()
|
||||
{
|
||||
nas_ref* bottom=stack+bytecode[0].num; // bytecode[0] is op_intg
|
||||
nas_ref* main_ctx_top=gc.stack==stack?top:gc.mctx.top; // if error occurs in coroutine, this works
|
||||
/* bytecode[0].num is the global size */
|
||||
nas_ref* bottom=gc.stack==stack?stack+bytecode[0].num:gc.stack;
|
||||
nas_ref* ctx_top=gc.stack==stack?top:gc.top;
|
||||
std::stack<u32> ret;
|
||||
for(nas_ref* i=bottom;i<=main_ctx_top;++i)
|
||||
if(i->type==vm_ret)
|
||||
for(nas_ref* i=bottom;i<=ctx_top;++i)
|
||||
if(i->type==vm_ret && i->ret()!=0)
|
||||
ret.push(i->ret());
|
||||
ret.push(pc); // store the position program crashed
|
||||
std::cout<<"trace back:\n";
|
||||
std::cout<<"trace back ("<<(gc.stack==stack?"main":"coroutine")<<")\n";
|
||||
for(u32 p=0,same=0,prev=0xffffffff;!ret.empty();prev=p,ret.pop())
|
||||
{
|
||||
if((p=ret.top())==prev)
|
||||
|
@ -228,14 +221,14 @@ void nasal_vm::traceback()
|
|||
<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
||||
<<prev<<std::dec<<": "<<same<<" same call(s)\n";
|
||||
same=0;
|
||||
bytecodeinfo(" ",p);
|
||||
std::cout<<" "<<codestream(bytecode[p],p,num_table,str_table,files)<<"\n";
|
||||
}
|
||||
// the first called place has no same calls
|
||||
}
|
||||
void nasal_vm::stackinfo(const u32 limit=10)
|
||||
{
|
||||
/* bytecode[0].num is the global size */
|
||||
u32 gsize=gc.stack==stack?bytecode[0].num:0;
|
||||
const u32 gsize=gc.stack==stack?bytecode[0].num:0;
|
||||
nas_ref* t=top;
|
||||
nas_ref* bottom=gc.stack+gsize;
|
||||
std::cout<<"vm stack (0x"<<std::hex<<(u64)bottom<<std::dec
|
||||
|
@ -317,9 +310,7 @@ void nasal_vm::detail()
|
|||
[[noreturn]]
|
||||
void nasal_vm::die(const string& str)
|
||||
{
|
||||
std::cout<<bold_red<<"[vm] error: "
|
||||
<<bold_white<<str<<"\n"
|
||||
<<reset;
|
||||
std::cout<<"[vm] error: "<<str<<"\n";
|
||||
traceback();
|
||||
stackinfo();
|
||||
if(detail_info)
|
||||
|
|
Loading…
Reference in New Issue