prepare for version 8.0

This commit is contained in:
ValKmjolnir 2021-10-08 15:32:18 +08:00
parent 13d40e886e
commit d71b4f09e2
4 changed files with 88 additions and 17 deletions

View File

@ -168,10 +168,10 @@ struct
struct opcode struct opcode
{ {
uint16_t op; uint16_t op; // opcode
uint16_t fidx; uint16_t fidx;// source code file index
uint32_t num; uint32_t num; // imm num
uint32_t line; 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) opcode(uint8_t _op=op_nop,uint16_t _fidx=0,uint32_t _num=0,uint32_t _line=0)
{ {
op=_op; op=_op;
@ -448,6 +448,15 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
gen(op_dynpara,string_table[str],tmp.get_line()); 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; exec_code[newfunc_label].num=exec_code.size()+1;
int jmp_ptr=exec_code.size(); int jmp_ptr=exec_code.size();
gen(op_jmp,0,0); gen(op_jmp,0,0);

View File

@ -9,6 +9,7 @@ enum nasal_type
vm_func, vm_func,
vm_vec, vm_vec,
vm_hash, vm_hash,
vm_obj,
vm_type_size vm_type_size
}; };
@ -18,10 +19,11 @@ const int increment[vm_type_size]=
{ {
0, // vm_nil,in fact it is not in use 0, // vm_nil,in fact it is not in use
65536,// vm_num 65536,// vm_num
512, // vm_str 2048, // vm_str
64, // vm_func 512, // vm_func
2048, // vm_vec 8192, // vm_vec
512 // vm_hash 512, // vm_hash
0 // vm_obj
}; };
// declaration of nasal_val // declaration of nasal_val
@ -29,6 +31,18 @@ struct nasal_val;
// define nasal_ref => nasal_val* // define nasal_ref => nasal_val*
typedef nasal_val* nasal_ref; 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 struct nasal_vec// 24 bytes
{ {
std::vector<nasal_ref> elems; std::vector<nasal_ref> elems;
@ -74,6 +88,7 @@ struct nasal_val// 16 bytes
nasal_vec* vec; nasal_vec* vec;
nasal_hash* hash; nasal_hash* hash;
nasal_func* func; nasal_func* func;
void* obj;
}ptr; }ptr;
nasal_val(int); nasal_val(int);
@ -100,8 +115,7 @@ nasal_ref* nasal_vec::get_mem(int index)
void nasal_vec::print() void nasal_vec::print()
{ {
static int depth=0; static int depth=0;
++depth; if(++depth>32)
if(depth>1024)
{ {
std::cout<<"[..]"; std::cout<<"[..]";
--depth; --depth;
@ -173,8 +187,7 @@ nasal_ref* nasal_hash::get_mem(std::string& key)
void nasal_hash::print() void nasal_hash::print()
{ {
static int depth=0; static int depth=0;
++depth; if(++depth>32)
if(depth>1024)
{ {
std::cout<<"{..}"; std::cout<<"{..}";
--depth; --depth;

View File

@ -869,8 +869,12 @@ inline void nasal_vm::opr_ret()
uint32_t offset=func->offset; uint32_t offset=func->offset;
nasal_ref cls=cls_stk.top();cls_stk.pop(); nasal_ref cls=cls_stk.top();cls_stk.pop();
// same closure detected,update the last local scope instead of the closure // 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) 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& vec=gc.local.back()->ptr.vec->elems;
auto& func_vec=func->closure->ptr.vec->elems; auto& func_vec=func->closure->ptr.vec->elems;
gc.local.pop_back(); gc.local.pop_back();
@ -879,6 +883,7 @@ inline void nasal_vm::opr_ret()
} }
else else
{ {
// two closures are not the same, update the func's closure and drop gc.local.back()
auto& vec=func->closure->ptr.vec->elems; auto& vec=func->closure->ptr.vec->elems;
for(uint32_t i=0;i<offset;++i) for(uint32_t i=0;i<offset;++i)
vec[i]=gc.local.back()->ptr.vec->elems[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) void nasal_vm::run(std::vector<opcode>& exec,bool op_cnt)
{ {
uint64_t count[op_ret+1]={0}; uint64_t count[op_ret+1]={0};
void* opr_table[]= const void* opr_table[]=
{ {
&&nop, &&intg, &&intl, &&offset, &&nop, &&intg, &&intl, &&offset,
&&loadg, &&loadl, &&pnum, &&pone, &&loadg, &&loadl, &&pnum, &&pone,
@ -918,7 +923,7 @@ void nasal_vm::run(std::vector<opcode>& exec,bool op_cnt)
}; };
bytecode=exec; bytecode=exec;
std::vector<void*> code; std::vector<const void*> code;
for(auto& i:exec) for(auto& i:exec)
{ {
code.push_back(opr_table[i.op]); code.push_back(opr_table[i.op]);

View File

@ -22,3 +22,47 @@ s.set_age(20);
s.set_name('Sidi Liang'); s.set_name('Sidi Liang');
s.print_info(); 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