123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141modulePosition=struct(* We encode the position in three, 21 bit fields: [cnum][lnum][bol] *)typet=intletfield_size=21letfield_mask=(1lslfield_size)-1letshift_bol=0letshift_lnum=field_sizeletshift_cnum=2*field_sizeletsmall_enough=letmax_size=1lslfield_sizeinlettestint=int<=max_sizeinfun[@inline]{Lexing.pos_bol;pos_cnum;pos_lnum;pos_fname=_}->testpos_bol&&testpos_cnum&&testpos_lnum;;let[@inline]of_position{Lexing.pos_bol;pos_cnum;pos_lnum;pos_fname=_}=((pos_bollandfield_mask)lslshift_bol)lor((pos_lnumlandfield_mask)lslshift_lnum)lor((pos_cnumlandfield_mask)lslshift_cnum);;let[@inline]bolt=(tlsrshift_bol)landfield_masklet[@inline]lnumt=(tlsrshift_lnum)landfield_masklet[@inline]cnumt=(tlsrshift_cnum)landfield_maskletto_positiont~fname:pos_fname=letpos_bol=boltinletpos_cnum=cnumtinletpos_lnum=lnumtin{Lexing.pos_bol;pos_cnum;pos_lnum;pos_fname};;endmoduleSame_line_loc=struct(* we encode the location in four, 15 bit chunks
[bol][lnum][start_cnum][stop_cnum]
Note that this leaves us with 3 spare bits. We should probably use them to
expand [bol] and [lnum] a little.
CR-someday jtov: Instead of [stop_cnum], we can store [stop_cnum -
start_cnum]. This should be smaller than [stop_cnum] and release more
bits for other fields.
*)typet=intletfield_size=15letfield_mask=(1lslfield_size)-1letshift_bol=0letshift_lnum=field_sizeletshift_start_cnum=2*field_sizeletshift_stop_cnum=3*field_sizeletcreate~bol~lnum~start_cnum~stop_cnum=((bollandfield_mask)lslshift_bol)lor((lnumlandfield_mask)lslshift_lnum)lor((start_cnumlandfield_mask)lslshift_start_cnum)lor((stop_cnumlandfield_mask)lslshift_stop_cnum);;let[@inline]bolt=(tlsrshift_bol)landfield_masklet[@inline]lnumt=(tlsrshift_lnum)landfield_masklet[@inline]start_cnumt=(tlsrshift_start_cnum)landfield_masklet[@inline]stop_cnumt=(tlsrshift_stop_cnum)landfield_maskletset_start_to_stopt=letbol=boltinletlnum=lnumtinletstop_cnum=stop_cnumtin(* this can be optimized more if necessary *)create~bol~lnum~start_cnum:stop_cnum~stop_cnum;;letsmall_enough=letmax_size=1lslfield_sizeinfun[@inline]int->int<=max_size;;let[@inline]to_loct~fname:pos_fname=letpos_lnum=lnumtinletpos_bol=boltinletstart={Lexing.pos_fname;pos_lnum;pos_bol;pos_cnum=start_cnumt}inletstop={startwithpos_cnum=stop_cnumt}in{Lexbuf.Loc.start;stop};;let[@inline]startt~fname:pos_fname=letpos_lnum=lnumtinletpos_bol=boltin{Lexing.pos_fname;pos_lnum;pos_bol;pos_cnum=start_cnumt};;let[@inline]stopt~fname:pos_fname=letpos_lnum=lnumtinletpos_bol=boltin{Lexing.pos_fname;pos_lnum;pos_bol;pos_cnum=stop_cnumt};;endincludePositiontypeof_loc=|Same_lineofSame_line_loc.t|Locof{start:t;stop:t}|Loc_does_not_fitlet[@inline]try_loc{Lexbuf.Loc.start;stop}=ifPosition.small_enoughstart&&Position.small_enoughstopthen(letstart=Position.of_positionstartinletstop=Position.of_positionstopinLoc{start;stop})elseLoc_does_not_fit;;let[@inline]of_loc({Lexbuf.Loc.start;stop}asloc)=ifstart.pos_fname<>stop.pos_fnamethenLoc_does_not_fitelseifstart.pos_bol=stop.pos_bol&&start.pos_lnum=stop.pos_lnumthen(letbol=start.pos_bolinletlnum=start.pos_lnuminletstart_cnum=start.pos_cnuminletstop_cnum=stop.pos_cnuminlettest=Same_line_loc.small_enoughiniftestbol&&testlnum&&teststart_cnum&&teststop_cnumthenSame_line(Same_line_loc.create~bol~lnum~start_cnum~stop_cnum)elsetry_locloc)elsetry_locloc;;letof_loc=ifSys.int_size=63thenof_locelsefun_->Loc_does_not_fitmoduleFor_tests=structletsmall_enough=small_enoughend