update
This commit is contained in:
parent
00c6e3b4fd
commit
ae0dae5956
21
nasal_gc.h
21
nasal_gc.h
|
@ -60,8 +60,8 @@ struct nasal_func// 120 bytes
|
|||
struct nasal_val// 16 bytes
|
||||
{
|
||||
#define GC_UNCOLLECTED 0
|
||||
#define GC_FOUND 1
|
||||
#define GC_COLLECTED 2
|
||||
#define GC_COLLECTED 1
|
||||
#define GC_FOUND 2
|
||||
uint8_t mark;
|
||||
uint16_t type;
|
||||
union
|
||||
|
@ -84,23 +84,15 @@ nasal_val* nasal_vec::get_val(int index)
|
|||
{
|
||||
int vec_size=elems.size();
|
||||
if(index<-vec_size || index>=vec_size)
|
||||
{
|
||||
std::cout<<">> [gc] nasal_vec::get_val: index out of range: "<<index<<"\n";
|
||||
return nullptr;
|
||||
}
|
||||
int idx[2]={index+vec_size,index};
|
||||
return elems[idx[index>=0]];
|
||||
return elems[index>=0?index:index+vec_size];
|
||||
}
|
||||
nasal_val** nasal_vec::get_mem(int index)
|
||||
{
|
||||
int vec_size=elems.size();
|
||||
if(index<-vec_size || index>=vec_size)
|
||||
{
|
||||
std::cout<<">> [gc] nasal_vec::get_mem: index out of range: "<<index<<"\n";
|
||||
return nullptr;
|
||||
}
|
||||
int idx[2]={index+vec_size,index};
|
||||
return &elems[idx[index>=0]];
|
||||
return &elems[index>=0?index:index+vec_size];
|
||||
}
|
||||
void nasal_vec::print()
|
||||
{
|
||||
|
@ -280,7 +272,7 @@ void nasal_gc::mark()
|
|||
{
|
||||
nasal_val* tmp=bfs.front();
|
||||
bfs.pop();
|
||||
if(!tmp || tmp->mark) continue;
|
||||
if(tmp->mark) continue;
|
||||
tmp->mark=GC_FOUND;
|
||||
if(tmp->type==vm_vec)
|
||||
for(auto i:tmp->ptr.vec->elems)
|
||||
|
@ -293,7 +285,8 @@ void nasal_gc::mark()
|
|||
for(auto i:tmp->ptr.func->closure)
|
||||
bfs.push(i);
|
||||
for(auto i:tmp->ptr.func->default_para)
|
||||
bfs.push(i);
|
||||
if(i)
|
||||
bfs.push(i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -265,17 +265,17 @@ void nasal_parse::check_memory_reachable(nasal_ast& node)
|
|||
if(node.get_type()==ast_call)
|
||||
{
|
||||
if(node.get_children()[0].get_type()!=ast_id)
|
||||
die(node.get_line(),"cannot get the memory of a temporary data");
|
||||
die(node.get_line(),"cannot get memory of temp data");
|
||||
for(auto& tmp:node.get_children())
|
||||
{
|
||||
if(tmp.get_type()==ast_callf)
|
||||
die(tmp.get_line(),"cannot get the memory of function-returned value");
|
||||
die(tmp.get_line(),"cannot get memory of func-returned value");
|
||||
if(tmp.get_type()==ast_callv && (tmp.get_children().size()>1 || tmp.get_children()[0].get_type()==ast_subvec))
|
||||
die(tmp.get_line(),"cannot get the memory in temporary sliced vector");
|
||||
}
|
||||
die(tmp.get_line(),"cannot get memory of temp sliced vector");
|
||||
}
|
||||
}
|
||||
else if(node.get_type()!=ast_id)
|
||||
die(node.get_line(),"cannot use calculation as the memory of scalar");
|
||||
die(node.get_line(),"cannot get memory of temp data");
|
||||
return;
|
||||
}
|
||||
nasal_ast nasal_parse::null_node_gen()
|
||||
|
@ -458,7 +458,7 @@ nasal_ast nasal_parse::expr()
|
|||
if(tok_type==tok_ret && !in_function)
|
||||
die(error_line,"use return in the function");
|
||||
switch(tok_type)
|
||||
{
|
||||
{
|
||||
case tok_nil:
|
||||
case tok_num:
|
||||
case tok_str:
|
||||
|
|
105
nasal_vm.h
105
nasal_vm.h
|
@ -5,16 +5,16 @@ class nasal_vm
|
|||
{
|
||||
private:
|
||||
/* reference from nasal_gc */
|
||||
nasal_val**& stack_top; // stack top
|
||||
nasal_val**& stack_top; // stack top
|
||||
/* values of nasal_vm */
|
||||
int pc; // program counter
|
||||
bool loop_mark; // when mark is false,break the main loop
|
||||
std::stack<int> ret; // ptr stack stores address for function to return
|
||||
std::stack<int> counter; // iterator stack for forindex/foreach
|
||||
std::vector<std::string> str_table; // symbols used in process
|
||||
std::vector<opcode> exec_code; // byte codes store here
|
||||
std::stack<nasal_val**> addr_stack; // stack for mem_call
|
||||
nasal_gc gc; // garbage collector
|
||||
int pc; // program counter
|
||||
bool loop_mark; // when mark is false,break the main loop
|
||||
std::stack<int> ret; // ptr stack stores address for function to return
|
||||
std::stack<int> counter; // iterator stack for forindex/foreach
|
||||
std::vector<std::string> str_table; // symbols used in process
|
||||
std::vector<opcode> exec_code; // byte codes store here
|
||||
std::stack<nasal_val**> addr_stack;// used for mem_call
|
||||
nasal_gc gc; // garbage collector
|
||||
|
||||
void die(std::string);
|
||||
bool condition(nasal_val*);
|
||||
|
@ -105,8 +105,6 @@ void nasal_vm::init(
|
|||
void nasal_vm::clear()
|
||||
{
|
||||
gc.gc_clear();
|
||||
while(!addr_stack.empty())
|
||||
addr_stack.pop();
|
||||
while(!ret.empty())
|
||||
ret.pop();
|
||||
while(!counter.empty())
|
||||
|
@ -123,16 +121,15 @@ void nasal_vm::die(std::string str)
|
|||
}
|
||||
bool nasal_vm::condition(nasal_val* val_addr)
|
||||
{
|
||||
int type=val_addr->type;
|
||||
if(type==vm_num)
|
||||
if(val_addr->type==vm_num)
|
||||
return val_addr->ptr.num;
|
||||
else if(type==vm_str)
|
||||
else if(val_addr->type==vm_str)
|
||||
{
|
||||
std::string& str=*val_addr->ptr.str;
|
||||
double number=str2num(str.c_str());
|
||||
if(std::isnan(number))
|
||||
double num=str2num(str.c_str());
|
||||
if(std::isnan(num))
|
||||
return str.empty();
|
||||
return number;
|
||||
return num;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -257,11 +254,11 @@ void nasal_vm::opr_unot()
|
|||
stack_top[0]=val->ptr.num?gc.zero_addr:gc.one_addr;
|
||||
else if(type==vm_str)
|
||||
{
|
||||
double number=str2num(val->ptr.str->c_str());
|
||||
if(std::isnan(number))
|
||||
double num=str2num(val->ptr.str->c_str());
|
||||
if(std::isnan(num))
|
||||
stack_top[0]=val->ptr.str->empty()?gc.one_addr:gc.zero_addr;
|
||||
else
|
||||
stack_top[0]=number?gc.zero_addr:gc.one_addr;
|
||||
stack_top[0]=num?gc.zero_addr:gc.one_addr;
|
||||
}
|
||||
else
|
||||
die("unot: incorrect value type");
|
||||
|
@ -311,8 +308,7 @@ void nasal_vm::opr_lnk()
|
|||
}
|
||||
void nasal_vm::opr_addeq()
|
||||
{
|
||||
nasal_val** mem_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
nasal_val** mem_addr=addr_stack.top();addr_stack.pop();
|
||||
nasal_val* new_val=gc.gc_alloc(vm_num);
|
||||
new_val->ptr.num=mem_addr[0]->to_number()+stack_top[0]->to_number();
|
||||
stack_top[0]=mem_addr[0]=new_val;
|
||||
|
@ -320,8 +316,7 @@ void nasal_vm::opr_addeq()
|
|||
}
|
||||
void nasal_vm::opr_subeq()
|
||||
{
|
||||
nasal_val** mem_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
nasal_val** mem_addr=addr_stack.top();addr_stack.pop();
|
||||
nasal_val* new_val=gc.gc_alloc(vm_num);
|
||||
new_val->ptr.num=mem_addr[0]->to_number()-stack_top[0]->to_number();
|
||||
stack_top[0]=mem_addr[0]=new_val;
|
||||
|
@ -329,8 +324,7 @@ void nasal_vm::opr_subeq()
|
|||
}
|
||||
void nasal_vm::opr_muleq()
|
||||
{
|
||||
nasal_val** mem_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
nasal_val** mem_addr=addr_stack.top();addr_stack.pop();
|
||||
nasal_val* new_val=gc.gc_alloc(vm_num);
|
||||
new_val->ptr.num=mem_addr[0]->to_number()*stack_top[0]->to_number();
|
||||
stack_top[0]=mem_addr[0]=new_val;
|
||||
|
@ -338,8 +332,7 @@ void nasal_vm::opr_muleq()
|
|||
}
|
||||
void nasal_vm::opr_diveq()
|
||||
{
|
||||
nasal_val** mem_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
nasal_val** mem_addr=addr_stack.top();addr_stack.pop();
|
||||
nasal_val* new_val=gc.gc_alloc(vm_num);
|
||||
new_val->ptr.num=mem_addr[0]->to_number()/stack_top[0]->to_number();
|
||||
stack_top[0]=mem_addr[0]=new_val;
|
||||
|
@ -347,8 +340,7 @@ void nasal_vm::opr_diveq()
|
|||
}
|
||||
void nasal_vm::opr_lnkeq()
|
||||
{
|
||||
nasal_val** mem_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
nasal_val** mem_addr=addr_stack.top();addr_stack.pop();
|
||||
nasal_val* new_val=gc.gc_alloc(vm_str);
|
||||
*new_val->ptr.str=mem_addr[0]->to_string()+stack_top[0]->to_string();
|
||||
stack_top[0]=mem_addr[0]=new_val;
|
||||
|
@ -502,14 +494,14 @@ void nasal_vm::opr_calll()
|
|||
}
|
||||
void nasal_vm::opr_callv()
|
||||
{
|
||||
nasal_val* val=*stack_top--;
|
||||
nasal_val* vec_addr=*stack_top;
|
||||
nasal_val* val=stack_top[0];
|
||||
nasal_val* vec_addr=(--stack_top)[0];
|
||||
int type=vec_addr->type;
|
||||
if(type==vm_vec)
|
||||
{
|
||||
nasal_val* res=vec_addr->ptr.vec->get_val(val->to_number());
|
||||
if(!res)
|
||||
die("callv: index out of range");
|
||||
die("callv: index out of range:"+val->to_string());
|
||||
stack_top[0]=res;
|
||||
}
|
||||
else if(type==vm_hash)
|
||||
|
@ -536,7 +528,7 @@ void nasal_vm::opr_callv()
|
|||
int str_size=str.length();
|
||||
if(num<-str_size || num>=str_size)
|
||||
{
|
||||
die("callv: index out of range");
|
||||
die("callv: index out of range:"+val->to_string());
|
||||
return;
|
||||
}
|
||||
nasal_val* res=gc.gc_alloc(vm_num);
|
||||
|
@ -558,7 +550,7 @@ void nasal_vm::opr_callvi()
|
|||
// cannot use operator[],because this may cause overflow
|
||||
nasal_val* res=val->ptr.vec->get_val(exec_code[pc].num);
|
||||
if(!res)
|
||||
die("callvi: index out of range");
|
||||
die("callvi: index out of range:"+num2str(exec_code[pc].num));
|
||||
(++stack_top)[0]=res;
|
||||
return;
|
||||
}
|
||||
|
@ -700,7 +692,7 @@ void nasal_vm::opr_slc()
|
|||
}
|
||||
nasal_val* res=stack_top[0]->ptr.vec->get_val(num);
|
||||
if(!res)
|
||||
die("slc: index out of range");
|
||||
die("slc: index out of range:"+num2str(num));
|
||||
gc.slice_stack.back()->ptr.vec->elems.push_back(res);
|
||||
return;
|
||||
}
|
||||
|
@ -756,10 +748,9 @@ void nasal_vm::opr_mcalll()
|
|||
}
|
||||
void nasal_vm::opr_mcallv()
|
||||
{
|
||||
nasal_val* val=*stack_top--;
|
||||
nasal_val** vec_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
int type=(*vec_addr)->type;
|
||||
nasal_val* val=*stack_top--;
|
||||
nasal_val* vec_addr=*addr_stack.top();
|
||||
int type=vec_addr->type;
|
||||
if(type==vm_vec)
|
||||
{
|
||||
int num;
|
||||
|
@ -769,10 +760,10 @@ void nasal_vm::opr_mcallv()
|
|||
case vm_str:num=(int)str2num(val->ptr.str->c_str());break;
|
||||
default:die("mcallv: error value type");break;
|
||||
}
|
||||
nasal_val** res=(*vec_addr)->ptr.vec->get_mem(num);
|
||||
if(!res)
|
||||
die("mcallv: index out of range");
|
||||
addr_stack.push(res);
|
||||
nasal_val** mem_addr=vec_addr->ptr.vec->get_mem(num);
|
||||
if(!mem_addr)
|
||||
die("mcallv: index out of range:"+num2str(num));
|
||||
addr_stack.top()=mem_addr;
|
||||
}
|
||||
else if(type==vm_hash)
|
||||
{
|
||||
|
@ -781,39 +772,37 @@ void nasal_vm::opr_mcallv()
|
|||
die("mcallv: must use string as the key");
|
||||
return;
|
||||
}
|
||||
nasal_hash& ref=*(*vec_addr)->ptr.hash;
|
||||
nasal_hash& ref=*vec_addr->ptr.hash;
|
||||
std::string& str=*val->ptr.str;
|
||||
nasal_val** res=ref.get_mem(str);
|
||||
if(!res)
|
||||
nasal_val** mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr)
|
||||
{
|
||||
ref.elems[str]=gc.nil_addr;
|
||||
res=ref.get_mem(str);
|
||||
mem_addr=ref.get_mem(str);
|
||||
}
|
||||
addr_stack.push(res);
|
||||
addr_stack.top()=mem_addr;
|
||||
}
|
||||
else
|
||||
die("mcallv: cannot get memory space in a string");
|
||||
die("mcallv: cannot get memory space in other types");
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_mcallh()
|
||||
{
|
||||
nasal_val** mem_addr=nullptr;
|
||||
nasal_val** hash_addr=addr_stack.top();
|
||||
addr_stack.pop();
|
||||
if((*hash_addr)->type!=vm_hash)
|
||||
nasal_val* hash_addr=*addr_stack.top();
|
||||
if(hash_addr->type!=vm_hash)
|
||||
{
|
||||
die("mcallh: must call a hash");
|
||||
return;
|
||||
}
|
||||
nasal_hash& ref=*(*hash_addr)->ptr.hash;
|
||||
nasal_hash& ref=*hash_addr->ptr.hash;
|
||||
std::string& str=str_table[exec_code[pc].num];
|
||||
mem_addr=ref.get_mem(str);
|
||||
nasal_val** mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr) // create a new key
|
||||
{
|
||||
ref.elems[str]=gc.nil_addr;
|
||||
mem_addr=ref.get_mem(str);
|
||||
}
|
||||
addr_stack.push(mem_addr);
|
||||
addr_stack.top()=mem_addr;
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_ret()
|
||||
|
@ -828,7 +817,7 @@ void nasal_vm::opr_ret()
|
|||
}
|
||||
void nasal_vm::run()
|
||||
{
|
||||
static void (nasal_vm::*opr_table[])()=
|
||||
void (nasal_vm::*opr_table[])()=
|
||||
{
|
||||
&nasal_vm::opr_nop,
|
||||
&nasal_vm::opr_intg,
|
||||
|
|
|
@ -1,30 +1,18 @@
|
|||
import("lib.nas");
|
||||
var filename=["main.cpp","nasal_ast.h","nasal_builtin.h","nasal_codegen.h","nasal_gc.h","nasal_import.h","nasal_lexer.h","nasal_parse.h","nasal_vm.h","nasal.h"];
|
||||
var space=[" "," ","",""," "," "," "," "," "," "];
|
||||
func(){
|
||||
var filename=[
|
||||
"main.cpp",
|
||||
"nasal_ast.h",
|
||||
"nasal_builtin.h",
|
||||
"nasal_codegen.h",
|
||||
"nasal_gc.h",
|
||||
"nasal_import.h",
|
||||
"nasal_lexer.h",
|
||||
"nasal_parse.h",
|
||||
"nasal_vm.h",
|
||||
"nasal.h"
|
||||
];
|
||||
var max_size=size('nasal_codegen.h');
|
||||
var (cnt,semi)=[0,0];
|
||||
foreach(var file;filename)
|
||||
var (bytes,cnt,semi)=(0,0,0);
|
||||
forindex(var i;filename)
|
||||
{
|
||||
var s=io.fin(file);
|
||||
var name=file;
|
||||
for(var i=size(name);i<max_size;i+=1)
|
||||
name~=' ';
|
||||
var s=io.fin(filename[i]);
|
||||
bytes+=size(s);
|
||||
var line_cnt=size(split('\n',s));
|
||||
var semi_cnt=size(split(';' ,s))-1;
|
||||
println(name,'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi');
|
||||
println(filename[i],space[i],'| ',line_cnt,' \tline | ',semi_cnt,' \tsemi');
|
||||
cnt +=line_cnt;
|
||||
semi+=semi_cnt;
|
||||
}
|
||||
println('total: | ',cnt,' \tline | ',semi,' \tsemi');
|
||||
println('bytes: | ',bytes,' bytes| ',int(bytes/1024),' \tkb');
|
||||
}();
|
Loading…
Reference in New Issue