update
This commit is contained in:
parent
a5825e0e92
commit
71f501a323
9
main.cpp
9
main.cpp
|
@ -132,10 +132,11 @@ void execute()
|
|||
}
|
||||
code_generator.main_progress(import.get_root());
|
||||
code_generator.print_byte_code();
|
||||
bytevm.set_string_table(code_generator.get_string_table());
|
||||
bytevm.set_number_table(code_generator.get_number_table());
|
||||
bytevm.set_exec_code(code_generator.get_exec_code());
|
||||
//bytevm.run();
|
||||
bytevm.run(
|
||||
code_generator.get_string_table(),
|
||||
code_generator.get_number_table(),
|
||||
code_generator.get_exec_code()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,10 +80,7 @@ public:
|
|||
nasal_bytecode_vm();
|
||||
~nasal_bytecode_vm();
|
||||
void clear();
|
||||
void set_string_table(std::vector<std::string>&);
|
||||
void set_number_table(std::vector<double>&);
|
||||
void set_exec_code(std::vector<opcode>&);
|
||||
void run();
|
||||
void run(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
||||
};
|
||||
|
||||
nasal_bytecode_vm::nasal_bytecode_vm()
|
||||
|
@ -172,10 +169,14 @@ void nasal_bytecode_vm::clear()
|
|||
vm.clear();
|
||||
global_scope_addr=-1;
|
||||
while(!value_stack.empty())value_stack.pop();
|
||||
while(local_scope_stack.top()!=-1)local_scope_stack.pop();
|
||||
while(!local_scope_stack.empty())local_scope_stack.pop();
|
||||
local_scope_stack.push(-1);
|
||||
while(!slice_stack.empty())slice_stack.pop();
|
||||
while(!call_stack.empty())call_stack.pop();
|
||||
while(!counter_stack.empty())counter_stack.pop();
|
||||
string_table.clear();
|
||||
number_table.clear();
|
||||
exec_code.clear();
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::die(std::string str)
|
||||
|
@ -211,7 +212,10 @@ void nasal_bytecode_vm::opr_load()
|
|||
{
|
||||
int val_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
vm.gc_get(global_scope_addr).get_closure().add_new_value(string_table[exec_code[ptr].index],val_addr);
|
||||
if(local_scope_stack.top()>=0)
|
||||
vm.gc_get(local_scope_stack.top()).get_closure().add_new_value(string_table[exec_code[ptr].index],val_addr);
|
||||
else
|
||||
vm.gc_get(global_scope_addr).get_closure().add_new_value(string_table[exec_code[ptr].index],val_addr);
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::opr_pushnum()
|
||||
|
@ -285,38 +289,27 @@ void nasal_bytecode_vm::opr_hashapp()
|
|||
{
|
||||
int val_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
int str_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
int hash_addr=value_stack.top();
|
||||
vm.gc_get(hash_addr).get_hash().add_elem(vm.gc_get(str_addr).get_string(),val_addr);
|
||||
vm.del_reference(str_addr);
|
||||
vm.gc_get(hash_addr).get_hash().add_elem(string_table[exec_code[ptr].index],val_addr);
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::opr_para()
|
||||
{
|
||||
int str_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
std::string str=vm.gc_get(str_addr).get_string();
|
||||
vm.del_reference(str_addr);
|
||||
vm.gc_get(value_stack.top()).get_func().add_para(str,-1);
|
||||
std::string str=string_table[exec_code[ptr].index];
|
||||
vm.gc_get(value_stack.top()).get_func().add_para(str);
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::opr_defpara()
|
||||
{
|
||||
int str_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
std::string str=vm.gc_get(str_addr).get_string();
|
||||
vm.del_reference(str_addr);
|
||||
vm.gc_get(value_stack.top()).get_func().add_para(str,value_stack.top());
|
||||
int val_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
std::string str=string_table[exec_code[ptr].index];
|
||||
vm.gc_get(value_stack.top()).get_func().add_para(str,val_addr);
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::opr_dynpara()
|
||||
{
|
||||
int str_addr=value_stack.top();
|
||||
value_stack.pop();
|
||||
std::string str=vm.gc_get(str_addr).get_string();
|
||||
vm.del_reference(str_addr);
|
||||
std::string str=string_table[exec_code[ptr].index];
|
||||
vm.gc_get(value_stack.top()).get_func().add_para(str,-1,true);
|
||||
return;
|
||||
}
|
||||
|
@ -1039,9 +1032,9 @@ void nasal_bytecode_vm::opr_call()
|
|||
{
|
||||
int val_addr=-1;
|
||||
if(local_scope_stack.top()>=0)
|
||||
vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(string_table[exec_code[ptr].index]);
|
||||
val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(string_table[exec_code[ptr].index]);
|
||||
else
|
||||
vm.gc_get(global_scope_addr).get_closure().get_value_address(string_table[exec_code[ptr].index]);
|
||||
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]+"\"");
|
||||
value_stack.push(val_addr);
|
||||
|
@ -1157,10 +1150,73 @@ void nasal_bytecode_vm::opr_callf()
|
|||
}
|
||||
nasal_function& ref=vm.gc_get(func_addr).get_func();
|
||||
int closure=ref.get_closure_addr();
|
||||
vm.gc_get(closure).get_closure().add_scope();
|
||||
nasal_closure& ref_closure=vm.gc_get(closure).get_closure();
|
||||
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();
|
||||
std::vector<std::string>& ref_para=ref.get_para();
|
||||
std::vector<int>& ref_default=ref.get_default();
|
||||
int i=0;
|
||||
for(;i<ref_para.size();++i)
|
||||
{
|
||||
if(i>=ref_vec.size())
|
||||
{
|
||||
if(ref_default[i]<0)
|
||||
{
|
||||
die("callf: lack argument(s)");
|
||||
return;
|
||||
}
|
||||
ref_closure.add_new_value(ref_para[i],ref_default[i]);
|
||||
vm.add_reference(ref_default[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmp=ref_vec.get_value_address(i);
|
||||
ref_closure.add_new_value(ref_para[i],tmp);
|
||||
vm.add_reference(tmp);
|
||||
}
|
||||
}
|
||||
if(ref.get_dynamic_para().length())
|
||||
{
|
||||
int vec_addr=vm.gc_alloc(vm_vector);
|
||||
for(;i<ref_vec.size();++i)
|
||||
{
|
||||
int tmp=ref_vec.get_value_address(i);
|
||||
vm.gc_get(vec_addr).get_vector().add_elem(tmp);
|
||||
vm.add_reference(tmp);
|
||||
}
|
||||
ref_closure.add_new_value(ref.get_dynamic_para(),vec_addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nasal_hash& ref_hash=vm.gc_get(para_addr).get_hash();
|
||||
std::vector<std::string>& ref_para=ref.get_para();
|
||||
std::vector<int>& ref_default=ref.get_default();
|
||||
if(ref.get_dynamic_para().length())
|
||||
{
|
||||
die("callf: special call cannot use dynamic parameter");
|
||||
return;
|
||||
}
|
||||
for(int i=0;i<ref_para.size();++i)
|
||||
{
|
||||
int tmp=ref_hash.get_special_para(ref_para[i]);
|
||||
if(tmp<0)
|
||||
tmp=ref_default[i];
|
||||
if(tmp<0)
|
||||
{
|
||||
die("callf: lack argument(s)");
|
||||
return;
|
||||
}
|
||||
vm.add_reference(tmp);
|
||||
ref_closure.add_new_value(ref_para[i],tmp);
|
||||
}
|
||||
}
|
||||
vm.del_reference(para_addr);
|
||||
call_stack.push(ptr);
|
||||
ptr=ref.get_entry()-1;
|
||||
return;
|
||||
|
@ -1182,7 +1238,7 @@ void nasal_bytecode_vm::opr_slicebegin()
|
|||
int val_addr=vm.gc_alloc(vm_vector);
|
||||
slice_stack.push(val_addr);
|
||||
if(vm.gc_get(value_stack.top()).get_type()!=vm_vector)
|
||||
die("must slice a vector");
|
||||
die("slcbegin: must slice a vector");
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::opr_sliceend()
|
||||
|
@ -1340,13 +1396,13 @@ void nasal_bytecode_vm::opr_mcallh()
|
|||
value_stack.pop();
|
||||
if(vm.gc_get(hash_addr).get_type()!=vm_hash)
|
||||
{
|
||||
die("must call a hash");
|
||||
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());
|
||||
if(mem_addr<0)
|
||||
{
|
||||
die("cannot get memory space in this hash");
|
||||
die("mcallh: cannot get memory space in this hash");
|
||||
return;
|
||||
}
|
||||
value_stack.push(mem_addr);
|
||||
|
@ -1360,20 +1416,18 @@ void nasal_bytecode_vm::opr_return()
|
|||
vm.del_reference(closure_addr);
|
||||
ptr=call_stack.top();
|
||||
call_stack.pop();
|
||||
int tmp=value_stack.top();
|
||||
value_stack.pop();
|
||||
// delete function
|
||||
vm.del_reference(value_stack.top());
|
||||
value_stack.pop();
|
||||
value_stack.push(tmp);
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::set_string_table(std::vector<std::string>& table)
|
||||
{
|
||||
string_table=table;
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::set_number_table(std::vector<double>& table)
|
||||
{
|
||||
number_table=table;
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::set_exec_code(std::vector<opcode>& exec)
|
||||
void nasal_bytecode_vm::run(std::vector<std::string>& strs,std::vector<double>& nums,std::vector<opcode>& exec)
|
||||
{
|
||||
string_table=strs;
|
||||
number_table=nums;
|
||||
int size=exec.size();
|
||||
for(int i=0;i<size;++i)
|
||||
{
|
||||
|
@ -1381,15 +1435,13 @@ void nasal_bytecode_vm::set_exec_code(std::vector<opcode>& exec)
|
|||
tmp=exec[i];
|
||||
exec_code.push_back(tmp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void nasal_bytecode_vm::run()
|
||||
{
|
||||
|
||||
error=0;
|
||||
global_scope_addr=vm.gc_alloc(vm_closure);
|
||||
int size=exec_code.size();
|
||||
size=exec_code.size();
|
||||
for(ptr=0;ptr<size;++ptr)
|
||||
{
|
||||
std::cout<<ptr<<'\n';
|
||||
(this->*opr_table[exec_code[ptr].op])();
|
||||
if(error)
|
||||
break;
|
||||
|
|
|
@ -277,10 +277,11 @@ void nasal_codegen::hash_gen(nasal_ast& ast)
|
|||
exec_code.push_back(op);
|
||||
for(int i=0;i<size;++i)
|
||||
{
|
||||
string_gen(ast.get_children()[i].get_children()[0]);
|
||||
calculation_gen(ast.get_children()[i].get_children()[1]);
|
||||
op.op=op_hashapp;
|
||||
op.index=0;
|
||||
std::string str=ast.get_children()[i].get_children()[0].get_str();
|
||||
regist_string(str);
|
||||
op.index=string_table[str];
|
||||
exec_code.push_back(op);
|
||||
}
|
||||
return;
|
||||
|
@ -1230,6 +1231,7 @@ void nasal_codegen::print_op(int index)
|
|||
switch(exec_code[index].op)
|
||||
{
|
||||
case op_pushnum:std::cout<<'('<<number_result_table[exec_code[index].index]<<')';break;
|
||||
case op_hashapp:
|
||||
case op_call:
|
||||
case op_builtincall:
|
||||
case op_mcall:
|
||||
|
|
46
nasal_gc.h
46
nasal_gc.h
|
@ -51,6 +51,7 @@ public:
|
|||
void add_elem(std::string,int);
|
||||
void del_elem(std::string);
|
||||
int size();
|
||||
int get_special_para(std::string);
|
||||
int get_value_address(std::string);
|
||||
int get_mem_address(std::string);
|
||||
bool check_contain(std::string);
|
||||
|
@ -67,13 +68,18 @@ private:
|
|||
int closure_addr;
|
||||
nasal_ast argument_list;
|
||||
nasal_ast function_expr;
|
||||
std::map<std::string,int> para;
|
||||
std::vector<std::string> para_name;
|
||||
std::string dynamic_para_name;
|
||||
std::vector<int> default_para_addr;
|
||||
public:
|
||||
nasal_function(nasal_virtual_machine&);
|
||||
~nasal_function();
|
||||
void set_entry(int);
|
||||
int get_entry();
|
||||
void add_para(std::string,int,bool);
|
||||
std::vector<std::string>& get_para();
|
||||
std::string get_dynamic_para();
|
||||
std::vector<int>& get_default();
|
||||
void set_closure_addr(int);
|
||||
int get_closure_addr();
|
||||
void set_arguments(nasal_ast&);
|
||||
|
@ -272,6 +278,12 @@ int nasal_hash::size()
|
|||
{
|
||||
return elems.size();
|
||||
}
|
||||
int nasal_hash::get_special_para(std::string key)
|
||||
{
|
||||
if(elems.find(key)!=elems.end())
|
||||
return vm.mem_get(elems[key]);
|
||||
return -1;
|
||||
}
|
||||
int nasal_hash::get_value_address(std::string key)
|
||||
{
|
||||
int ret_value_addr=-1;
|
||||
|
@ -388,6 +400,7 @@ void nasal_hash::print()
|
|||
nasal_function::nasal_function(nasal_virtual_machine& nvm):vm(nvm)
|
||||
{
|
||||
closure_addr=-1;
|
||||
dynamic_para_name="";
|
||||
argument_list.clear();
|
||||
function_expr.clear();
|
||||
return;
|
||||
|
@ -396,10 +409,9 @@ nasal_function::~nasal_function()
|
|||
{
|
||||
if(closure_addr>=0)
|
||||
vm.del_reference(closure_addr);
|
||||
for(std::map<std::string,int>::iterator i=para.begin();i!=para.end();++i)
|
||||
if(i->second>=0)
|
||||
vm.del_reference(i->second);
|
||||
para.clear();
|
||||
for(int i=0;i<default_para_addr.size();++i)
|
||||
if(default_para_addr[i]>=0)
|
||||
vm.del_reference(default_para_addr[i]);
|
||||
argument_list.clear();
|
||||
function_expr.clear();
|
||||
return;
|
||||
|
@ -413,15 +425,29 @@ int nasal_function::get_entry()
|
|||
{
|
||||
return entry;
|
||||
}
|
||||
void nasal_function::add_para(std::string key,int init_value_addr,bool is_dynamic=false)
|
||||
void nasal_function::add_para(std::string name,int val_addr=-1,bool is_dynamic=false)
|
||||
{
|
||||
if(para.find(key)!=para.end())
|
||||
vm.del_reference(para[key]);
|
||||
para[key]=init_value_addr;
|
||||
if(is_dynamic)
|
||||
para[key]=vm.gc_alloc(vm_vector);
|
||||
{
|
||||
dynamic_para_name=name;
|
||||
return;
|
||||
}
|
||||
para_name.push_back(name);
|
||||
default_para_addr.push_back(val_addr);
|
||||
return;
|
||||
}
|
||||
std::vector<std::string>& nasal_function::get_para()
|
||||
{
|
||||
return para_name;
|
||||
}
|
||||
std::string nasal_function::get_dynamic_para()
|
||||
{
|
||||
return dynamic_para_name;
|
||||
}
|
||||
std::vector<int>& nasal_function::get_default()
|
||||
{
|
||||
return default_para_addr;
|
||||
}
|
||||
void nasal_function::set_closure_addr(int value_address)
|
||||
{
|
||||
if(closure_addr>=0)
|
||||
|
|
|
@ -53,7 +53,7 @@ private:
|
|||
int call_scalar(nasal_ast&,int);
|
||||
int call_vector(nasal_ast&,int,int);
|
||||
int call_hash(nasal_ast&,int,int);
|
||||
int call_function(nasal_ast&,std::string,int,int,int);
|
||||
int call_function(nasal_ast&,int,int,int);
|
||||
int call_builtin_function(std::string,int);
|
||||
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
|
||||
int call_scalar_mem(nasal_ast&,int);
|
||||
|
@ -505,7 +505,7 @@ int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr)
|
|||
val_name=call_expr.get_str();
|
||||
break;
|
||||
case ast_call_func:
|
||||
tmp_value_addr=call_function(call_expr,val_name,value_address,last_call_hash_addr,local_scope_addr);
|
||||
tmp_value_addr=call_function(call_expr,value_address,last_call_hash_addr,local_scope_addr);
|
||||
last_call_hash_addr=-1;
|
||||
val_name="";
|
||||
break;
|
||||
|
@ -734,7 +734,7 @@ int nasal_runtime::call_hash(nasal_ast& node,int base_value_addr,int local_scope
|
|||
nasal_vm.add_reference(ret_value_addr);
|
||||
return ret_value_addr;
|
||||
}
|
||||
int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_value_addr,int last_call_hash_addr,int local_scope_addr)
|
||||
int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_call_hash_addr,int local_scope_addr)
|
||||
{
|
||||
int ret_value_addr=-1;
|
||||
int value_type=nasal_vm.gc_get(base_value_addr).get_type();
|
||||
|
@ -753,12 +753,6 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_
|
|||
nasal_vm.add_reference(last_call_hash_addr);
|
||||
run_closure.add_new_value("me",last_call_hash_addr);
|
||||
}
|
||||
else if(func_name.length())
|
||||
{
|
||||
// when hash.me does not exist,set self
|
||||
nasal_vm.add_reference(base_value_addr);
|
||||
run_closure.add_new_value(func_name,base_value_addr);
|
||||
}
|
||||
nasal_ast& argument_format=reference_of_func.get_arguments();
|
||||
if(!node.get_children().size())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue