123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163typet=Int32.tletnum_bits_=ref0letset_num_bitsx=num_bits_:=xletnum_bits()=match!num_bits_with|(31|32)asx->x|x->failwith(Printf.sprintf"Targetint.num_bits %d unsupported"x)typeoffset=Offsetofint[@@ocaml.unboxed]let()=assert(Obj.is_int(Obj.repr(Offset0)))letoffset()=Offset(32-num_bits())letequal=Int32.equalletcompare=Int32.compareletwrap(Offsetoffset)i=Int32.(shift_leftioffset)letunwrap(Offsetoffset)i=Int32.(shift_rightioffset)letwrap_moduloi=letoffset=offset()inunwrapoffset(wrapoffseti)letmax_int_(Offsetoffset)=Int32.shift_rightInt32.max_intoffsetletmin_int_(Offsetoffset)=Int32.shift_rightInt32.min_intoffsetletmin_int()=letoffset=offset()inmin_int_offsetletmax_int()=letoffset=offset()inmax_int_offsetletto_stringx=Int32.to_stringxletto_floatx=Int32.to_floatxletto_int32x=xletto_int_exnx=ifSys.int_size>=32||Int32.of_intInt.min_int<=x||x<=Int32.of_intInt.max_intthenInt32.to_intxelsefailwith"to_int_exn"letnegx=letoffset=offset()inunwrapoffset(Int32.neg(wrapoffsetx))letabsx=letoffset=offset()inunwrapoffset(Int32.abs(wrapoffsetx))letint_binopfxy=wrap_modulo(fxy)letadd=int_binopInt32.addletzero=0lletone=1lletsuccx=addxoneletsub=int_binopInt32.subletmul=int_binopInt32.mulletdiv=int_binopInt32.divletrem=int_binopInt32.remletlogand=int_binopInt32.logandletlogor=int_binopInt32.logorletlogxor=int_binopInt32.logxorletshift_opfxy=letoffset=offset()in(* Limit the shift offset to [0, 31], this works for both 31 and 32
bit integers *)unwrapoffset(f(wrapoffsetx)(yland0x1f))letshift_left=shift_opInt32.shift_leftletshift_right=shift_opInt32.shift_rightletshift_right_logical=shift_opInt32.shift_right_logicalletis_zerox=equalx0lletof_int_exn(x:int)=letoffset=offset()inifSys.int_size<=32||(Int32.to_int(min_int_offset)<=x&&x<=Int32.to_int(max_int_offset))thenInt32.of_intxelsefailwith(Printf.sprintf"of_int_exn(%d)"x)letof_int32_exn(x:int32)=letoffset=offset()inifmin_int_offset<=x&&x<=max_int_offsetthenxelsefailwith"of_int32_exn"letof_string_exnx=tryletoffset=offset()inletx32=Int32.of_stringxinifmin_int_offset<=x32||x32<=max_int_offsetthenx32elseraiseNot_foundwithNot_found|_->failwith(Printf.sprintf"Targetint.of_string_exn(%s)"x)letof_float_optx=letoffset=offset()inifInt32.to_float(min_int_offset)<=x||x<=Int32.to_float(max_int_offset)thenSome(wrap_modulo(Int32.of_floatx))elseNoneletof_int_warning_on_overflowi=Stdlib.Int32.convert_warning_on_overflow"integer"~to_int32:(funi->wrap_modulo(Int32.of_inti))~of_int32:Int32.to_int~equal:Int.equal~to_dec:(Printf.sprintf"%d")~to_hex:(Printf.sprintf"%x")iletof_int32_warning_on_overflown=Stdlib.Int32.convert_warning_on_overflow"int32"~to_int32:(funi->wrap_moduloi)~of_int32:Fun.id~equal:Int32.equal~to_dec:(Printf.sprintf"%ld")~to_hex:(Printf.sprintf"%lx")nletof_nativeint_warning_on_overflown=Stdlib.Int32.convert_warning_on_overflow"native integer"~to_int32:(funi->wrap_modulo(Nativeint.to_int32i))~of_int32:Nativeint.of_int32~equal:Nativeint.equal~to_dec:(Printf.sprintf"%nd")~to_hex:(Printf.sprintf"%nx")nexternal(<):int32->int32->bool="%lessthan"external(<=):int32->int32->bool="%lessequal"external(<>):int32->int32->bool="%notequal"external(=):int32->int32->bool="%equal"external(>):int32->int32->bool="%greaterthan"external(>=):int32->int32->bool="%greaterequal"