prepare for version 8.0
This commit is contained in:
parent
13d40e886e
commit
d71b4f09e2
|
@ -168,10 +168,10 @@ struct
|
|||
|
||||
struct opcode
|
||||
{
|
||||
uint16_t op;
|
||||
uint16_t fidx;
|
||||
uint32_t num;
|
||||
uint32_t line;
|
||||
uint16_t op; // opcode
|
||||
uint16_t fidx;// source code file index
|
||||
uint32_t num; // imm num
|
||||
uint32_t line;// line of source code
|
||||
opcode(uint8_t _op=op_nop,uint16_t _fidx=0,uint32_t _num=0,uint32_t _line=0)
|
||||
{
|
||||
op=_op;
|
||||
|
@ -448,6 +448,15 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
|
|||
gen(op_dynpara,string_table[str],tmp.get_line());
|
||||
}
|
||||
}
|
||||
// default dynamic parameter name is arg.
|
||||
// if there are too many arguments,unused arguments will be collected to a nasal_vec
|
||||
// if(!ast.get_children().size() || ast.get_children().back().get_type()!=ast_dynamic_id)
|
||||
// {
|
||||
// const std::string str="arg";
|
||||
// regist_string(str);
|
||||
// add_sym(str);
|
||||
// gen(op_dynpara,string_table[str],ast.get_line());
|
||||
// }
|
||||
exec_code[newfunc_label].num=exec_code.size()+1;
|
||||
int jmp_ptr=exec_code.size();
|
||||
gen(op_jmp,0,0);
|
||||
|
|
33
nasal_gc.h
33
nasal_gc.h
|
@ -9,6 +9,7 @@ enum nasal_type
|
|||
vm_func,
|
||||
vm_vec,
|
||||
vm_hash,
|
||||
vm_obj,
|
||||
vm_type_size
|
||||
};
|
||||
|
||||
|
@ -18,10 +19,11 @@ const int increment[vm_type_size]=
|
|||
{
|
||||
0, // vm_nil,in fact it is not in use
|
||||
65536,// vm_num
|
||||
512, // vm_str
|
||||
64, // vm_func
|
||||
2048, // vm_vec
|
||||
512 // vm_hash
|
||||
2048, // vm_str
|
||||
512, // vm_func
|
||||
8192, // vm_vec
|
||||
512, // vm_hash
|
||||
0 // vm_obj
|
||||
};
|
||||
|
||||
// declaration of nasal_val
|
||||
|
@ -29,11 +31,23 @@ struct nasal_val;
|
|||
// define nasal_ref => nasal_val*
|
||||
typedef nasal_val* nasal_ref;
|
||||
|
||||
#ifdef __NASAL_REF__
|
||||
struct nasal_ref
|
||||
{
|
||||
uint8_t type;
|
||||
union
|
||||
{
|
||||
double num;
|
||||
nasal_val* gcobj;
|
||||
}value;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct nasal_vec// 24 bytes
|
||||
{
|
||||
std::vector<nasal_ref> elems;
|
||||
|
||||
void print();
|
||||
void print();
|
||||
nasal_ref get_val(int);
|
||||
nasal_ref* get_mem(int);
|
||||
};
|
||||
|
@ -42,7 +56,7 @@ struct nasal_hash// 56 bytes
|
|||
{
|
||||
std::unordered_map<std::string,nasal_ref> elems;
|
||||
|
||||
void print();
|
||||
void print();
|
||||
nasal_ref get_val(std::string&);
|
||||
nasal_ref* get_mem(std::string&);
|
||||
};
|
||||
|
@ -74,6 +88,7 @@ struct nasal_val// 16 bytes
|
|||
nasal_vec* vec;
|
||||
nasal_hash* hash;
|
||||
nasal_func* func;
|
||||
void* obj;
|
||||
}ptr;
|
||||
|
||||
nasal_val(int);
|
||||
|
@ -100,8 +115,7 @@ nasal_ref* nasal_vec::get_mem(int index)
|
|||
void nasal_vec::print()
|
||||
{
|
||||
static int depth=0;
|
||||
++depth;
|
||||
if(depth>1024)
|
||||
if(++depth>32)
|
||||
{
|
||||
std::cout<<"[..]";
|
||||
--depth;
|
||||
|
@ -173,8 +187,7 @@ nasal_ref* nasal_hash::get_mem(std::string& key)
|
|||
void nasal_hash::print()
|
||||
{
|
||||
static int depth=0;
|
||||
++depth;
|
||||
if(depth>1024)
|
||||
if(++depth>32)
|
||||
{
|
||||
std::cout<<"{..}";
|
||||
--depth;
|
||||
|
|
|
@ -869,8 +869,12 @@ inline void nasal_vm::opr_ret()
|
|||
uint32_t offset=func->offset;
|
||||
nasal_ref cls=cls_stk.top();cls_stk.pop();
|
||||
// same closure detected,update the last local scope instead of the closure
|
||||
// because when calling a function,local scope get a copy of the func's closure,not the reference
|
||||
if(!cls_stk.empty() && cls_stk.top()==cls)
|
||||
{
|
||||
// this condition in fact is that two called function are using the same closure
|
||||
// if this copy of closure is changed, the closure will be updated at the same time
|
||||
// also the copy of closure that still in using will alse be updated
|
||||
auto& vec=gc.local.back()->ptr.vec->elems;
|
||||
auto& func_vec=func->closure->ptr.vec->elems;
|
||||
gc.local.pop_back();
|
||||
|
@ -879,6 +883,7 @@ inline void nasal_vm::opr_ret()
|
|||
}
|
||||
else
|
||||
{
|
||||
// two closures are not the same, update the func's closure and drop gc.local.back()
|
||||
auto& vec=func->closure->ptr.vec->elems;
|
||||
for(uint32_t i=0;i<offset;++i)
|
||||
vec[i]=gc.local.back()->ptr.vec->elems[i];
|
||||
|
@ -894,7 +899,7 @@ inline void nasal_vm::opr_ret()
|
|||
void nasal_vm::run(std::vector<opcode>& exec,bool op_cnt)
|
||||
{
|
||||
uint64_t count[op_ret+1]={0};
|
||||
void* opr_table[]=
|
||||
const void* opr_table[]=
|
||||
{
|
||||
&&nop, &&intg, &&intl, &&offset,
|
||||
&&loadg, &&loadl, &&pnum, &&pone,
|
||||
|
@ -918,7 +923,7 @@ void nasal_vm::run(std::vector<opcode>& exec,bool op_cnt)
|
|||
};
|
||||
|
||||
bytecode=exec;
|
||||
std::vector<void*> code;
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:exec)
|
||||
{
|
||||
code.push_back(opr_table[i.op]);
|
||||
|
|
|
@ -21,4 +21,48 @@ println(s.get_age(),' ',s.get_name());
|
|||
s.set_age(20);
|
||||
s.set_name('Sidi Liang');
|
||||
s.print_info();
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
println(s.get_age(),' ',s.get_name());
|
||||
# flightgear nasal-console cannot use this kind of object initializing
|
||||
var m=func(){
|
||||
var (_1,_2)=(0,1);
|
||||
return {
|
||||
a:func(){
|
||||
print(_1,' ',_2,'\n');
|
||||
},
|
||||
b:func(x){
|
||||
_1=x;
|
||||
},
|
||||
c:func(x){
|
||||
_2=x;
|
||||
},
|
||||
d:func(x){
|
||||
return func{
|
||||
print(_1,' ',_2,' ',x,'\n');
|
||||
};
|
||||
},
|
||||
g:func(x){
|
||||
var y=x;
|
||||
return func{
|
||||
print(_1,' ',_2,' ',x,' ',y,'\n');
|
||||
}
|
||||
},
|
||||
h:func(){
|
||||
return func(x){
|
||||
_1=x;
|
||||
}
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
m.a(); # 0 1
|
||||
m.b(2048);
|
||||
m.c(1024);
|
||||
var a=m.d(-1);
|
||||
var b=m.g(1);
|
||||
a(); # 2048 1024 -1
|
||||
b(); # 2048 1024 1 1
|
||||
|
||||
m.h()(2147483647);
|
||||
m.a();
|
||||
# flightgear-nasal-console: 2147483647 1024
|
||||
# nasal-interpreter 2048 1024
|
Loading…
Reference in New Issue