#ifndef __NASAL_BUILTIN_H__ #define __NASAL_BUILTIN_H__ #if defined __APPLE__ #include #define environ (*_NSGetEnviron()) #endif // declaration of builtin functions #define native(name) nas_ref name(nas_ref*,nasal_gc&) native(builtin_print); native(builtin_println); native(builtin_abort); native(builtin_append); native(builtin_setsize); native(builtin_system); native(builtin_input); native(builtin_fin); native(builtin_fout); native(builtin_split); native(builtin_rand); native(builtin_id); native(builtin_int); native(builtin_floor); native(builtin_num); native(builtin_pop); native(builtin_str); native(builtin_size); native(builtin_i32xor); native(builtin_i32and); native(builtin_i32or); native(builtin_i32nand); native(builtin_i32not); native(builtin_u32xor); native(builtin_u32and); native(builtin_u32or); native(builtin_u32nand); native(builtin_u32not); native(builtin_pow); native(builtin_sin); native(builtin_cos); native(builtin_tan); native(builtin_exp); native(builtin_lg); native(builtin_ln); native(builtin_sqrt); native(builtin_atan2); native(builtin_isnan); native(builtin_time); native(builtin_contains); native(builtin_delete); native(builtin_keys); native(builtin_die); native(builtin_find); native(builtin_type); native(builtin_substr); native(builtin_streq); native(builtin_left); native(builtin_right); native(builtin_cmp); native(builtin_chr); native(builtin_values); native(builtin_exists); native(builtin_open); native(builtin_close); native(builtin_read); native(builtin_write); native(builtin_seek); native(builtin_tell); native(builtin_readln); native(builtin_stat); native(builtin_eof); native(builtin_fld); native(builtin_sfld); native(builtin_setfld); native(builtin_buf); native(builtin_sleep); native(builtin_pipe); native(builtin_fork); native(builtin_waitpid); native(builtin_opendir); native(builtin_readdir); native(builtin_closedir); native(builtin_chdir); native(builtin_environ); native(builtin_getcwd); native(builtin_getenv); native(builtin_dlopen); native(builtin_dlsym); native(builtin_dlclose); native(builtin_dlcall); native(builtin_platform); native(builtin_md5); native(builtin_cocreate); native(builtin_coresume); native(builtin_coyield); native(builtin_costatus); native(builtin_corun); native(builtin_millisec); native(builtin_sysargv); native(builtin_logtime); nas_ref builtin_err(const string& errfunc,const string& info) { std::cerr<<"[vm] "<& 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<"; break; case vm_co: std::cout<<""; break; } } nas_ref builtin_print(nas_ref* local,nasal_gc& gc) { // get arguments,local[0] is reserved for 'me' print_core(local[1].vec().elems); std::cout<>ret.str(); return ret; } nas_ref builtin_fin(nas_ref* local,nasal_gc& gc) { nas_ref val=local[1]; if(val.type!=vm_str) return builtin_err("io.fin","\"filename\" must be string"); std::ifstream fin(val.str()); if(!fin.fail()) { std::stringstream rd; rd<"); } nas_ref builtin_fout(nas_ref* local,nasal_gc& gc) { nas_ref val=local[1]; nas_ref str=local[2]; if(val.type!=vm_str) return builtin_err("io.fout","\"filename\" must be string"); if(str.type!=vm_str) 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()+">"); fout<& vec=res.vec().elems; if(!deli.length()) { for(auto i:s) vec.push_back(gc.newstr(i)); gc.temp=nil; return res; } usize last=0; usize pos=s.find(deli,last); while(pos!=string::npos) { if(pos>last) vec.push_back(gc.newstr(s.substr(last,pos-last))); last=pos+deli.length(); pos=s.find(deli,last); } if(last!=s.length()) vec.push_back(gc.newstr(s.substr(last))); gc.temp=nil; return res; } nas_ref builtin_rand(nas_ref* local,nasal_gc& gc) { nas_ref val=local[1]; if(val.type!=vm_num && val.type!=vm_nil) return builtin_err("rand","\"seed\" must be nil or number"); if(val.type==vm_num) { srand((unsigned int)val.num()); return nil; } f64 num=0; for(int i=0;i<5;++i) num=(num+rand())*(1.0/(RAND_MAX+1.0)); return {vm_num,num}; } nas_ref builtin_id(nas_ref* local,nasal_gc& gc) { nas_ref val=local[1]; std::stringstream ss; if(val.type>vm_num) ss<<"0x"<=str.str().length() || begin+length>str.str().length()) return builtin_err("susbtr","index out of range"); return gc.newstr(str.str().substr(begin,length)); } nas_ref builtin_streq(nas_ref* local,nasal_gc& gc) { nas_ref a=local[1]; nas_ref b=local[2]; return {vm_num,f64((a.type!=vm_str || b.type!=vm_str)?0:(a.str()==b.str()))}; } nas_ref builtin_left(nas_ref* local,nasal_gc& gc) { nas_ref str=local[1]; nas_ref len=local[2]; if(str.type!=vm_str) return builtin_err("left","\"string\" must be string"); if(len.type!=vm_num) return builtin_err("left","\"length\" must be number"); int length=(int)len.num(); if(length<0) length=0; return gc.newstr(str.str().substr(0,length)); } nas_ref builtin_right(nas_ref* local,nasal_gc& gc) { nas_ref str=local[1]; nas_ref len=local[2]; if(str.type!=vm_str) return builtin_err("right","\"string\" must be string"); if(len.type!=vm_num) return builtin_err("right","\"length\" must be number"); int length=(int)len.num(); int srclen=str.str().length(); if(length>srclen) length=srclen; if(length<0) length=0; return gc.newstr(str.str().substr(srclen-length, srclen)); } nas_ref builtin_cmp(nas_ref* local,nasal_gc& gc) { nas_ref a=local[1]; nas_ref b=local[2]; if(a.type!=vm_str) return builtin_err("cmp","\"a\" must be string"); if(b.type!=vm_str) return builtin_err("cmp","\"b\" must be string"); return {vm_num,(f64)strcmp(a.str().c_str(),b.str().c_str())}; } nas_ref builtin_chr(nas_ref* local,nasal_gc& gc) { const char* extend[]={ "€"," ","‚","ƒ","„","…","†","‡", "ˆ","‰","Š","‹","Œ"," ","Ž"," ", " ","‘","’","“","”","•","–","—", "˜","™","š","›","œ"," ","ž","Ÿ", " ","¡","¢","£","¤","¥","¦","§", "¨","©","ª","«","¬"," ","®","¯", "°","±","²","³","´","µ","¶","·", "¸","¹","º","»","¼","½","¾","¿", "À","Á","Â","Ã","Ä","Å","Æ","Ç", "È","É","Ê","Ë","Ì","Í","Î","Ï", "Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×", "Ø","Ù","Ú","Û","Ü","Ý","Þ","ß", "à","á","â","ã","ä","å","æ","ç", "è","é","ê","ë","ì","í","î","ï", "ð","ñ","ò","ó","ô","õ","ö","÷", "ø","ù","ú","û","ü","ý","þ","ÿ" }; nas_ref code=local[1]; if(code.type!=vm_num) return builtin_err("chr","\"code\" must be number"); int num=code.num(); if(0<=num && num<128) return gc.newstr((char)num); else if(128<=num && num<256) return gc.newstr(extend[num-128]); return gc.newstr(" "); } nas_ref builtin_values(nas_ref* local,nasal_gc& gc) { nas_ref hash=local[1]; if(hash.type!=vm_hash) return builtin_err("values","\"hash\" must be a hashmap"); nas_ref vec=gc.alloc(vm_vec); auto& v=vec.vec().elems; for(auto& i:hash.hash().elems) v.push_back(i.second); return vec; } nas_ref builtin_exists(nas_ref* local,nasal_gc& gc) { if(local[1].type!=vm_str) return zero; return access(local[1].str().c_str(),F_OK)!=-1?one:zero; } void obj_file_dtor(void* ptr) { fclose((FILE*)ptr); } nas_ref builtin_open(nas_ref* local,nasal_gc& gc) { nas_ref name=local[1]; nas_ref mode=local[2]; if(name.type!=vm_str) return builtin_err("open","\"filename\" must be string"); if(mode.type!=vm_str) return builtin_err("open","\"mode\" must be string"); FILE* res=fopen(name.str().c_str(),mode.str().c_str()); if(!res) return builtin_err("open","failed to open file <"+name.str()+">"); nas_ref ret=gc.alloc(vm_obj); ret.obj().set(nas_obj::file,res,obj_file_dtor); return ret; } nas_ref builtin_close(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; if(!fd.objchk(nas_obj::file)) return builtin_err("close","not a valid filehandle"); fclose((FILE*)fd.obj().ptr); fd.obj().ptr=nullptr; return nil; } nas_ref builtin_read(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; nas_ref buf=local[2]; nas_ref len=local[3]; if(!fd.objchk(nas_obj::file)) return builtin_err("read","not a valid filehandle"); if(buf.type!=vm_str) return builtin_err("read","\"buf\" must be string"); 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"); if(len.num()<=0 || len.num()>=(1<<30)) return builtin_err("read","\"len\" less than 1 or too large"); char* buff=new char[(usize)len.num()+1]; if(!buff) return builtin_err("read","memory allocation error"); f64 res=fread(buff,1,len.num(),(FILE*)fd.obj().ptr); buf.str()=buff; delete []buff; return {vm_num,res}; } nas_ref builtin_write(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; nas_ref str=local[2]; if(!fd.objchk(nas_obj::file)) return builtin_err("write","not a valid filehandle"); if(str.type!=vm_str) return builtin_err("write","\"str\" must be string"); f64 res=(f64)fwrite(str.str().c_str(),1,str.str().length(),(FILE*)fd.obj().ptr); return {vm_num,res}; } nas_ref builtin_seek(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; nas_ref pos=local[2]; nas_ref whence=local[3]; if(!fd.objchk(nas_obj::file)) return builtin_err("seek","not a valid filehandle"); if(pos.type!=vm_num) return builtin_err("seek","\"pos\" must be number"); if(whence.type!=vm_num || whence.num()<0 || whence.num()>2) return builtin_err("seek","\"whence\" must be number between 0 and 2"); f64 res=fseek((FILE*)fd.obj().ptr,pos.num(),whence.num()); return {vm_num,res}; } nas_ref builtin_tell(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; if(!fd.objchk(nas_obj::file)) return builtin_err("tell","not a valid filehandle"); f64 res=ftell((FILE*)fd.obj().ptr); return {vm_num,res}; } nas_ref builtin_readln(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; if(!fd.objchk(nas_obj::file)) return builtin_err("readln","not a valid filehandle"); nas_ref str=gc.alloc(vm_str); auto& s=str.str(); char c; while((c=fgetc((FILE*)fd.obj().ptr))!=EOF) { if(c=='\r') continue; if(c=='\n') return str; s+=c; } if(s.length()) return str; return nil; } nas_ref builtin_stat(nas_ref* local,nasal_gc& gc) { nas_ref name=local[1]; if(name.type!=vm_str) return builtin_err("stat","\"filename\" must be string"); struct stat buf; if(stat(name.str().c_str(),&buf)<0) return builtin_err("stat","failed to open file <"+name.str()+">"); nas_ref ret=gc.alloc(vm_vec); ret.vec().elems={ {vm_num,(f64)buf.st_dev}, {vm_num,(f64)buf.st_ino}, {vm_num,(f64)buf.st_mode}, {vm_num,(f64)buf.st_nlink}, {vm_num,(f64)buf.st_uid}, {vm_num,(f64)buf.st_gid}, {vm_num,(f64)buf.st_rdev}, {vm_num,(f64)buf.st_size}, {vm_num,(f64)buf.st_atime}, {vm_num,(f64)buf.st_mtime}, {vm_num,(f64)buf.st_ctime} }; return ret; } nas_ref builtin_eof(nas_ref* local,nasal_gc& gc) { nas_ref fd=local[1]; if(!fd.objchk(nas_obj::file)) return builtin_err("readln","not a valid filehandle"); return {vm_num,(f64)feof((FILE*)fd.obj().ptr)}; } nas_ref builtin_fld(nas_ref* local,nasal_gc& gc) { // bits.fld(s,0,3); // if s stores 10100010(162) // will get 101(5) nas_ref str=local[1]; nas_ref startbit=local[2]; nas_ref length=local[3]; 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"); u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); if(bit+len>8*str.str().length()) return builtin_err("fld","bitfield out of bounds"); u32 res=0; auto& s=str.str(); for(u32 i=bit;i>3]&(1<<(7-(i&7)))) res|=1<<(bit+len-i-1); return {vm_num,(f64)res}; } nas_ref builtin_sfld(nas_ref* local,nasal_gc& gc) { // bits.sfld(s,0,3); // if s stores 10100010(162) // will get 101(5) then this will be signed extended to // 11111101(-3) nas_ref str=local[1]; nas_ref startbit=local[2]; nas_ref length=local[3]; 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"); u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); if(bit+len>8*str.str().length()) return builtin_err("sfld","bitfield out of bounds"); u32 res=0; auto& s=str.str(); for(u32 i=bit;i>3]&(1<<(7-(i&7)))) res|=1<<(bit+len-i-1); if(res&(1<<(len-1))) res|=~((1<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"); u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); u64 val=(u64)value.num(); if(bit+len>8*str.str().length()) return builtin_err("setfld","bitfield out of bounds"); auto& s=str.str(); for(u32 i=bit;i>3]|=(1<<(7-(i&7))); else s[i>>3]&=~(1<<(7-(i&7))); } return nil; } nas_ref builtin_buf(nas_ref* local,nasal_gc& gc) { nas_ref length=local[1]; if(length.type!=vm_num || length.num()<=0) return builtin_err("buf","\"len\" must be a number greater than 0"); nas_ref str=gc.alloc(vm_str); auto& s=str.str(); s.resize(length.num(),'\0'); return str; } nas_ref builtin_sleep(nas_ref* local,nasal_gc& gc) { nas_ref val=local[1]; if(val.type!=vm_num) return builtin_err("sleep","\"duration\" must be number"); std::this_thread::sleep_for(std::chrono::microseconds(i64(val.num()*1e6))); return nil; } nas_ref builtin_pipe(nas_ref* local,nasal_gc& gc) { #ifndef _WIN32 int fd[2]; nas_ref res=gc.alloc(vm_vec); if(pipe(fd)==-1) return builtin_err("pipe","failed to create pipe"); res.vec().elems.push_back({vm_num,(f64)fd[0]}); res.vec().elems.push_back({vm_num,(f64)fd[1]}); return res; #endif return builtin_err("pipe","not supported for windows"); } nas_ref builtin_fork(nas_ref* local,nasal_gc& gc) { #ifndef _WIN32 f64 res=fork(); if(res<0) return builtin_err("fork","failed to fork a process"); return {vm_num,(f64)res}; #endif return builtin_err("fork","not supported for windows"); } nas_ref builtin_waitpid(nas_ref* local,nasal_gc& gc) { nas_ref pid=local[1]; nas_ref nohang=local[2]; if(pid.type!=vm_num || nohang.type!=vm_num) return builtin_err("waitpid","pid and nohang must be number"); #ifndef _WIN32 int ret_pid; int status; ret_pid=waitpid(pid.num(),&status,nohang.num()==0?0:WNOHANG); nas_ref vec=gc.alloc(vm_vec); vec.vec().elems.push_back({vm_num,(f64)ret_pid}); vec.vec().elems.push_back({vm_num,(f64)status}); return vec; #endif return builtin_err("waitpid","not supported for windows"); } void obj_dir_dtor(void* ptr) { #ifndef _MSC_VER closedir((DIR*)ptr); #else FindClose(ptr); #endif } nas_ref builtin_opendir(nas_ref* local,nasal_gc& gc) { nas_ref path=local[1]; if(path.type!=vm_str) return builtin_err("opendir","\"path\" must be string"); #ifdef _MSC_VER WIN32_FIND_DATA data; HANDLE p; p=FindFirstFile((path.str()+"\\*.*").c_str(),&data); if(p==INVALID_HANDLE_VALUE) return builtin_err("opendir","cannot open dir <"+path.str()+">"); #else DIR* p=opendir(path.str().c_str()); if(!p) return builtin_err("opendir","cannot open dir <"+path.str()+">"); #endif nas_ref ret=gc.alloc(vm_obj); ret.obj().set(nas_obj::dir,p,obj_dir_dtor); return ret; } nas_ref builtin_readdir(nas_ref* local,nasal_gc& gc) { nas_ref handle=local[1]; if(!handle.objchk(nas_obj::dir)) return builtin_err("readdir","not a valid dir handle"); #ifdef _MSC_VER WIN32_FIND_DATA data; if(!FindNextFile(handle.obj().ptr,&data)) return nil; return gc.newstr(data.cFileName); #else dirent* p=readdir((DIR*)handle.obj().ptr); if(!p) return nil; return gc.newstr(p->d_name); #endif } nas_ref builtin_closedir(nas_ref* local,nasal_gc& gc) { nas_ref handle=local[1]; if(!handle.objchk(nas_obj::dir)) return builtin_err("closedir","not a valid dir handle"); #ifndef _MSC_VER closedir((DIR*)handle.obj().ptr); #else FindClose(handle.obj().ptr); #endif handle.obj().ptr=nullptr; return nil; } nas_ref builtin_chdir(nas_ref* local,nasal_gc& gc) { nas_ref path=local[1]; if(path.type!=vm_str) return builtin_err("chdir","\"path\" must be string"); if(chdir(path.str().c_str())<0) return builtin_err("chdir","failed to execute chdir"); return nil; } nas_ref builtin_environ(nas_ref* local,nasal_gc& gc) { char** env=environ; nas_ref res=gc.temp=gc.alloc(vm_vec); auto& vec=res.vec().elems; while(*env) { vec.push_back(gc.newstr(*env)); ++env; } gc.temp=nil; return res; } nas_ref builtin_getcwd(nas_ref* local,nasal_gc& gc) { char buf[1024]; if(!getcwd(buf,sizeof(buf))) return builtin_err("getcwd","failed to call getcwd"); return gc.newstr(buf); } nas_ref builtin_getenv(nas_ref* local,nasal_gc& gc) { nas_ref envvar=local[1]; if(envvar.type!=vm_str) return builtin_err("getenv","\"envvar\" must be string"); char* res=getenv(envvar.str().c_str()); if(!res) return nil; return gc.newstr(res); } void obj_dylib_dtor(void* ptr) { #ifdef _WIN32 FreeLibrary((HMODULE)ptr); #else dlclose(ptr); #endif } nas_ref builtin_dlopen(nas_ref* local,nasal_gc& gc) { nas_ref dlname=local[1]; if(dlname.type!=vm_str) return builtin_err("dlopen","\"libname\" must be string"); #ifdef _WIN32 wchar_t* str=new wchar_t[dlname.str().size()+1]; memset(str,0,sizeof(wchar_t)*dlname.str().size()+1); mbstowcs(str,dlname.str().c_str(),dlname.str().size()+1); void* ptr=LoadLibraryW(str); delete []str; #else void* ptr=dlopen(dlname.str().c_str(),RTLD_LOCAL|RTLD_LAZY); #endif if(!ptr) return builtin_err("dlopen","cannot open dynamic lib <"+dlname.str()+">"); nas_ref ret=gc.alloc(vm_obj); ret.obj().set(nas_obj::dylib,ptr,obj_dylib_dtor); return ret; } nas_ref builtin_dlsym(nas_ref* local,nasal_gc& gc) { nas_ref lib=local[1]; nas_ref sym=local[2]; if(!lib.objchk(nas_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)lib.obj().ptr,sym.str().c_str()); #else void* func=dlsym(lib.obj().ptr,sym.str().c_str()); #endif if(!func) return builtin_err("dlsym","cannot find symbol \""+sym.str()+"\""); nas_ref ret=gc.alloc(vm_obj); ret.obj().set(nas_obj::faddr,func); return ret; } nas_ref builtin_dlclose(nas_ref* local,nasal_gc& gc) { nas_ref libptr=local[1]; if(!libptr.objchk(nas_obj::dylib)) return builtin_err("dlclose","\"lib\" is not a valid dynamic lib"); #ifdef _WIN32 FreeLibrary((HMODULE)libptr.obj().ptr); #else dlclose(libptr.obj().ptr); #endif libptr.obj().ptr=nullptr; return nil; } nas_ref builtin_dlcall(nas_ref* local,nasal_gc& gc) { nas_ref funcptr=local[1]; nas_ref args=local[2]; if(!funcptr.objchk(nas_obj::faddr)) return builtin_err("dlcall","\"funcptr\" is not a valid function pointer"); typedef nas_ref (*externs)(std::vector&,nasal_gc&); externs func=(externs)funcptr.obj().ptr; return func(args.vec().elems,gc); } nas_ref builtin_platform(nas_ref* local,nasal_gc& gc) { #if defined _WIN32 || defined _WIN64 return gc.newstr("windows"); #elif defined __linux__ return gc.newstr("linux"); #elif defined __APPLE__ return gc.newstr("macOS"); #endif return gc.newstr("unknown"); } // md5 related functions string tohex(u32 num) { const char str16[]="0123456789abcdef"; string str=""; for(u32 i=0;i<4;i++,num>>=8) { string tmp=""; for(u32 j=0,b=num&0xff;j<2;j++,b>>=4) tmp.insert(0,1,str16[b&0xf]); str+=tmp; } return str; } string md5(const string& source) { std::vector buff; u32 num=((source.length()+8)>>6)+1; u32 buffsize=num<<4; buff.resize(buffsize,0); for(u32 i=0;i>2]|=((unsigned char)source[i])<<((i&0x3)<<3); buff[source.length()>>2]|=0x80<<(((source.length()%4))<<3); buff[buffsize-2]=(source.length()<<3)&0xffffffff; buff[buffsize-1]=((source.length()<<3)>>32)&0xffffffff; // u32(abs(sin(i+1))*(2pow32)) const u32 k[]={ 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501, 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821, 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a, 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70, 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665, 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1, 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; // left shift bits const u32 s[]={ 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 }; // index const u32 idx[]={ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // g=i 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, // g=(5*i+1)%16; 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, // g=(3*i+5)%16; 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 // g=(7*i)%16; }; #define shift(x,n) (((x)<<(n))|((x)>>(32-(n)))) // cycle left shift #define md5f(x,y,z) (((x)&(y))|((~x)&(z))) #define md5g(x,y,z) (((x)&(z))|((y)&(~z))) #define md5h(x,y,z) ((x)^(y)^(z)) #define md5i(x,y,z) ((y)^((x)|(~z))) u32 atmp=0x67452301,btmp=0xefcdab89; u32 ctmp=0x98badcfe,dtmp=0x10325476; for(u32 i=0;i (std::chrono::high_resolution_clock::now().time_since_epoch()) .count(); return {vm_num,res}; } nas_ref builtin_sysargv(nas_ref* local,nasal_gc& gc) { nas_ref res=gc.alloc(vm_vec); res.vec().elems=gc.env_argv; return res; } nas_ref builtin_logtime(nas_ref* local,nasal_gc& gc) { time_t t=time(nullptr); tm* tm_t=localtime(&t); char s[128]; sprintf(s,"%d-%.2d-%.2d %.2d:%.2d:%.2d",tm_t->tm_year+1900,tm_t->tm_mon+1,tm_t->tm_mday,tm_t->tm_hour,tm_t->tm_min,tm_t->tm_sec); return gc.newstr(s); } #endif