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
{
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);

View File

@ -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;

View File

@ -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]);

View File

@ -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