From 4bfce37f40bd75295ddb5572de806180835d9dc7 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 28 Oct 2021 21:49:08 +0800 Subject: [PATCH] add bits lib --- lib.nas | 164 +++++++++++++----------------------------------- nasal_builtin.h | 120 ++++++++++++++++++++++++++++++++++- nasal_gc.h | 3 + nasal_vm.h | 2 +- stl/lib.nas | 164 +++++++++++++----------------------------------- 5 files changed, 209 insertions(+), 244 deletions(-) diff --git a/lib.nas b/lib.nas index 11c3d46..fbb2e85 100644 --- a/lib.nas +++ b/lib.nas @@ -1,133 +1,51 @@ -var import=func(filename) -{ - return __builtin_import(filename); -} -var print=func(elems...) -{ - return __builtin_print(elems); -}; -var println=func(elems...) -{ +var import= func(filename){return __builtin_import(filename);} +var print= func(elems...){return __builtin_print(elems);} +var append= func(vec,elems...){return __builtin_append(vec,elems);} +var setsize= func(vec,size){return __builtin_setsize(vec,size);} +var system= func(str){return __builtin_system(str);} +var input= func(){return __builtin_input();} +var sleep= func(duration){return __builtin_sleep(duration);} +var split= func(deli,str){return __builtin_split(deli,str);} +var rand= func(seed=nil){return __builtin_rand(seed);} +var id= func(object){return __builtin_id(object);} +var int= func(val){return __builtin_int(val);} +var num= func(val){return __builtin_num(val);} +var pop= func(vec){return __builtin_pop(vec);} +var str= func(num){return __builtin_str(num);} +var size= func(object){return __builtin_size(object);} +var contains= func(hash,key){return __builtin_contains(hash,key);} +var delete= func(hash,key){return __builtin_delete(hash,key);} +var keys= func(hash){return __builtin_keys(hash);} +var time= func(begin){return __builtin_time(begin);} +var die= func(str){return __builtin_die(str);} +var typeof= func(object){return __builtin_type(object);} +var substr= func(str,begin,len){return __builtin_substr(str,begin,len);} +var streq= func(a,b){return __builtin_streq(a,b);} +var left= func(str,len){return __builtin_left(str,len);} +var right= func(str,len){return __builtin_right(str,len);} +var cmp= func(a,b){return __builtin_cmp(a,b);} +var chr= func(code){return __builtin_chr(code);} +var println=func(elems...){ __builtin_print(elems); elems=['\n']; return __builtin_print(elems); } -var append=func(vec,elems...) -{ - return __builtin_append(vec,elems); -} -var setsize=func(vec,size) -{ - return __builtin_setsize(vec,size); -} -var system=func(str) -{ - return __builtin_system(str); -} -var input=func() -{ - return __builtin_input(); -} -var sleep=func(duration) -{ - return __builtin_sleep(duration); -} -var split=func(deli,str) -{ - return __builtin_split(deli,str); -} -var rand=func(seed=nil) -{ - return __builtin_rand(seed); -} -var id=func(object) -{ - return __builtin_id(object); -} -var int=func(val) -{ - return __builtin_int(val); -} -var num=func(val) -{ - return __builtin_num(val); -} -var pop=func(vec) -{ - return __builtin_pop(vec); -} -var str=func(num) -{ - return __builtin_str(num); -} -var size=func(object) -{ - return __builtin_size(object); -} -var contains=func(hash,key) -{ - return __builtin_contains(hash,key); -} -var delete=func(hash,key) -{ - return __builtin_delete(hash,key); -} -var keys=func(hash) -{ - return __builtin_keys(hash); -} -var time=func(begin_time) -{ - return __builtin_time(begin_time); -} -var die=func(str) -{ - return __builtin_die(str); -} -var typeof=func(object) -{ - return __builtin_type(object); -} -var substr=func(str,begin,len) -{ - return __builtin_substr(str,begin,len); -} -var streq=func(a,b) -{ - return __builtin_streq(a,b); -} -var left=func(str,len) -{ - return __builtin_left(str,len); -} -var right=func(str,len) -{ - return __builtin_right(str,len); -} -var cmp=func(a,b) -{ - return __builtin_cmp(a,b); -} -var chr=func(code) -{ - return __builtin_chr(code); -} - var io= { - fin: func(filename){return __builtin_fin(filename);}, - fout:func(filename,str){return __builtin_fout(filename,str);}, SEEK_SET:0, SEEK_CUR:1, SEEK_END:2, - open:func(filename,mode="r"){return __builtin_open(filename,mode);}, - close:func(filehandle){return __builtin_close(filehandle);}, - read:func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, - write:func(filehandle,str){return __builtin_write(filehandle,str);}, - seek:func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);}, - tell:func(filehandle){return __builtin_tell(filehandle);}, + fin: func(filename){return __builtin_fin(filename);}, + fout: func(filename,str){return __builtin_fout(filename,str);}, + open: func(filename,mode="r"){return __builtin_open(filename,mode);}, + close: func(filehandle){return __builtin_close(filehandle);}, + read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, + write: func(filehandle,str){return __builtin_write(filehandle,str);}, + seek: func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);}, + tell: func(filehandle){return __builtin_tell(filehandle);}, readln:func(filehandle){return __builtin_readln(filehandle);}, - stat:func(filename){return __builtin_stat(filename);} + stat: func(filename){return __builtin_stat(filename);}, + eof: func(filehandle){return __builtin_eof(filehandle);} }; var bits= @@ -136,7 +54,11 @@ var bits= bitand: func(a,b){return __builtin_and(a,b); }, bitor: func(a,b){return __builtin_or(a,b); }, bitnand: func(a,b){return __builtin_nand(a,b);}, - bitnot: func(a) {return __builtin_not(a); } + bitnot: func(a) {return __builtin_not(a); }, + fld: func(str,startbit,len){return __builtin_fld;}, + sfld: func(str,startbit,len){return __builtin_sfld;}, + setfld: func(str,startbit,len,val){return __builtin_setfld;}, + buf: func(len){return __builtin_buf;} }; var math= diff --git a/nasal_builtin.h b/nasal_builtin.h index 157d4c6..8d11e1e 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -64,6 +64,11 @@ nas_native(builtin_seek); nas_native(builtin_tell); nas_native(builtin_readln); nas_native(builtin_stat); +nas_native(builtin_eof); +nas_native(builtin_fld); +nas_native(builtin_sfld); +nas_native(builtin_setfld); +nas_native(builtin_buf); nasal_ref builtin_err(const char* func_name,std::string info) { @@ -129,6 +134,11 @@ struct {"__builtin_tell", builtin_tell }, {"__builtin_readln", builtin_readln }, {"__builtin_stat", builtin_stat }, + {"__builtin_eof", builtin_eof }, + {"__builtin_fld", builtin_fld }, + {"__builtin_sfld", builtin_sfld }, + {"__builtin_setfld", builtin_setfld }, + {"__builtin_buf", builtin_buf }, {nullptr, nullptr } }; @@ -745,7 +755,19 @@ nasal_ref builtin_readln(std::vector& local,nasal_gc& gc) nasal_ref filehandle=local[1]; if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file) return builtin_err("readln","not a correct filehandle"); - /* unfinished */ + nasal_ref str=gc.alloc(vm_str); + auto& s=*str.str(); + char c; + while((c=fgetc((FILE*)filehandle.obj()->ptr))!=EOF) + { + if(c=='\r') + continue; + if(c=='\n') + return str; + s+=c; + } + if(s.length()) + return str; return gc.nil; } nasal_ref builtin_stat(std::vector& local,nasal_gc& gc) @@ -772,4 +794,100 @@ nasal_ref builtin_stat(std::vector& local,nasal_gc& gc) }; return ret; } +nasal_ref builtin_eof(std::vector& local,nasal_gc& gc) +{ + nasal_ref filehandle=local[1]; + if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file) + return builtin_err("readln","not a correct filehandle"); + double res=feof((FILE*)filehandle.obj()->ptr); + return {vm_num,res}; +} +nasal_ref builtin_fld(std::vector& local,nasal_gc& gc) +{ + // bits.fld(s,0,3); + // if s stores 10100010(162) + // will get 101(5) + nasal_ref str=local[1]; + nasal_ref startbit=local[2]; + nasal_ref length=local[3]; + if(str.type!=vm_str || str.value.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"); + uint32_t bit=(uint32_t)startbit.num(); + uint32_t len=(uint32_t)length.num(); + if(bit+len>8*str.str()->length()) + return builtin_err("fld","bitfield out of bounds"); + uint32_t res=0; + auto& s=*str.str(); + for(uint32_t i=bit;i>3]&(1<<(7-(i&7)))) + res|=1<<(bit+len-i-1); + return {vm_num,(double)res}; +} +nasal_ref builtin_sfld(std::vector& 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) + nasal_ref str=local[1]; + nasal_ref startbit=local[2]; + nasal_ref length=local[3]; + if(str.type!=vm_str || str.value.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"); + uint32_t bit=(uint32_t)startbit.num(); + uint32_t len=(uint32_t)length.num(); + if(bit+len>8*str.str()->length()) + return builtin_err("sfld","bitfield out of bounds"); + uint32_t res=0; + auto& s=*str.str(); + for(uint32_t i=bit;i>3]&(1<<(7-(i&7)))) + res|=1<<(bit+len-i-1); + if(res&(1<<(len-1))) + res|=~((1<& local,nasal_gc& gc) +{ + // bits.setfld(s,0,8,69); + // set 1000101(69) to string will get this: + // 10100010(162) + // so s[0]=162 + nasal_ref str=local[1]; + nasal_ref startbit=local[2]; + nasal_ref length=local[3]; + nasal_ref value=local[4]; + if(str.type!=vm_str || str.value.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"); + uint32_t bit=(uint32_t)startbit.num(); + uint32_t len=(uint32_t)length.num(); + uint64_t val=(uint64_t)value.num(); + if(bit+len>8*str.str()->length()) + return builtin_err("setfld","bitfield out of bounds"); + auto& s=*str.str(); + for(uint32_t i=bit;i>3]|=(1<<(7-(i&7))); + else + s[i>>3]&=~(1<<(7-(i&7))); + } + return gc.nil; +} +nasal_ref builtin_buf(std::vector& 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"); + nasal_ref str=gc.alloc(vm_str); + auto& s=*str.str(); + s.resize(length.num(),'\0'); + return str; +} #endif \ No newline at end of file diff --git a/nasal_gc.h b/nasal_gc.h index 490050c..4e8ddcd 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -115,6 +115,7 @@ struct nasal_val { uint8_t mark; uint8_t type; + uint8_t unmut; union { std::string* str; @@ -262,6 +263,7 @@ nasal_val::nasal_val(uint8_t val_type) { mark=GC_COLLECTED; type=val_type; + unmut=0; switch(val_type) { case vm_str: ptr.str=new std::string; break; @@ -400,6 +402,7 @@ void nasal_gc::init(const std::vector& s) for(uint32_t i=0;iunmut=1; *strs[i].str()=s[i]; } } diff --git a/nasal_vm.h b/nasal_vm.h index 01f9381..9b6e94d 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -607,7 +607,7 @@ inline void nasal_vm::opr_callv() int str_size=str.length(); if(num<-str_size || num>=str_size) die("callv: index out of range:"+std::to_string(val.to_number())); - gc.top[0]={vm_num,static_cast(str[num>=0? num:num+str_size])}; + gc.top[0]={vm_num,double((uint8_t)str[num>=0? num:num+str_size])}; } else die("callv: must call a vector/hash/string"); diff --git a/stl/lib.nas b/stl/lib.nas index 11c3d46..fbb2e85 100644 --- a/stl/lib.nas +++ b/stl/lib.nas @@ -1,133 +1,51 @@ -var import=func(filename) -{ - return __builtin_import(filename); -} -var print=func(elems...) -{ - return __builtin_print(elems); -}; -var println=func(elems...) -{ +var import= func(filename){return __builtin_import(filename);} +var print= func(elems...){return __builtin_print(elems);} +var append= func(vec,elems...){return __builtin_append(vec,elems);} +var setsize= func(vec,size){return __builtin_setsize(vec,size);} +var system= func(str){return __builtin_system(str);} +var input= func(){return __builtin_input();} +var sleep= func(duration){return __builtin_sleep(duration);} +var split= func(deli,str){return __builtin_split(deli,str);} +var rand= func(seed=nil){return __builtin_rand(seed);} +var id= func(object){return __builtin_id(object);} +var int= func(val){return __builtin_int(val);} +var num= func(val){return __builtin_num(val);} +var pop= func(vec){return __builtin_pop(vec);} +var str= func(num){return __builtin_str(num);} +var size= func(object){return __builtin_size(object);} +var contains= func(hash,key){return __builtin_contains(hash,key);} +var delete= func(hash,key){return __builtin_delete(hash,key);} +var keys= func(hash){return __builtin_keys(hash);} +var time= func(begin){return __builtin_time(begin);} +var die= func(str){return __builtin_die(str);} +var typeof= func(object){return __builtin_type(object);} +var substr= func(str,begin,len){return __builtin_substr(str,begin,len);} +var streq= func(a,b){return __builtin_streq(a,b);} +var left= func(str,len){return __builtin_left(str,len);} +var right= func(str,len){return __builtin_right(str,len);} +var cmp= func(a,b){return __builtin_cmp(a,b);} +var chr= func(code){return __builtin_chr(code);} +var println=func(elems...){ __builtin_print(elems); elems=['\n']; return __builtin_print(elems); } -var append=func(vec,elems...) -{ - return __builtin_append(vec,elems); -} -var setsize=func(vec,size) -{ - return __builtin_setsize(vec,size); -} -var system=func(str) -{ - return __builtin_system(str); -} -var input=func() -{ - return __builtin_input(); -} -var sleep=func(duration) -{ - return __builtin_sleep(duration); -} -var split=func(deli,str) -{ - return __builtin_split(deli,str); -} -var rand=func(seed=nil) -{ - return __builtin_rand(seed); -} -var id=func(object) -{ - return __builtin_id(object); -} -var int=func(val) -{ - return __builtin_int(val); -} -var num=func(val) -{ - return __builtin_num(val); -} -var pop=func(vec) -{ - return __builtin_pop(vec); -} -var str=func(num) -{ - return __builtin_str(num); -} -var size=func(object) -{ - return __builtin_size(object); -} -var contains=func(hash,key) -{ - return __builtin_contains(hash,key); -} -var delete=func(hash,key) -{ - return __builtin_delete(hash,key); -} -var keys=func(hash) -{ - return __builtin_keys(hash); -} -var time=func(begin_time) -{ - return __builtin_time(begin_time); -} -var die=func(str) -{ - return __builtin_die(str); -} -var typeof=func(object) -{ - return __builtin_type(object); -} -var substr=func(str,begin,len) -{ - return __builtin_substr(str,begin,len); -} -var streq=func(a,b) -{ - return __builtin_streq(a,b); -} -var left=func(str,len) -{ - return __builtin_left(str,len); -} -var right=func(str,len) -{ - return __builtin_right(str,len); -} -var cmp=func(a,b) -{ - return __builtin_cmp(a,b); -} -var chr=func(code) -{ - return __builtin_chr(code); -} - var io= { - fin: func(filename){return __builtin_fin(filename);}, - fout:func(filename,str){return __builtin_fout(filename,str);}, SEEK_SET:0, SEEK_CUR:1, SEEK_END:2, - open:func(filename,mode="r"){return __builtin_open(filename,mode);}, - close:func(filehandle){return __builtin_close(filehandle);}, - read:func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, - write:func(filehandle,str){return __builtin_write(filehandle,str);}, - seek:func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);}, - tell:func(filehandle){return __builtin_tell(filehandle);}, + fin: func(filename){return __builtin_fin(filename);}, + fout: func(filename,str){return __builtin_fout(filename,str);}, + open: func(filename,mode="r"){return __builtin_open(filename,mode);}, + close: func(filehandle){return __builtin_close(filehandle);}, + read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, + write: func(filehandle,str){return __builtin_write(filehandle,str);}, + seek: func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);}, + tell: func(filehandle){return __builtin_tell(filehandle);}, readln:func(filehandle){return __builtin_readln(filehandle);}, - stat:func(filename){return __builtin_stat(filename);} + stat: func(filename){return __builtin_stat(filename);}, + eof: func(filehandle){return __builtin_eof(filehandle);} }; var bits= @@ -136,7 +54,11 @@ var bits= bitand: func(a,b){return __builtin_and(a,b); }, bitor: func(a,b){return __builtin_or(a,b); }, bitnand: func(a,b){return __builtin_nand(a,b);}, - bitnot: func(a) {return __builtin_not(a); } + bitnot: func(a) {return __builtin_not(a); }, + fld: func(str,startbit,len){return __builtin_fld;}, + sfld: func(str,startbit,len){return __builtin_sfld;}, + setfld: func(str,startbit,len,val){return __builtin_setfld;}, + buf: func(len){return __builtin_buf;} }; var math=