This commit is contained in:
ValKmjolnir 2021-10-16 23:36:43 +08:00
parent d4a9412947
commit 1bfa7d2638
5 changed files with 114 additions and 117 deletions

View File

@ -90,7 +90,7 @@ void execute(const std::string& file,const uint16_t cmd)
if(cmd&VM_LEXINFO) if(cmd&VM_LEXINFO)
lexer.print(); lexer.print();
if(cmd&VM_ASTINFO) if(cmd&VM_ASTINFO)
parse.ast().print(0); parse.print();
if(cmd&VM_CODEINFO) if(cmd&VM_CODEINFO)
gen.print(); gen.print();
if(cmd&VM_EXECTIME) if(cmd&VM_EXECTIME)

View File

@ -91,8 +91,8 @@ struct nasal_vec// 24 bytes
std::vector<nasal_ref> elems; std::vector<nasal_ref> elems;
void print(); void print();
nasal_ref get_val(int); nasal_ref get_val(const int);
nasal_ref* get_mem(int); nasal_ref* get_mem(const int);
}; };
struct nasal_hash// 56 bytes struct nasal_hash// 56 bytes
@ -100,8 +100,8 @@ struct nasal_hash// 56 bytes
std::unordered_map<std::string,nasal_ref> elems; std::unordered_map<std::string,nasal_ref> elems;
void print(); void print();
nasal_ref get_val(std::string&); nasal_ref get_val(const std::string&);
nasal_ref* get_mem(std::string&); nasal_ref* get_mem(const std::string&);
}; };
struct nasal_func// 112 bytes struct nasal_func// 112 bytes
@ -137,14 +137,14 @@ struct nasal_val// 16 bytes
}; };
/*functions of nasal_vec*/ /*functions of nasal_vec*/
nasal_ref nasal_vec::get_val(int index) nasal_ref nasal_vec::get_val(const int index)
{ {
int vec_size=elems.size(); int vec_size=elems.size();
if(index<-vec_size || index>=vec_size) if(index<-vec_size || index>=vec_size)
return nasal_ref(vm_none); return {vm_none};
return elems[index>=0?index:index+vec_size]; return elems[index>=0?index:index+vec_size];
} }
nasal_ref* nasal_vec::get_mem(int index) nasal_ref* nasal_vec::get_mem(const int index)
{ {
int vec_size=elems.size(); int vec_size=elems.size();
if(index<-vec_size || index>=vec_size) if(index<-vec_size || index>=vec_size)
@ -187,7 +187,7 @@ void nasal_vec::print()
} }
/*functions of nasal_hash*/ /*functions of nasal_hash*/
nasal_ref nasal_hash::get_val(std::string& key) nasal_ref nasal_hash::get_val(const std::string& key)
{ {
if(elems.count(key)) if(elems.count(key))
return elems[key]; return elems[key];
@ -204,9 +204,9 @@ nasal_ref nasal_hash::get_val(std::string& key)
return ret; return ret;
} }
} }
return nasal_ref(vm_none); return {vm_none};
} }
nasal_ref* nasal_hash::get_mem(std::string& key) nasal_ref* nasal_hash::get_mem(const std::string& key)
{ {
if(elems.count(key)) if(elems.count(key))
return &elems[key]; return &elems[key];

View File

@ -5,10 +5,9 @@ class nasal_import
{ {
private: private:
uint32_t error; uint32_t error;
nasal_lexer import_lex; nasal_lexer lex;
nasal_parse import_par; nasal_parse par;
nasal_ast import_ast; std::vector<std::string> files;
std::vector<std::string> file_table;
void die(const std::string&,const char*); void die(const std::string&,const char*);
bool check_import(const nasal_ast&); bool check_import(const nasal_ast&);
bool check_exist(const std::string&); bool check_exist(const std::string&);
@ -18,7 +17,7 @@ private:
public: public:
uint32_t err(){return error;} uint32_t err(){return error;}
void link(nasal_parse&,const std::string&); void link(nasal_parse&,const std::string&);
const std::vector<std::string>& get_file() const {return file_table;} const std::vector<std::string>& get_file() const {return files;}
}; };
void nasal_import::die(const std::string& file,const char* stage) void nasal_import::die(const std::string& file,const char* stage)
@ -38,14 +37,14 @@ only this kind of node can be recognized as 'import':
*/ */
if(node.type()!=ast_call) if(node.type()!=ast_call)
return false; return false;
const std::vector<nasal_ast>& ref_vec=node.child(); const std::vector<nasal_ast>& vec=node.child();
if(ref_vec.size()!=2) if(vec.size()!=2)
return false; return false;
if(ref_vec[0].str()!="import") if(vec[0].str()!="import")
return false; return false;
if(ref_vec[1].type()!=ast_callf) if(vec[1].type()!=ast_callf)
return false; return false;
if(ref_vec[1].child().size()!=1 || ref_vec[1].child()[0].type()!=ast_str) if(vec[1].child().size()!=1 || vec[1].child()[0].type()!=ast_str)
return false; return false;
return true; return true;
} }
@ -53,10 +52,10 @@ only this kind of node can be recognized as 'import':
bool nasal_import::check_exist(const std::string& file) bool nasal_import::check_exist(const std::string& file)
{ {
// avoid importing the same file // avoid importing the same file
for(auto& fname:file_table) for(auto& fname:files)
if(file==fname) if(file==fname)
return true; return true;
file_table.push_back(file); files.push_back(file);
return false; return false;
} }
@ -78,21 +77,21 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
return {0,ast_root}; return {0,ast_root};
// start importing... // start importing...
import_lex.scan(filename); lex.scan(filename);
if(import_lex.err()) if(lex.err())
{ {
die(filename,"lexer"); die(filename,"lexer");
return {0,ast_root}; return {0,ast_root};
} }
import_par.compile(import_lex); par.compile(lex);
if(import_par.err()) if(par.err())
{ {
die(filename,"parser"); die(filename,"parser");
return {0,ast_root}; return {0,ast_root};
} }
nasal_ast tmp=std::move(import_par.ast()); nasal_ast tmp=std::move(par.ast());
// check if tmp has 'import' // check if tmp has 'import'
return load(tmp,file_table.size()-1); return load(tmp,files.size()-1);
} }
nasal_ast nasal_import::load(nasal_ast& root,uint16_t fileindex) nasal_ast nasal_import::load(nasal_ast& root,uint16_t fileindex)
@ -113,7 +112,7 @@ void nasal_import::link(nasal_parse& parse,const std::string& self)
{ {
// initializing // initializing
error=0; error=0;
file_table={self}; files={self};
// scan root and import files,then generate a new ast and return to import_ast // scan root and import files,then generate a new ast and return to import_ast
// the main file's index is 0 // the main file's index is 0
parse.ast()=load(parse.ast(),0); parse.ast()=load(parse.ast(),0);

View File

@ -100,6 +100,7 @@ private:
nasal_ast ret_expr(); nasal_ast ret_expr();
public: public:
uint32_t err(){return error;} uint32_t err(){return error;}
void print(){root.print(0);}
void compile(const nasal_lexer&); void compile(const nasal_lexer&);
nasal_ast& ast(){return root;} nasal_ast& ast(){return root;}
const nasal_ast& ast() const {return root;} const nasal_ast& ast() const {return root;}

View File

@ -14,7 +14,7 @@ private:
std::stack<int> counter; // iterator stack for forindex/foreach std::stack<int> counter; // iterator stack for forindex/foreach
const double* num_table;// numbers used in process(const calculation) const double* num_table;// numbers used in process(const calculation)
std::vector<std::string> str_table;// symbols used in process std::vector<std::string> str_table;// symbols used in process
const uint32_t* imm; // immediate number std::vector<uint32_t> imm; // immediate number
nasal_ref* mem_addr; // used for mem_call nasal_ref* mem_addr; // used for mem_call
nasal_gc gc; // garbage collector nasal_gc gc; // garbage collector
/* values used for debug */ /* values used for debug */
@ -124,7 +124,6 @@ void nasal_vm::init(
const std::vector<std::string>& filenames) const std::vector<std::string>& filenames)
{ {
gc.init(strs); gc.init(strs);
gc.val_stack[STACK_MAX_DEPTH-1].value.gcobj=nullptr;
num_table=nums.data(); // get constant numbers num_table=nums.data(); // get constant numbers
str_table=strs; // get constant strings & symbols str_table=strs; // get constant strings & symbols
files=filenames;// get filenames for debugger files=filenames;// get filenames for debugger
@ -804,20 +803,18 @@ void nasal_vm::run(const nasal_codegen& gen,const nasal_import& linker,const boo
&&mcallh, &&ret, &&vmexit &&mcallh, &&ret, &&vmexit
}; };
bytecode=gen.get_code(); bytecode=gen.get_code();
std::vector<const void*> codes; std::vector<const void*> code;
std::vector<uint32_t> imms;
for(auto& i:bytecode) for(auto& i:bytecode)
{ {
codes.push_back(opr_table[i.op]); code.push_back(opr_table[i.op]);
imms.push_back(i.num); imm.push_back(i.num);
} }
auto code=codes.data();
imm=imms.data();
// set canary and program counter // set canary and program counter
auto& canary=gc.val_stack[STACK_MAX_DEPTH-1]; auto& canary=gc.val_stack[STACK_MAX_DEPTH-1];
canary.value.gcobj=nullptr;
pc=0; pc=0;
// run // goto the first operand
goto *code[pc]; goto *code[pc];
vmexit: vmexit:
@ -846,83 +843,83 @@ vmexit:
// do not cause stackoverflow // do not cause stackoverflow
#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];} #define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
nop: exec_opnodie(opr_nop ,op_nop ); // do nothing nop: exec_opnodie(opr_nop ,op_nop ); // 0
intg: exec_opnodie(opr_intg ,op_intg ); // stack+=imm[pc] (detected at codegen) intg: exec_opnodie(opr_intg ,op_intg ); // +imm[pc] (detected at codegen)
intl: exec_opnodie(opr_intl ,op_intl ); // stack-=0 intl: exec_opnodie(opr_intl ,op_intl ); // -0
loadg: exec_opnodie(opr_loadg ,op_loadg ); // stack-=1 loadg: exec_opnodie(opr_loadg ,op_loadg ); // -1
loadl: exec_opnodie(opr_loadl ,op_loadl ); // stack-=1 loadl: exec_opnodie(opr_loadl ,op_loadl ); // -1
loadu: exec_opnodie(opr_loadu ,op_loadu ); // stack-=1 loadu: exec_opnodie(opr_loadu ,op_loadu ); // -1
pnum: exec_operand(opr_pnum ,op_pnum ); // stack+=1 pnum: exec_operand(opr_pnum ,op_pnum ); // +1
pone: exec_operand(opr_pone ,op_pone ); // stack+=1 pone: exec_operand(opr_pone ,op_pone ); // +1
pzero: exec_operand(opr_pzero ,op_pzero ); // stack+=1 pzero: exec_operand(opr_pzero ,op_pzero ); // +1
pnil: exec_operand(opr_pnil ,op_pnil ); // stack+=1 pnil: exec_operand(opr_pnil ,op_pnil ); // +1
pstr: exec_operand(opr_pstr ,op_pstr ); // stack+=1 pstr: exec_operand(opr_pstr ,op_pstr ); // +1
newv: exec_operand(opr_newv ,op_newv ); // stack+=1-imm[pc] newv: exec_operand(opr_newv ,op_newv ); // +1-imm[pc]
newh: exec_operand(opr_newh ,op_newh ); // stack+=1 newh: exec_operand(opr_newh ,op_newh ); // +1
newf: exec_operand(opr_newf ,op_newf ); // stack+=1 newf: exec_operand(opr_newf ,op_newf ); // +1
happ: exec_opnodie(opr_happ ,op_happ ); // stack-=1 happ: exec_opnodie(opr_happ ,op_happ ); // -1
para: exec_opnodie(opr_para ,op_para ); // stack-=0 para: exec_opnodie(opr_para ,op_para ); // -0
defpara: exec_opnodie(opr_defpara ,op_defpara ); // stack-=1 defpara: exec_opnodie(opr_defpara ,op_defpara ); // -1
dynpara: exec_opnodie(opr_dynpara ,op_dynpara ); // stack-=0 dynpara: exec_opnodie(opr_dynpara ,op_dynpara ); // -0
unot: exec_opnodie(opr_unot ,op_unot ); // stack-=0 unot: exec_opnodie(opr_unot ,op_unot ); // -0
usub: exec_opnodie(opr_usub ,op_usub ); // stack-=0 usub: exec_opnodie(opr_usub ,op_usub ); // -0
add: exec_opnodie(opr_add ,op_add ); // stack-=1 add: exec_opnodie(opr_add ,op_add ); // -1
sub: exec_opnodie(opr_sub ,op_sub ); // stack-=1 sub: exec_opnodie(opr_sub ,op_sub ); // -1
mul: exec_opnodie(opr_mul ,op_mul ); // stack-=1 mul: exec_opnodie(opr_mul ,op_mul ); // -1
div: exec_opnodie(opr_div ,op_div ); // stack-=1 div: exec_opnodie(opr_div ,op_div ); // -1
lnk: exec_opnodie(opr_lnk ,op_lnk ); // stack-=1 lnk: exec_opnodie(opr_lnk ,op_lnk ); // -1
addc: exec_opnodie(opr_addc ,op_addc ); // stack-=0 addc: exec_opnodie(opr_addc ,op_addc ); // -0
subc: exec_opnodie(opr_subc ,op_subc ); // stack-=0 subc: exec_opnodie(opr_subc ,op_subc ); // -0
mulc: exec_opnodie(opr_mulc ,op_mulc ); // stack-=0 mulc: exec_opnodie(opr_mulc ,op_mulc ); // -0
divc: exec_opnodie(opr_divc ,op_divc ); // stack-=0 divc: exec_opnodie(opr_divc ,op_divc ); // -0
lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); // stack-=0 lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); // -0
addeq: exec_opnodie(opr_addeq ,op_addeq ); // stack-=1 addeq: exec_opnodie(opr_addeq ,op_addeq ); // -1
subeq: exec_opnodie(opr_subeq ,op_subeq ); // stack-=1 subeq: exec_opnodie(opr_subeq ,op_subeq ); // -1
muleq: exec_opnodie(opr_muleq ,op_muleq ); // stack-=1 muleq: exec_opnodie(opr_muleq ,op_muleq ); // -1
diveq: exec_opnodie(opr_diveq ,op_diveq ); // stack-=1 diveq: exec_opnodie(opr_diveq ,op_diveq ); // -1
lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); // stack-=1 lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); // -1
addeqc: exec_opnodie(opr_addeqc ,op_addeqc ); // stack-=0 addeqc: exec_opnodie(opr_addeqc ,op_addeqc ); // -0
subeqc: exec_opnodie(opr_subeqc ,op_subeqc ); // stack-=0 subeqc: exec_opnodie(opr_subeqc ,op_subeqc ); // -0
muleqc: exec_opnodie(opr_muleqc ,op_muleqc ); // stack-=0 muleqc: exec_opnodie(opr_muleqc ,op_muleqc ); // -0
diveqc: exec_opnodie(opr_diveqc ,op_diveqc ); // stack-=0 diveqc: exec_opnodie(opr_diveqc ,op_diveqc ); // -0
lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc ); // stack-=0 lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc ); // -0
meq: exec_opnodie(opr_meq ,op_meq ); // stack-=1 meq: exec_opnodie(opr_meq ,op_meq ); // -1
eq: exec_opnodie(opr_eq ,op_eq ); // stack-=1 eq: exec_opnodie(opr_eq ,op_eq ); // -1
neq: exec_opnodie(opr_neq ,op_neq ); // stack-=1 neq: exec_opnodie(opr_neq ,op_neq ); // -1
less: exec_opnodie(opr_less ,op_less ); // stack-=1 less: exec_opnodie(opr_less ,op_less ); // -1
leq: exec_opnodie(opr_leq ,op_leq ); // stack-=1 leq: exec_opnodie(opr_leq ,op_leq ); // -1
grt: exec_opnodie(opr_grt ,op_grt ); // stack-=1 grt: exec_opnodie(opr_grt ,op_grt ); // -1
geq: exec_opnodie(opr_geq ,op_geq ); // stack-=1 geq: exec_opnodie(opr_geq ,op_geq ); // -1
lessc: exec_opnodie(opr_lessc ,op_lessc ); // stack-=0 lessc: exec_opnodie(opr_lessc ,op_lessc ); // -0
leqc: exec_opnodie(opr_leqc ,op_leqc ); // stack-=0 leqc: exec_opnodie(opr_leqc ,op_leqc ); // -0
grtc: exec_opnodie(opr_grtc ,op_grtc ); // stack-=0 grtc: exec_opnodie(opr_grtc ,op_grtc ); // -0
geqc: exec_opnodie(opr_geqc ,op_geqc ); // stack-=0 geqc: exec_opnodie(opr_geqc ,op_geqc ); // -0
pop: exec_opnodie(opr_pop ,op_pop ); // stack-=1 pop: exec_opnodie(opr_pop ,op_pop ); // -1
jmp: exec_opnodie(opr_jmp ,op_jmp ); // stack-=0 jmp: exec_opnodie(opr_jmp ,op_jmp ); // -0
jt: exec_opnodie(opr_jt ,op_jt ); // stack-=0 jt: exec_opnodie(opr_jt ,op_jt ); // -0
jf: exec_opnodie(opr_jf ,op_jf ); // stack-=1 jf: exec_opnodie(opr_jf ,op_jf ); // -1
counter: exec_opnodie(opr_counter ,op_cnt ); // stack-=0 counter: exec_opnodie(opr_counter ,op_cnt ); // -0
cntpop: exec_opnodie(opr_cntpop ,op_cntpop ); // stack-=0 cntpop: exec_opnodie(opr_cntpop ,op_cntpop ); // -0
findex: exec_operand(opr_findex ,op_findex ); // stack+=1 findex: exec_operand(opr_findex ,op_findex ); // +1
feach: exec_operand(opr_feach ,op_feach ); // stack+=1 feach: exec_operand(opr_feach ,op_feach ); // +1
callg: exec_operand(opr_callg ,op_callg ); // stack+=1 callg: exec_operand(opr_callg ,op_callg ); // +1
calll: exec_operand(opr_calll ,op_calll ); // stack+=1 calll: exec_operand(opr_calll ,op_calll ); // +1
upval: exec_operand(opr_upval ,op_upval ); // stack+=1 upval: exec_operand(opr_upval ,op_upval ); // +1
callv: exec_opnodie(opr_callv ,op_callv ); // stack-=0 callv: exec_opnodie(opr_callv ,op_callv ); // -0
callvi: exec_opnodie(opr_callvi ,op_callvi ); // stack-=0 callvi: exec_opnodie(opr_callvi ,op_callvi ); // -0
callh: exec_opnodie(opr_callh ,op_callh ); // stack-=0 callh: exec_opnodie(opr_callh ,op_callh ); // -0
callfv: exec_opnodie(opr_callfv ,op_callfv ); // stack-=0 callfv: exec_opnodie(opr_callfv ,op_callfv ); // -0
callfh: exec_opnodie(opr_callfh ,op_callfh ); // stack-=0 callfh: exec_opnodie(opr_callfh ,op_callfh ); // -0
callb: exec_opnodie(opr_callb ,op_callb ); // stack-=0 callb: exec_opnodie(opr_callb ,op_callb ); // -0
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // stack+=1 slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // +1
slcend: exec_opnodie(opr_slcend ,op_slcend ); // stack-=1 slcend: exec_opnodie(opr_slcend ,op_slcend ); // -1
slc: exec_opnodie(opr_slc ,op_slc ); // stack-=1 slc: exec_opnodie(opr_slc ,op_slc ); // -1
slc2: exec_opnodie(opr_slc2 ,op_slc2 ); // stack-=2 slc2: exec_opnodie(opr_slc2 ,op_slc2 ); // -2
mcallg: exec_operand(opr_mcallg ,op_mcallg ); // stack+=1 mcallg: exec_operand(opr_mcallg ,op_mcallg ); // +1
mcalll: exec_operand(opr_mcalll ,op_mcalll ); // stack+=1 mcalll: exec_operand(opr_mcalll ,op_mcalll ); // +1
mupval: exec_operand(opr_mupval ,op_mupval ); // stack+=1 mupval: exec_operand(opr_mupval ,op_mupval ); // +1
mcallv: exec_opnodie(opr_mcallv ,op_mcallv ); // stack-=0 mcallv: exec_opnodie(opr_mcallv ,op_mcallv ); // -0
mcallh: exec_opnodie(opr_mcallh ,op_mcallh ); // stack-=0 mcallh: exec_opnodie(opr_mcallh ,op_mcallh ); // -0
ret: exec_opnodie(opr_ret ,op_ret ); // stack-=1 ret: exec_opnodie(opr_ret ,op_ret ); // -1
} }
#endif #endif