@@ -196,24 +196,50 @@ where
196196 '=' => {
197197 let tok_start = self . get_pos ( ) ;
198198 let _ = self . next_char ( ) ;
199- match self . chr0 {
200- Some ( '=' ) => {
201- let _ = self . next_char ( ) ;
202- let tok_end = self . get_pos ( ) ;
203- if let Some ( '=' ) = self . chr0 {
204- return Err ( LexicalError {
205- error : LexicalErrorType :: InvalidTripleEqual ,
206- location : SrcSpan {
207- start : tok_start,
208- end : tok_end + 1 ,
209- } ,
210- } ) ;
211- }
212- self . emit ( ( tok_start, Token :: EqualEqual , tok_end) ) ;
199+
200+ if self . chr0 != Some ( '=' ) {
201+ let tok_end = self . get_pos ( ) ;
202+ self . emit ( ( tok_start, Token :: Equal , tok_end) ) ;
203+ return Ok ( ( ) ) ;
204+ }
205+
206+ let _ = self . next_char ( ) ;
207+
208+ if self . chr0 != Some ( '=' ) {
209+ self . emit ( ( tok_start, Token :: EqualEqual , self . get_pos ( ) ) ) ;
210+ return Ok ( ( ) ) ;
211+ }
212+
213+ let _ = self . next_char ( ) ;
214+ let mut seen_eq = 3 ;
215+
216+ loop {
217+ if seen_eq >= 7 {
218+ return Err ( LexicalError {
219+ error : LexicalErrorType :: MergeConflictIndicator ,
220+ location : SrcSpan {
221+ start : tok_start,
222+ end : self . get_pos ( ) ,
223+ } ,
224+ } ) ;
213225 }
214- _ => {
215- let tok_end = self . get_pos ( ) ;
216- self . emit ( ( tok_start, Token :: Equal , tok_end) ) ;
226+
227+ if self . chr0 == Some ( '=' ) {
228+ let _ = self . next_char ( ) ;
229+ seen_eq += 1 ;
230+ } else {
231+ // we've found at least three `=`s, but not
232+ // enough to be a merge conflict indicator,
233+ // so we just return the triple equals error
234+ //
235+ // TODO: provide a better error for 3 < '='s < 7
236+ return Err ( LexicalError {
237+ error : LexicalErrorType :: InvalidTripleEqual ,
238+ location : SrcSpan {
239+ start : tok_start,
240+ end : tok_start + 3 ,
241+ } ,
242+ } ) ;
217243 }
218244 }
219245 }
@@ -353,84 +379,8 @@ where
353379 ':' => {
354380 self . eat_single_char ( Token :: Colon ) ;
355381 }
356- '<' => {
357- let tok_start = self . get_pos ( ) ;
358- let _ = self . next_char ( ) ;
359- match self . chr0 {
360- Some ( '>' ) => {
361- let _ = self . next_char ( ) ;
362- let tok_end = self . get_pos ( ) ;
363- self . emit ( ( tok_start, Token :: Concatenate , tok_end) ) ;
364- }
365- Some ( '<' ) => {
366- let _ = self . next_char ( ) ;
367- let tok_end = self . get_pos ( ) ;
368- self . emit ( ( tok_start, Token :: LtLt , tok_end) ) ;
369- }
370- Some ( '.' ) => {
371- let _ = self . next_char ( ) ;
372- let tok_end = self . get_pos ( ) ;
373- self . emit ( ( tok_start, Token :: LessDot , tok_end) ) ;
374- }
375- Some ( '-' ) => {
376- let _ = self . next_char ( ) ;
377- let tok_end = self . get_pos ( ) ;
378- self . emit ( ( tok_start, Token :: LArrow , tok_end) ) ;
379- }
380- Some ( '=' ) => {
381- let _ = self . next_char ( ) ;
382- match self . chr0 {
383- Some ( '.' ) => {
384- let _ = self . next_char ( ) ;
385- let tok_end = self . get_pos ( ) ;
386- self . emit ( ( tok_start, Token :: LessEqualDot , tok_end) ) ;
387- }
388- _ => {
389- let tok_end = self . get_pos ( ) ;
390- self . emit ( ( tok_start, Token :: LessEqual , tok_end) ) ;
391- }
392- }
393- }
394- _ => {
395- let tok_end = self . get_pos ( ) ;
396- self . emit ( ( tok_start, Token :: Less , tok_end) ) ;
397- }
398- }
399- }
400- '>' => {
401- let tok_start = self . get_pos ( ) ;
402- let _ = self . next_char ( ) ;
403- match self . chr0 {
404- Some ( '>' ) => {
405- let _ = self . next_char ( ) ;
406- let tok_end = self . get_pos ( ) ;
407- self . emit ( ( tok_start, Token :: GtGt , tok_end) ) ;
408- }
409- Some ( '.' ) => {
410- let _ = self . next_char ( ) ;
411- let tok_end = self . get_pos ( ) ;
412- self . emit ( ( tok_start, Token :: GreaterDot , tok_end) ) ;
413- }
414- Some ( '=' ) => {
415- let _ = self . next_char ( ) ;
416- match self . chr0 {
417- Some ( '.' ) => {
418- let _ = self . next_char ( ) ;
419- let tok_end = self . get_pos ( ) ;
420- self . emit ( ( tok_start, Token :: GreaterEqualDot , tok_end) ) ;
421- }
422- _ => {
423- let tok_end = self . get_pos ( ) ;
424- self . emit ( ( tok_start, Token :: GreaterEqual , tok_end) ) ;
425- }
426- }
427- }
428- _ => {
429- let tok_end = self . get_pos ( ) ;
430- self . emit ( ( tok_start, Token :: Greater , tok_end) ) ;
431- }
432- }
433- }
382+ '<' => return self . lex_lt ( ) ,
383+ '>' => return self . lex_gt ( ) ,
434384 ',' => {
435385 self . eat_single_char ( Token :: Comma ) ;
436386 }
@@ -838,6 +788,158 @@ where
838788 Ok ( ( ) )
839789 }
840790
791+ // Once we've found a `<`, proceed from there
792+ fn lex_lt ( & mut self ) -> Result < ( ) , LexicalError > {
793+ let mut tok_start = self . get_pos ( ) ;
794+ let _ = self . next_char ( ) ;
795+ match self . chr0 {
796+ Some ( '>' ) => {
797+ let _ = self . next_char ( ) ;
798+ let tok_end = self . get_pos ( ) ;
799+ self . emit ( ( tok_start, Token :: Concatenate , tok_end) ) ;
800+ }
801+ Some ( '<' ) => {
802+ let _ = self . next_char ( ) ;
803+
804+ if self . chr0 != Some ( '<' ) {
805+ self . emit ( ( tok_start, Token :: LtLt , self . get_pos ( ) ) ) ;
806+ return Ok ( ( ) ) ;
807+ }
808+
809+ let _ = self . next_char ( ) ;
810+ let mut seen_lt = 3 ;
811+
812+ loop {
813+ if seen_lt >= 7 {
814+ return Err ( LexicalError {
815+ error : LexicalErrorType :: MergeConflictIndicator ,
816+ location : SrcSpan {
817+ start : tok_start,
818+ end : self . get_pos ( ) ,
819+ } ,
820+ } ) ;
821+ }
822+
823+ if self . chr0 == Some ( '<' ) {
824+ let _ = self . next_char ( ) ;
825+ seen_lt += 1 ;
826+ } else {
827+ while seen_lt > 1 {
828+ self . emit ( ( tok_start, Token :: LtLt , tok_start + 2 ) ) ;
829+ tok_start += 2 ;
830+ seen_lt -= 2 ;
831+ }
832+ if seen_lt == 1 {
833+ return self . lex_lt ( ) ;
834+ } else {
835+ return Ok ( ( ) ) ;
836+ }
837+ }
838+ }
839+ }
840+ Some ( '.' ) => {
841+ let _ = self . next_char ( ) ;
842+ let tok_end = self . get_pos ( ) ;
843+ self . emit ( ( tok_start, Token :: LessDot , tok_end) ) ;
844+ }
845+ Some ( '-' ) => {
846+ let _ = self . next_char ( ) ;
847+ let tok_end = self . get_pos ( ) ;
848+ self . emit ( ( tok_start, Token :: LArrow , tok_end) ) ;
849+ }
850+ Some ( '=' ) => {
851+ let _ = self . next_char ( ) ;
852+ match self . chr0 {
853+ Some ( '.' ) => {
854+ let _ = self . next_char ( ) ;
855+ let tok_end = self . get_pos ( ) ;
856+ self . emit ( ( tok_start, Token :: LessEqualDot , tok_end) ) ;
857+ }
858+ _ => {
859+ let tok_end = self . get_pos ( ) ;
860+ self . emit ( ( tok_start, Token :: LessEqual , tok_end) ) ;
861+ }
862+ }
863+ }
864+ _ => {
865+ let tok_end = self . get_pos ( ) ;
866+ self . emit ( ( tok_start, Token :: Less , tok_end) ) ;
867+ }
868+ }
869+ Ok ( ( ) )
870+ }
871+
872+ // once we've found a `>`
873+ fn lex_gt ( & mut self ) -> Result < ( ) , LexicalError > {
874+ let mut tok_start = self . get_pos ( ) ;
875+ let _ = self . next_char ( ) ;
876+ match self . chr0 {
877+ Some ( '>' ) => {
878+ let _ = self . next_char ( ) ;
879+ let tok_end = self . get_pos ( ) ;
880+
881+ if self . chr0 != Some ( '>' ) {
882+ self . emit ( ( tok_start, Token :: GtGt , tok_end) ) ;
883+ return Ok ( ( ) ) ;
884+ }
885+
886+ let _ = self . next_char ( ) ;
887+ let mut seen_gt = 3 ;
888+
889+ loop {
890+ if seen_gt >= 7 {
891+ return Err ( LexicalError {
892+ error : LexicalErrorType :: MergeConflictIndicator ,
893+ location : SrcSpan {
894+ start : tok_start,
895+ end : self . get_pos ( ) ,
896+ } ,
897+ } ) ;
898+ }
899+
900+ if self . chr0 == Some ( '>' ) {
901+ let _ = self . next_char ( ) ;
902+ seen_gt += 1 ;
903+ } else {
904+ while seen_gt > 1 {
905+ self . emit ( ( tok_start, Token :: GtGt , tok_start + 2 ) ) ;
906+ tok_start += 2 ;
907+ seen_gt -= 2 ;
908+ }
909+ if seen_gt > 0 {
910+ return self . lex_lt ( ) ;
911+ } else {
912+ return Ok ( ( ) ) ;
913+ }
914+ }
915+ }
916+ }
917+ Some ( '.' ) => {
918+ let _ = self . next_char ( ) ;
919+ let tok_end = self . get_pos ( ) ;
920+ self . emit ( ( tok_start, Token :: GreaterDot , tok_end) ) ;
921+ }
922+ Some ( '=' ) => {
923+ let _ = self . next_char ( ) ;
924+ match self . chr0 {
925+ Some ( '.' ) => {
926+ let _ = self . next_char ( ) ;
927+ let tok_end = self . get_pos ( ) ;
928+ self . emit ( ( tok_start, Token :: GreaterEqualDot , tok_end) ) ;
929+ }
930+ _ => {
931+ let tok_end = self . get_pos ( ) ;
932+ self . emit ( ( tok_start, Token :: GreaterEqual , tok_end) ) ;
933+ }
934+ }
935+ }
936+ _ => {
937+ let tok_end = self . get_pos ( ) ;
938+ self . emit ( ( tok_start, Token :: Greater , tok_end) ) ;
939+ }
940+ }
941+ return Ok ( ( ) ) ;
942+ }
841943 // Lexer helper functions:
842944 // this can be either a reserved word, or a name
843945 fn lex_name ( & mut self ) -> LexResult {
0 commit comments