123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137(**************************************************************************)(* *)(* Copyright 2011 Jun Furuse *)(* Copyright 2012-2013 OCamlPro *)(* *)(* All rights reserved.This file is distributed under the terms of the *)(* GNU Lesser General Public License version 2.1 with linking *)(* exception. *)(* *)(* TypeRex is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* Lesser GNU General Public License for more details. *)(* *)(**************************************************************************)openPosopenApprox_lexertypetoken={region:Region.t;token:Approx_lexer.token;newlines:int;between:stringLazy.t;substr:stringLazy.t;offset:int;}typecons=|Consoftoken*t|Nullandt=conslazy_tletof_string?(start_pos=Position.zero)?(start_offset=0)string=letlexbuf={Lexing.refill_buff=(funlexbuf->lexbuf.Lexing.lex_eof_reached<-true);lex_buffer=Bytes.of_stringstring;lex_buffer_len=String.lengthstring;lex_abs_pos=start_offset;lex_start_pos=start_offset;lex_curr_pos=start_offset;lex_last_pos=start_offset;lex_last_action=0;lex_mem=[||];lex_eof_reached=true;lex_start_p=start_pos;lex_curr_p=start_pos;}inApprox_lexer.init();letreclooplast=letopenLexinginmatchApprox_lexer.token_with_commentslexbufwith|EOL|SPACES->looplast|token->letpos_last=Region.sndlastandpos_start=lexbuf.lex_start_pandpos_end=lexbuf.lex_curr_pinletregion=Region.createpos_startpos_endinletoffset=Region.start_columnregion-Region.start_columnlastinletspaces=pos_start.pos_cnum-pos_last.pos_cnuminletlen=pos_end.pos_cnum-pos_start.pos_cnuminletnewlines=pos_start.pos_lnum-pos_last.pos_lnuminletbetween=lazy(String.substringpos_last.pos_cnumspaces)inletsubstr=lazy(String.substringpos_start.pos_cnumlen)inCons({region;token;newlines;between;substr;offset},lazy(matchtokenwith|EOF->Null|_->loopregion))inletinit_region=letpos_above={start_poswithLexing.pos_lnum=start_pos.Lexing.pos_lnum-1}inRegion.createpos_abovepos_aboveinlazy(loopinit_region)letof_channel?(start_pos=Position.zero)ic=(* add some caching to the reader function, so that
we can get back the original strings *)letbuf=Buffer.create511inletreaderstrcount=letn=inputicstr0countinBuffer.add_substringbuf(Bytes.to_stringstr)0n;ninletlexbuf=Lexing.from_functionreaderinletlexbuf={lexbufwithLexing.lex_start_p=start_pos;Lexing.lex_curr_p=start_pos;}inApprox_lexer.init();letreclooplast=letopenLexinginmatchApprox_lexer.token_with_commentslexbufwith|EOL|SPACES->looplast|token->letpos_last=Region.sndlastandpos_start=lexbuf.lex_start_pandpos_end=lexbuf.lex_curr_pinletspaces=pos_start.pos_cnum-pos_last.pos_cnuminletlen=pos_end.pos_cnum-pos_start.pos_cnuminletnewlines=pos_start.pos_lnum-pos_last.pos_lnuminletbetween=lets=Buffer.subbuf0spacesinlazysinletsubstr=lets=Buffer.subbufspacesleninlazysinlettotal=pos_end.pos_cnum-pos_last.pos_cnuminletmore=Buffer.subbuftotal(Buffer.lengthbuf-total)inBuffer.clearbuf;Buffer.add_stringbufmore;letregion=Region.createpos_startpos_endinletoffset=Region.start_columnregion-Region.start_columnlastinCons({region;token;newlines;between;substr;offset},lazy(matchtokenwith|EOF->Null|_->loopregion))inletinit_region=letpos_above={start_poswithLexing.pos_lnum=start_pos.Lexing.pos_lnum-1}inRegion.createpos_abovepos_aboveinlazy(loopinit_region)letnext=function|lazyNull->None|lazy(Cons(car,cdr))->Some(car,cdr)