optimize codes

This commit is contained in:
ValKmjolnir 2022-07-19 23:55:12 +08:00
parent cfbec9a3f1
commit cc4ff38f28
8 changed files with 100 additions and 103 deletions

View File

@ -637,14 +637,14 @@ nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
for(auto& i:vec.vec().elems)
switch(i.type)
{
case vm_none: std::cout<<"undefined"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(...){...}"; break;
case vm_obj: std::cout<<"<object>"; break;
case vm_none: std::cout<<"undefined"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(..){..}";break;
case vm_obj: std::cout<<"<object>"; break;
}
std::cout<<std::flush;
// generate return value,

View File

@ -603,14 +603,14 @@ nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
for(auto& i:vec.vec().elems)
switch(i.type)
{
case vm_none: std::cout<<"undefined"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(...){...}"; break;
case vm_obj: std::cout<<"<object>"; break;
case vm_none: std::cout<<"undefined"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(..){..}";break;
case vm_obj: std::cout<<"<object>"; break;
}
std::cout<<std::flush;
// 最后一定要记得生成返回值,返回值必须是一个内置的类型,

View File

@ -7,7 +7,7 @@ SRC=\
nasal_builtin.h\
nasal_opt.h\
nasal_codegen.h\
nasal_gc.h\
nasal_gc.h\
nasal_import.h\
nasal_lexer.h\
nasal_parse.h\

View File

@ -102,7 +102,7 @@ native(builtin_logtime);
nasal_ref builtin_err(const std::string& errfunc,const std::string& info)
{
std::cerr<<"[vm] "<<errfunc<<": "<<info<<".\n";
std::cerr<<"[vm] "<<errfunc<<": "<<info<<"\n";
return {vm_none};
}
@ -213,15 +213,15 @@ inline void print_core(std::vector<nasal_ref>& elems)
for(auto& i:elems)
switch(i.type)
{
case vm_none: std::cout<<"null"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(...){...}"; break;
case vm_obj: std::cout<<"<object>"; break;
case vm_co: std::cout<<"<coroutine>"; break;
case vm_none: std::cout<<"null"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<i.str(); break;
case vm_vec: i.vec().print(); break;
case vm_hash: i.hash().print(); break;
case vm_func: std::cout<<"func(..){..}";break;
case vm_obj: std::cout<<"<object>"; break;
case vm_co: std::cout<<"<coroutine>"; break;
}
}
nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
@ -290,15 +290,14 @@ nasal_ref builtin_fin(nasal_ref* local,nasal_gc& gc)
nasal_ref val=local[1];
if(val.type!=vm_str)
return builtin_err("io.fin","\"filename\" must be string");
std::string& filename=val.str();
std::ifstream fin(filename);
std::ifstream fin(val.str());
if(!fin.fail())
{
std::stringstream rd;
rd<<fin.rdbuf();
return gc.newstr(rd.str());
}
return builtin_err("io.fin","cannot open \""+filename+"\"");
return builtin_err("io.fin","cannot open <"+val.str()+">");
}
nasal_ref builtin_fout(nasal_ref* local,nasal_gc& gc)
{
@ -310,7 +309,7 @@ nasal_ref builtin_fout(nasal_ref* local,nasal_gc& gc)
return builtin_err("io.fout","\"str\" must be string");
std::ofstream fout(val.str());
if(fout.fail())
return builtin_err("io.fout","cannot open \""+val.str()+"\"");
return builtin_err("io.fout","cannot open <"+val.str()+">");
fout<<str.str();
return nil;
}
@ -370,7 +369,7 @@ nasal_ref builtin_id(nasal_ref* local,nasal_gc& gc)
nasal_ref val=local[1];
std::stringstream ss;
if(val.type>vm_num)
ss<<"0x"<<std::hex<<(uint64_t)val.value.gcobj<<std::dec;
ss<<"0x"<<std::hex<<(uint64_t)val.val.gcobj<<std::dec;
else
ss<<"0";
return gc.newstr(ss.str());
@ -754,7 +753,7 @@ nasal_ref builtin_values(nasal_ref* local,nasal_gc& gc)
v.push_back(i.second);
return vec;
}
void obj_file_destructor(void* ptr)
void obj_file_dtor(void* ptr)
{
fclose((FILE*)ptr);
}
@ -770,9 +769,7 @@ nasal_ref builtin_open(nasal_ref* local,nasal_gc& gc)
if(!res)
return builtin_err("open","failed to open file <"+name.str()+">");
nasal_ref ret=gc.alloc(vm_obj);
ret.obj().type=nasal_obj::file;
ret.obj().ptr=(void*)res;
ret.obj().destructor=obj_file_destructor;
ret.obj().set(nasal_obj::file,res,obj_file_dtor);
return ret;
}
nasal_ref builtin_close(nasal_ref* local,nasal_gc& gc)
@ -793,7 +790,7 @@ nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
return builtin_err("read","not a valid filehandle");
if(buf.type!=vm_str)
return builtin_err("read","\"buf\" must be string");
if(buf.value.gcobj->unmut)
if(buf.val.gcobj->unmut)
return builtin_err("read","\"buf\" is not a mutable string");
if(len.type!=vm_num)
return builtin_err("read","\"len\" must be number");
@ -889,8 +886,7 @@ nasal_ref builtin_eof(nasal_ref* local,nasal_gc& gc)
nasal_ref fd=local[1];
if(!fd.objchk(nasal_obj::file))
return builtin_err("readln","not a valid filehandle");
double res=feof((FILE*)fd.obj().ptr);
return {vm_num,res};
return {vm_num,(double)feof((FILE*)fd.obj().ptr)};
}
nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
{
@ -900,7 +896,7 @@ nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
nasal_ref str=local[1];
nasal_ref startbit=local[2];
nasal_ref length=local[3];
if(str.type!=vm_str || str.value.gcobj->unmut)
if(str.type!=vm_str || str.val.gcobj->unmut)
return builtin_err("fld","\"str\" must be mutable string");
if(startbit.type!=vm_num || length.type!=vm_num)
return builtin_err("fld","\"startbit\",\"len\" must be number");
@ -924,7 +920,7 @@ nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
nasal_ref str=local[1];
nasal_ref startbit=local[2];
nasal_ref length=local[3];
if(str.type!=vm_str || str.value.gcobj->unmut)
if(str.type!=vm_str || str.val.gcobj->unmut)
return builtin_err("sfld","\"str\" must be mutable string");
if(startbit.type!=vm_num || length.type!=vm_num)
return builtin_err("sfld","\"startbit\",\"len\" must be number");
@ -951,7 +947,7 @@ nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
nasal_ref startbit=local[2];
nasal_ref length=local[3];
nasal_ref value=local[4];
if(str.type!=vm_str || str.value.gcobj->unmut)
if(str.type!=vm_str || str.val.gcobj->unmut)
return builtin_err("setfld","\"str\" must be mutable string");
if(startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num)
return builtin_err("setfld","\"startbit\",\"len\",\"val\" must be number");
@ -974,7 +970,7 @@ nasal_ref builtin_buf(nasal_ref* local,nasal_gc& gc)
{
nasal_ref length=local[1];
if(length.type!=vm_num || length.num()<=0)
return builtin_err("buf","\"len\" must be a number greater than 9");
return builtin_err("buf","\"len\" must be a number greater than 0");
nasal_ref str=gc.alloc(vm_str);
auto& s=str.str();
s.resize(length.num(),'\0');
@ -999,7 +995,7 @@ nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
res.vec().elems.push_back({vm_num,(double)fd[1]});
return res;
#endif
return builtin_err("pipe","not supported for windows platform");
return builtin_err("pipe","not supported for windows");
}
nasal_ref builtin_fork(nasal_ref* local,nasal_gc& gc)
{
@ -1009,7 +1005,7 @@ nasal_ref builtin_fork(nasal_ref* local,nasal_gc& gc)
return builtin_err("fork","failed to fork a process");
return {vm_num,(double)res};
#endif
return builtin_err("fork","not supported for windows platform");
return builtin_err("fork","not supported for windows");
}
nasal_ref builtin_waitpid(nasal_ref* local,nasal_gc& gc)
{
@ -1026,9 +1022,9 @@ nasal_ref builtin_waitpid(nasal_ref* local,nasal_gc& gc)
vec.vec().elems.push_back({vm_num,(double)status});
return vec;
#endif
return builtin_err("waitpid","not supported for windows platform");
return builtin_err("waitpid","not supported for windows");
}
void obj_dir_destructor(void* ptr)
void obj_dir_dtor(void* ptr)
{
#ifndef _MSC_VER
closedir((DIR*)ptr);
@ -1053,9 +1049,7 @@ nasal_ref builtin_opendir(nasal_ref* local,nasal_gc& gc)
return builtin_err("opendir","cannot open dir <"+path.str()+">");
#endif
nasal_ref ret=gc.alloc(vm_obj);
ret.obj().type=nasal_obj::dir;
ret.obj().ptr=(void*)p;
ret.obj().destructor=obj_dir_destructor;
ret.obj().set(nasal_obj::dir,p,obj_dir_dtor);
return ret;
}
nasal_ref builtin_readdir(nasal_ref* local,nasal_gc& gc)
@ -1127,7 +1121,7 @@ nasal_ref builtin_getenv(nasal_ref* local,nasal_gc& gc)
return nil;
return gc.newstr(res);
}
void obj_dylib_destructor(void* ptr)
void obj_dylib_dtor(void* ptr)
{
#ifdef _WIN32
FreeLibrary((HMODULE)ptr);
@ -1152,29 +1146,26 @@ nasal_ref builtin_dlopen(nasal_ref* local,nasal_gc& gc)
if(!ptr)
return builtin_err("dlopen","cannot open dynamic lib <"+dlname.str()+">");
nasal_ref ret=gc.alloc(vm_obj);
ret.obj().type=nasal_obj::dylib;
ret.obj().ptr=ptr;
ret.obj().destructor=obj_dylib_destructor;
ret.obj().set(nasal_obj::dylib,ptr,obj_dylib_dtor);
return ret;
}
nasal_ref builtin_dlsym(nasal_ref* local,nasal_gc& gc)
{
nasal_ref libptr=local[1];
nasal_ref lib=local[1];
nasal_ref sym=local[2];
if(!libptr.objchk(nasal_obj::dylib))
if(!lib.objchk(nasal_obj::dylib))
return builtin_err("dlsym","\"lib\" is not a valid dynamic lib");
if(sym.type!=vm_str)
return builtin_err("dlsym","\"sym\" must be string");
#ifdef _WIN32
void* func=(void*)GetProcAddress((HMODULE)libptr.obj().ptr,sym.str().c_str());
void* func=(void*)GetProcAddress((HMODULE)lib.obj().ptr,sym.str().c_str());
#else
void* func=dlsym(libptr.obj().ptr,sym.str().c_str());
void* func=dlsym(lib.obj().ptr,sym.str().c_str());
#endif
if(!func)
return builtin_err("dlsym","cannot find symbol \""+sym.str()+"\"");
nasal_ref ret=gc.alloc(vm_obj);
ret.obj().type=nasal_obj::faddr;
ret.obj().ptr=func;
ret.obj().set(nasal_obj::faddr,func);
return ret;
}
nasal_ref builtin_dlclose(nasal_ref* local,nasal_gc& gc)

View File

@ -61,29 +61,29 @@ struct nasal_ref
double num;
nasal_ref* addr;
nasal_val* gcobj;
} value;
} val;
// vm_none/vm_nil
nasal_ref(const uint8_t t=vm_none):type(t){}
// vm_ret
nasal_ref(const uint8_t t,const uint32_t n):type(t){value.ret=n;}
nasal_ref(const uint8_t t,const uint32_t n):type(t){val.ret=n;}
// vm_cnt
nasal_ref(const uint8_t t,const int64_t n):type(t){value.cnt=n;}
nasal_ref(const uint8_t t,const int64_t n):type(t){val.cnt=n;}
// vm_num
nasal_ref(const uint8_t t,const double n):type(t){value.num=n;}
nasal_ref(const uint8_t t,const double n):type(t){val.num=n;}
// vm_str/vm_func/vm_vec/vm_hash/vm_upval/vm_obj
nasal_ref(const uint8_t t,nasal_val* n):type(t){value.gcobj=n;}
nasal_ref(const uint8_t t,nasal_val* n):type(t){val.gcobj=n;}
// vm_addr
nasal_ref(const uint8_t t,nasal_ref* n):type(t){value.addr=n;}
nasal_ref(const nasal_ref& nr):type(nr.type),value(nr.value){}
nasal_ref(const uint8_t t,nasal_ref* n):type(t){val.addr=n;}
nasal_ref(const nasal_ref& nr):type(nr.type),val(nr.val){}
nasal_ref& operator=(const nasal_ref& nr)
{
type=nr.type;
value=nr.value;
val=nr.val;
return *this;
}
bool operator==(const nasal_ref& nr){return type==nr.type && value.gcobj==nr.value.gcobj;}
bool operator!=(const nasal_ref& nr){return type!=nr.type || value.gcobj!=nr.value.gcobj;}
bool operator==(const nasal_ref& nr){return type==nr.type && val.gcobj==nr.val.gcobj;}
bool operator!=(const nasal_ref& nr){return type!=nr.type || val.gcobj!=nr.val.gcobj;}
// number and string can be translated to each other
double tonum();
std::string tostr();
@ -154,7 +154,7 @@ struct nasal_upval
struct nasal_obj
{
enum obj_type
enum obj_t:std::uint32_t
{
null,
file,
@ -166,20 +166,25 @@ struct nasal_obj
/* new object is initialized when creating */
uint32_t type;
void* ptr;
/* RAII destroyer */
/* default destroyer does nothing */
typedef void (*dest)(void*);
dest destructor;
dest dtor;
nasal_obj():type(obj_type::null),ptr(nullptr),destructor(nullptr){}
nasal_obj():type(obj_t::null),ptr(nullptr),dtor(nullptr){}
~nasal_obj(){clear();}
void set(uint32_t t=obj_t::null,void* p=nullptr,dest d=nullptr)
{
type=t;
ptr=p;
dtor=d;
}
void clear()
{
if(destructor && ptr)
destructor(ptr);
if(dtor && ptr)
dtor(ptr);
ptr=nullptr;
destructor=nullptr;
dtor=nullptr;
}
};
@ -382,7 +387,7 @@ nasal_val::~nasal_val()
}
double nasal_ref::tonum()
{
return type!=vm_str?value.num:str2num(str().c_str());
return type!=vm_str?val.num:str2num(str().c_str());
}
std::string nasal_ref::tostr()
{
@ -403,7 +408,7 @@ void nasal_ref::print()
{
case vm_none: std::cout<<"undefined"; break;
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<value.num; break;
case vm_num: std::cout<<val.num; break;
case vm_str: std::cout<<str(); break;
case vm_vec: vec().print(); break;
case vm_hash: hash().print(); break;
@ -416,17 +421,17 @@ bool nasal_ref::objchk(uint32_t objtype)
{
return type==vm_obj && obj().type==objtype && obj().ptr;
}
inline nasal_ref* nasal_ref::addr (){return value.addr; }
inline uint32_t nasal_ref::ret (){return value.ret; }
inline int64_t& nasal_ref::cnt (){return value.cnt; }
inline double nasal_ref::num (){return value.num; }
inline std::string& nasal_ref::str (){return *value.gcobj->ptr.str; }
inline nasal_vec& nasal_ref::vec (){return *value.gcobj->ptr.vec; }
inline nasal_hash& nasal_ref::hash (){return *value.gcobj->ptr.hash; }
inline nasal_func& nasal_ref::func (){return *value.gcobj->ptr.func; }
inline nasal_upval& nasal_ref::upval(){return *value.gcobj->ptr.upval;}
inline nasal_obj& nasal_ref::obj (){return *value.gcobj->ptr.obj; }
inline nasal_co& nasal_ref::co (){return *value.gcobj->ptr.co; }
inline nasal_ref* nasal_ref::addr (){return val.addr; }
inline uint32_t nasal_ref::ret (){return val.ret; }
inline int64_t& nasal_ref::cnt (){return val.cnt; }
inline double nasal_ref::num (){return val.num; }
inline std::string& nasal_ref::str (){return *val.gcobj->ptr.str; }
inline nasal_vec& nasal_ref::vec (){return *val.gcobj->ptr.vec; }
inline nasal_hash& nasal_ref::hash (){return *val.gcobj->ptr.hash; }
inline nasal_func& nasal_ref::func (){return *val.gcobj->ptr.func; }
inline nasal_upval& nasal_ref::upval(){return *val.gcobj->ptr.upval;}
inline nasal_obj& nasal_ref::obj (){return *val.gcobj->ptr.obj; }
inline nasal_co& nasal_ref::co (){return *val.gcobj->ptr.co; }
const nasal_ref zero={vm_num,(double)0};
const nasal_ref one ={vm_num,(double)1};
@ -517,8 +522,8 @@ void nasal_gc::mark()
{
nasal_ref tmp=bfs.front();
bfs.pop();
if(tmp.type<=vm_num || tmp.value.gcobj->mark) continue;
tmp.value.gcobj->mark=GC_FOUND;
if(tmp.type<=vm_num || tmp.val.gcobj->mark) continue;
tmp.val.gcobj->mark=GC_FOUND;
switch(tmp.type)
{
case vm_vec:
@ -591,7 +596,7 @@ void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::str
for(uint32_t i=0;i<strs.size();++i)
{
strs[i]={vm_str,new nasal_val(vm_str)};
strs[i].value.gcobj->unmut=1;
strs[i].val.gcobj->unmut=1;
strs[i].str()=s[i];
}
// record arguments
@ -599,7 +604,7 @@ void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::str
for(size_t i=0;i<argv.size();++i)
{
env_argv[i]={vm_str,new nasal_val(vm_str)};
env_argv[i].value.gcobj->unmut=1;
env_argv[i].val.gcobj->unmut=1;
env_argv[i].str()=argv[i];
}
}
@ -612,7 +617,7 @@ void nasal_gc::clear()
while(!unused[i].empty())
unused[i].pop();
for(auto& i:strs)
delete i.value.gcobj;
delete i.val.gcobj;
strs.clear();
env_argv.clear();
}
@ -648,7 +653,7 @@ nasal_ref nasal_gc::alloc(uint8_t type)
}
}
nasal_ref ret={type,unused[index].front()};
ret.value.gcobj->mark=GC_UNCOLLECTED;
ret.val.gcobj->mark=GC_UNCOLLECTED;
unused[index].pop();
return ret;
}

View File

@ -157,7 +157,7 @@ void nasal_vm::init(
}
void nasal_vm::valinfo(nasal_ref& val)
{
const nasal_val* p=val.value.gcobj;
const nasal_val* p=val.val.gcobj;
std::cout<<"\t";
switch(val.type)
{
@ -670,7 +670,7 @@ inline void nasal_vm::opr_callv()
die("callv: must use string as the key");
top[0]=vec.hash().get_val(val.str());
if(top[0].type==vm_none)
die("callv: cannot find member \""+val.str()+"\" of this hash");
die("callv: cannot find member \""+val.str()+"\"");
if(top[0].type==vm_func)
top[0].func().local[0]=val;// 'me'
}
@ -958,8 +958,9 @@ inline void nasal_vm::opr_ret()
auto& upval=up.upval();
auto size=func.func().lsize;
upval.onstk=false;
upval.elems.resize(size);
for(uint32_t i=0;i<size;++i)
upval.elems.push_back(local[i]);
upval.elems[i]=local[i];
}
// cannot use gc.coroutine to judge,
// because there maybe another function call inside

View File

@ -193,7 +193,7 @@ var bf=func(program)
}elsif(c==','){
for(var j=0;j<size(stack);j+=1)
f~='\t';
f~="paper[ptr]=input();\n";
f~="paper[ptr]=input()[0];\n";
}elsif(c=='.'){
for(var j=0;j<size(stack);j+=1)
f~='\t';

View File

@ -44,10 +44,10 @@ println(z.numb);#//1
println(z.listt[2][1]);#//hello
println(z1.hashh.listt[2][1]);#//hello
println(y2[3].hashh.listt[2][1]);#//hello
println(f);#//func(...){...}
println(f);#//func(..){..}
f();#//f is called
println(z.funcc);#//func(...){...}
println(z.funcc);#//func(..){..}
z.funcc();#//f is called
println(z.funcccall);#//func(...){...}
println(z.funcccall);#//func(..){..}
z2.listt2[3].hashh.funcc();#//f is called
println(y1[f2()][w]);#//hello