update
This commit is contained in:
parent
71f501a323
commit
d8ce203ab3
33
main.cpp
33
main.cpp
|
@ -17,7 +17,8 @@ void help()
|
|||
std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
|
||||
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
|
||||
std::cout<<">> [run ] run abstract syntax tree.\n";
|
||||
std::cout<<">> [exec ] generate byte code.\n";
|
||||
std::cout<<">> [code ] show byte code.\n";
|
||||
std::cout<<">> [exec ] execute program on bytecode vm.\n";
|
||||
std::cout<<">> [logo ] print logo of nasal .\n";
|
||||
std::cout<<">> [exit ] quit nasal interpreter.\n";
|
||||
return;
|
||||
|
@ -108,7 +109,7 @@ void runtime_start()
|
|||
return;
|
||||
}
|
||||
|
||||
void execute()
|
||||
void show_bytecode()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
|
@ -132,6 +133,32 @@ void execute()
|
|||
}
|
||||
code_generator.main_progress(import.get_root());
|
||||
code_generator.print_byte_code();
|
||||
return;
|
||||
}
|
||||
|
||||
void execute()
|
||||
{
|
||||
lexer.openfile(inputfile);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
{
|
||||
die("lexer",inputfile);
|
||||
return;
|
||||
}
|
||||
parse.set_toklist(lexer.get_token_list());
|
||||
parse.main_process();
|
||||
if(parse.get_error())
|
||||
{
|
||||
die("parse",inputfile);
|
||||
return;
|
||||
}
|
||||
import.link(parse.get_root());
|
||||
if(import.get_error())
|
||||
{
|
||||
die("import",inputfile);
|
||||
return;
|
||||
}
|
||||
code_generator.main_progress(import.get_root());
|
||||
bytevm.run(
|
||||
code_generator.get_string_table(),
|
||||
code_generator.get_number_table(),
|
||||
|
@ -189,6 +216,8 @@ int main()
|
|||
ast_print();
|
||||
else if(command=="run")
|
||||
runtime_start();
|
||||
else if(command=="code")
|
||||
show_bytecode();
|
||||
else if(command=="exec")
|
||||
execute();
|
||||
else if(command=="logo")
|
||||
|
|
|
@ -7,16 +7,27 @@ private:
|
|||
int error;
|
||||
int ptr;
|
||||
int global_scope_addr;
|
||||
// garbage collector and memory manager
|
||||
nasal_virtual_machine vm;
|
||||
// byte codes store here
|
||||
std::vector<opcode> exec_code;
|
||||
// main calculation stack
|
||||
std::stack<int> value_stack;
|
||||
// local scope for function block
|
||||
std::stack<int> local_scope_stack;
|
||||
// slice stack for vec[val,val,val:val]
|
||||
std::stack<int> slice_stack;
|
||||
// ptr stack stores address for function to return
|
||||
std::stack<int> call_stack;
|
||||
// iterator stack for forindex/foreach
|
||||
std::stack<int> counter_stack;
|
||||
// string table
|
||||
std::vector<std::string> string_table;
|
||||
// number table
|
||||
std::vector<double> number_table;
|
||||
// opcode -> function address table
|
||||
std::vector<void (nasal_bytecode_vm::*)()> opr_table;
|
||||
// builtin function address table
|
||||
std::map<std::string,int (*)(int x,nasal_virtual_machine& vm)> builtin_func_hashmap;
|
||||
void die(std::string);
|
||||
bool check_condition(int);
|
||||
|
@ -182,7 +193,15 @@ void nasal_bytecode_vm::clear()
|
|||
void nasal_bytecode_vm::die(std::string str)
|
||||
{
|
||||
++error;
|
||||
std::cout<<">> [vm] "<<str<<'\n';
|
||||
std::string numinfo="";
|
||||
int num=ptr;
|
||||
for(int i=0;i<8;++i)
|
||||
{
|
||||
int tmp=num&0x0f;
|
||||
numinfo=(char)(tmp>9? 'a'+tmp-10:'0'+tmp)+numinfo;
|
||||
num>>=4;
|
||||
}
|
||||
std::cout<<">> [vm] 0x"<<numinfo<<": "<<str<<'\n';
|
||||
return;
|
||||
}
|
||||
bool nasal_bytecode_vm::check_condition(int value_addr)
|
||||
|
@ -1004,6 +1023,7 @@ void nasal_bytecode_vm::opr_forindex()
|
|||
{
|
||||
vm.del_reference(value_stack.top());
|
||||
value_stack.pop();
|
||||
counter_stack.pop();
|
||||
ptr=exec_code[ptr].index-1;
|
||||
return;
|
||||
}
|
||||
|
@ -1020,6 +1040,7 @@ void nasal_bytecode_vm::opr_foreach()
|
|||
{
|
||||
vm.del_reference(value_stack.top());
|
||||
value_stack.pop();
|
||||
counter_stack.pop();
|
||||
ptr=exec_code[ptr].index-1;
|
||||
return;
|
||||
}
|
||||
|
@ -1033,10 +1054,14 @@ void nasal_bytecode_vm::opr_call()
|
|||
int val_addr=-1;
|
||||
if(local_scope_stack.top()>=0)
|
||||
val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(string_table[exec_code[ptr].index]);
|
||||
else
|
||||
if(val_addr<0)
|
||||
val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(string_table[exec_code[ptr].index]);
|
||||
if(val_addr<0)
|
||||
{
|
||||
die("call: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\"");
|
||||
return;
|
||||
}
|
||||
vm.add_reference(val_addr);
|
||||
value_stack.push(val_addr);
|
||||
return;
|
||||
}
|
||||
|
@ -1098,6 +1123,11 @@ void nasal_bytecode_vm::opr_callv()
|
|||
die("callv: cannot find member \""+vm.gc_get(val_addr).get_string()+"\" of this hash");
|
||||
return;
|
||||
}
|
||||
if(vm.gc_get(res).get_type()==vm_function)
|
||||
{
|
||||
vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value("me",val_addr);
|
||||
vm.add_reference(val_addr);
|
||||
}
|
||||
vm.add_reference(res);
|
||||
value_stack.push(res);
|
||||
}
|
||||
|
@ -1133,8 +1163,16 @@ void nasal_bytecode_vm::opr_callh()
|
|||
return;
|
||||
}
|
||||
int res=vm.gc_get(val_addr).get_hash().get_value_address(string_table[exec_code[ptr].index]);
|
||||
if(res<0)
|
||||
{
|
||||
die("callh: hash member \""+string_table[exec_code[ptr].index]+"\" does not exist");
|
||||
return;
|
||||
}
|
||||
vm.add_reference(res);
|
||||
vm.del_reference(val_addr);
|
||||
if(vm.gc_get(res).get_type()==vm_function)
|
||||
vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value("me",val_addr);
|
||||
else
|
||||
vm.del_reference(val_addr);
|
||||
value_stack.push(res);
|
||||
return;
|
||||
}
|
||||
|
@ -1154,7 +1192,6 @@ void nasal_bytecode_vm::opr_callf()
|
|||
ref_closure.add_scope();
|
||||
local_scope_stack.push(closure);
|
||||
vm.add_reference(closure);
|
||||
// unfinished
|
||||
if(vm.gc_get(para_addr).get_type()==vm_vector)
|
||||
{
|
||||
nasal_vector& ref_vec=vm.gc_get(para_addr).get_vector();
|
||||
|
@ -1212,8 +1249,8 @@ void nasal_bytecode_vm::opr_callf()
|
|||
die("callf: lack argument(s)");
|
||||
return;
|
||||
}
|
||||
vm.add_reference(tmp);
|
||||
ref_closure.add_new_value(ref_para[i],tmp);
|
||||
vm.add_reference(tmp);
|
||||
}
|
||||
}
|
||||
vm.del_reference(para_addr);
|
||||
|
@ -1333,7 +1370,7 @@ void nasal_bytecode_vm::opr_mcall()
|
|||
int mem_addr=-1;
|
||||
if(local_scope_stack.top()>=0)
|
||||
mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(string_table[exec_code[ptr].index]);
|
||||
else
|
||||
if(mem_addr<0)
|
||||
mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(string_table[exec_code[ptr].index]);
|
||||
if(mem_addr<0)
|
||||
die("mcall: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\"");
|
||||
|
@ -1390,8 +1427,6 @@ void nasal_bytecode_vm::opr_mcallv()
|
|||
void nasal_bytecode_vm::opr_mcallh()
|
||||
{
|
||||
int mem_addr=-1;
|
||||
int val_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
int hash_addr=vm.mem_get(value_stack.top());
|
||||
value_stack.pop();
|
||||
if(vm.gc_get(hash_addr).get_type()!=vm_hash)
|
||||
|
@ -1399,7 +1434,7 @@ void nasal_bytecode_vm::opr_mcallh()
|
|||
die("mcallh: must call a hash");
|
||||
return;
|
||||
}
|
||||
mem_addr=vm.gc_get(hash_addr).get_hash().get_mem_address(vm.gc_get(val_addr).get_string());
|
||||
mem_addr=vm.gc_get(hash_addr).get_hash().get_mem_address(string_table[exec_code[ptr].index]);
|
||||
if(mem_addr<0)
|
||||
{
|
||||
die("mcallh: cannot get memory space in this hash");
|
||||
|
@ -1435,18 +1470,23 @@ void nasal_bytecode_vm::run(std::vector<std::string>& strs,std::vector<double>&
|
|||
tmp=exec[i];
|
||||
exec_code.push_back(tmp);
|
||||
}
|
||||
|
||||
|
||||
error=0;
|
||||
global_scope_addr=vm.gc_alloc(vm_closure);
|
||||
size=exec_code.size();
|
||||
time_t begin_time=std::time(NULL);
|
||||
for(ptr=0;ptr<size;++ptr)
|
||||
{
|
||||
std::cout<<ptr<<'\n';
|
||||
(this->*opr_table[exec_code[ptr].op])();
|
||||
if(error)
|
||||
break;
|
||||
}
|
||||
time_t end_time=std::time(NULL);
|
||||
time_t total_run_time=end_time-begin_time;
|
||||
if(total_run_time>=1)
|
||||
std::cout<<">> [vm] process exited after "<<total_run_time<<"s.\n";
|
||||
vm.del_reference(global_scope_addr);
|
||||
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ private:
|
|||
void multi_assignment_gen(nasal_ast&);
|
||||
void conditional_gen(nasal_ast&);
|
||||
void loop_gen(nasal_ast&);
|
||||
void load_continue_break();
|
||||
void load_continue_break(int,int);
|
||||
void while_gen(nasal_ast&);
|
||||
void for_gen(nasal_ast&);
|
||||
void forindex_gen(nasal_ast&);
|
||||
|
@ -465,10 +465,11 @@ void nasal_codegen::call_func(nasal_ast& ast)
|
|||
for(int i=0;i<size;++i)
|
||||
{
|
||||
nasal_ast& tmp=ast.get_children()[i];
|
||||
string_gen(tmp.get_children()[0]);
|
||||
calculation_gen(tmp.get_children()[1]);
|
||||
std::string str=tmp.get_children()[0].get_str();
|
||||
regist_string(str);
|
||||
op.op=op_hashapp;
|
||||
op.index=0;
|
||||
op.index=string_table[str];
|
||||
exec_code.push_back(op);
|
||||
}
|
||||
op.op=op_callf;
|
||||
|
@ -683,13 +684,13 @@ void nasal_codegen::loop_gen(nasal_ast& ast)
|
|||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::load_continue_break()
|
||||
void nasal_codegen::load_continue_break(int continue_place,int break_place)
|
||||
{
|
||||
for(int i=0;i<continue_ptr.size();++i)
|
||||
exec_code[continue_ptr[i]].index=exec_code.size()-2;
|
||||
exec_code[continue_ptr[i]].index=continue_place;
|
||||
continue_ptr.clear();
|
||||
for(int i=0;i<break_ptr.size();++i)
|
||||
exec_code[break_ptr[i]].index=exec_code.size();
|
||||
exec_code[break_ptr[i]].index=break_place;
|
||||
break_ptr.clear();
|
||||
return;
|
||||
}
|
||||
|
@ -709,7 +710,7 @@ void nasal_codegen::while_gen(nasal_ast& ast)
|
|||
exec_code.push_back(op);
|
||||
exec_code[condition_ptr].index=exec_code.size();
|
||||
pop_gen();
|
||||
load_continue_break();
|
||||
load_continue_break(exec_code.size()-2,exec_code.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -744,6 +745,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
|
|||
exec_code.push_back(op);
|
||||
pop_gen();
|
||||
block_gen(ast.get_children()[3]);
|
||||
int continue_place=exec_code.size();
|
||||
switch(ast.get_children()[2].get_type())
|
||||
{
|
||||
case ast_null:break;
|
||||
|
@ -763,7 +765,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
|
|||
exec_code.push_back(op);
|
||||
exec_code[label_exit].index=exec_code.size();
|
||||
pop_gen();
|
||||
load_continue_break();
|
||||
load_continue_break(continue_place,exec_code.size());
|
||||
return;
|
||||
}
|
||||
void nasal_codegen::forindex_gen(nasal_ast& ast)
|
||||
|
@ -799,7 +801,7 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
|
|||
op.index=ptr;
|
||||
exec_code.push_back(op);
|
||||
exec_code[ptr].index=exec_code.size();
|
||||
load_continue_break();
|
||||
load_continue_break(exec_code.size()-1,exec_code.size());
|
||||
return;
|
||||
}
|
||||
void nasal_codegen::foreach_gen(nasal_ast& ast)
|
||||
|
@ -835,7 +837,7 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
|
|||
op.index=ptr;
|
||||
exec_code.push_back(op);
|
||||
exec_code[ptr].index=exec_code.size();
|
||||
load_continue_break();
|
||||
load_continue_break(exec_code.size()-1,exec_code.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1125,6 +1127,8 @@ void nasal_codegen::return_gen(nasal_ast& ast)
|
|||
{
|
||||
if(ast.get_children().size())
|
||||
calculation_gen(ast.get_children()[0]);
|
||||
else
|
||||
nil_gen();
|
||||
opcode op;
|
||||
op.op=op_return;
|
||||
exec_code.push_back(op);
|
||||
|
|
Loading…
Reference in New Issue