diff --git a/lib.nas b/lib.nas index 44c82b0..65a8882 100644 --- a/lib.nas +++ b/lib.nas @@ -60,6 +60,17 @@ var int=func(val){ return __builtin_int(val); } +# floor will get the integral number of input argument +# which is less than or equal to this argument +var floor=func(val){ + return __builtin_floor(val); +} + +# abs gets absolute number +var abs=func(n){ + return n>0?n:-n; +} + # num will change all the other types into number. # mostly used to change a numerable string. var num=func(val){ @@ -105,6 +116,9 @@ var keys=func(hash){ var time=func(begin){ return __builtin_time(begin); } +var systime=func(){ + return time(0); +} # die is a special native function. # use it at where you want the program to crash immediately. @@ -118,6 +132,11 @@ var typeof=func(object){ return __builtin_type(object); } +# subvec is used to get part of a vector +var subvec=func(vec,begin,length=nil){ + return vec[begin:(length==nil?nil:begin+length-1)]; +} + # substr will get the sub-string. # it gets the string, the begin index and sub-string's length as arguments. var substr=func(str,begin,len){ @@ -169,6 +188,45 @@ var println=func(elems...){ return __builtin_print(elems); } +var isfunc=func(f){ + return typeof(f)=="func"; +} + +var isghost=func(g){ + die("this runtime have no ghost object"); + return 0; +} + +var ishash=func(h){ + return typeof(h)=="hash"; +} + +var isint=func(x){ + return x==floor(x); +} + +var isnum=func(x){ + return typeof(x)=="num" or !math.isnan(num(x)); +} + +var isscalar=func(s){ + var t=typeof(s); + return t=="num" or t=="str"; +} + +var isstr=func(s){ + return typeof(s)=="str"; +} + +var isvec=func(v){ + return typeof(v)=="vec"; +} + +var vecindex=func(vec,val){ + # unfinished + return nil; +} + var io= { SEEK_SET:0, diff --git a/nasal_builtin.h b/nasal_builtin.h index f932507..5d17c79 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -20,6 +20,7 @@ nas_native(builtin_split); nas_native(builtin_rand); nas_native(builtin_id); nas_native(builtin_int); +nas_native(builtin_floor); nas_native(builtin_num); nas_native(builtin_pop); nas_native(builtin_str); @@ -108,6 +109,7 @@ struct {"__builtin_rand", builtin_rand }, {"__builtin_id", builtin_id }, {"__builtin_int", builtin_int }, + {"__builtin_floor", builtin_floor }, {"__builtin_num", builtin_num }, {"__builtin_pop", builtin_pop }, {"__builtin_str", builtin_str }, @@ -363,6 +365,11 @@ nasal_ref builtin_int(nasal_ref* local,nasal_gc& gc) int number=(int)val.num(); return {vm_num,(double)number}; } +nasal_ref builtin_floor(nasal_ref* local,nasal_gc& gc) +{ + nasal_ref val=local[1]; + return {vm_num,std::floor(val.num())}; +} nasal_ref builtin_num(nasal_ref* local,nasal_gc& gc) { nasal_ref val=local[1]; diff --git a/nasal_vm.h b/nasal_vm.h index 6952624..556c996 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -797,8 +797,8 @@ inline void nasal_vm::opr_slc2() else if(type1!=vm_nil && type2==vm_nil) num2=num1<0? -1:size-1; - if(num1>=num2) - die("slc2: begin index must be less than end index"); + if(num1>num2) + die("slc2: begin index must be less than or equal to end index"); else if(num1<-size || num1>=size) die("slc2: begin index out of range: "+std::to_string(num1)); else if(num2<-size || num2>=size) diff --git a/stl/lib.nas b/stl/lib.nas index 44c82b0..65a8882 100644 --- a/stl/lib.nas +++ b/stl/lib.nas @@ -60,6 +60,17 @@ var int=func(val){ return __builtin_int(val); } +# floor will get the integral number of input argument +# which is less than or equal to this argument +var floor=func(val){ + return __builtin_floor(val); +} + +# abs gets absolute number +var abs=func(n){ + return n>0?n:-n; +} + # num will change all the other types into number. # mostly used to change a numerable string. var num=func(val){ @@ -105,6 +116,9 @@ var keys=func(hash){ var time=func(begin){ return __builtin_time(begin); } +var systime=func(){ + return time(0); +} # die is a special native function. # use it at where you want the program to crash immediately. @@ -118,6 +132,11 @@ var typeof=func(object){ return __builtin_type(object); } +# subvec is used to get part of a vector +var subvec=func(vec,begin,length=nil){ + return vec[begin:(length==nil?nil:begin+length-1)]; +} + # substr will get the sub-string. # it gets the string, the begin index and sub-string's length as arguments. var substr=func(str,begin,len){ @@ -169,6 +188,45 @@ var println=func(elems...){ return __builtin_print(elems); } +var isfunc=func(f){ + return typeof(f)=="func"; +} + +var isghost=func(g){ + die("this runtime have no ghost object"); + return 0; +} + +var ishash=func(h){ + return typeof(h)=="hash"; +} + +var isint=func(x){ + return x==floor(x); +} + +var isnum=func(x){ + return typeof(x)=="num" or !math.isnan(num(x)); +} + +var isscalar=func(s){ + var t=typeof(s); + return t=="num" or t=="str"; +} + +var isstr=func(s){ + return typeof(s)=="str"; +} + +var isvec=func(v){ + return typeof(v)=="vec"; +} + +var vecindex=func(vec,val){ + # unfinished + return nil; +} + var io= { SEEK_SET:0, diff --git a/test/md5.nas b/test/md5.nas index 59db46f..08c63ea 100644 --- a/test/md5.nas +++ b/test/md5.nas @@ -3,15 +3,15 @@ import("lib.nas"); var check=func(x){ if(x<0x100000000) return x; - return x-int(x/0x100000000)*0x100000000; + return x-floor(x/0x100000000)*0x100000000; } var u32_bits_and=func(x,y){ (x,y)=(check(x),check(y)); var (res,op)=(0,1); for(var i=0;i<32;i+=1){ - var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); + var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2); res+=op*(tmpx==1 and tmpy==1); - (x,y)=(int(x/2),int(y/2)); + (x,y)=(floor(x/2),floor(y/2)); op*=2; } return res; @@ -20,9 +20,9 @@ var u32_bits_or=func(x,y){ (x,y)=(check(x),check(y)); var (res,op)=(0,1); for(var i=0;i<32;i+=1){ - var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); + var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2); res+=op*(tmpx==1 or tmpy==1); - (x,y)=(int(x/2),int(y/2)); + (x,y)=(floor(x/2),floor(y/2)); op*=2; } return res; @@ -31,9 +31,9 @@ var u32_bits_xor=func(x,y){ (x,y)=(check(x),check(y)); var (res,op)=(0,1); for(var i=0;i<32;i+=1){ - var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2); + var (tmpx,tmpy)=(x-floor(x/2)*2,y-floor(y/2)*2); res+=op*(tmpx!=tmpy); - (x,y)=(int(x/2),int(y/2)); + (x,y)=(floor(x/2),floor(y/2)); op*=2; } return res; @@ -42,8 +42,8 @@ var u32_bits_not=func(x){ x=check(x); var (res,op)=(0,1); for(var i=0;i<32;i+=1){ - res+=op*((x-int(x/2)*2)==1?0:1); - x=int(x/2); + res+=op*((x-floor(x/2)*2)==1?0:1); + x=floor(x/2); op*=2; } return res; @@ -61,7 +61,7 @@ var hex32str=func(){ var res=""; for(var i=0;i<4;i+=1){ res~=tbl[u32_bits_and(num,0xff)]; - num=int(num/256); + num=floor(num/256); } return res; }; @@ -103,7 +103,7 @@ var _md5=func(){ for(var i=0;i448){ - var i=size(res); - setsize(res,int(i/512)*512+960); # 512+448=960 - res[i]=1; - for(i+=1;i56){ + res_size=floor(s_size/64)*64+120; # 512+448=960 960/8=120 } + setsize(res,res_size); + res[s_size]=0x80; + for(var i=s_size+1;i0;i-=1){ - tmp[tmp_size-4-i]=int(lower32-int(lower32/256)*256); - lower32=int(lower32/256); + res[s_size-4-i]=floor(lower32-floor(lower32/256)*256); + lower32=floor(lower32/256); } for(var i=4;i>0;i-=1){ - tmp[tmp_size-i]=int(higher32-int(higher32/256)*256); - higher32=int(higher32/256); + res[s_size-i]=floor(higher32-floor(higher32/256)*256); + higher32=floor(higher32/256); } - res=tmp; # 1 block=>16 uint32=>64 byte=>512 bit # because using double to discribe number # this may only work when string's length is under 1<<51 - tmp=[]; + var tmp=[]; setsize(tmp,size(res)/4); for(var i=0;i