@@ -10,8 +10,9 @@ use std::ops::RangeInclusive;
1010
1111pub fn line_is_valid ( line : & str ) -> bool {
1212 let line = line. trim ( ) ;
13- let first_is_alphanumeric = line. chars ( ) . next ( ) . map ( |x| x. is_alphanumeric ( ) ) . unwrap_or ( false ) ;
14- let second_is_measure_sep = line. as_bytes ( ) . get ( 1 ) . map ( |x| * x == b'|' ) . unwrap_or ( false ) ;
13+ let mut chars = line. chars ( ) ;
14+ let first_is_alphanumeric = chars. next ( ) . map ( |x| x. is_alphanumeric ( ) ) . unwrap_or ( false ) ;
15+ let second_is_measure_sep = chars. next ( ) . map ( |x| x == '|' ) . unwrap_or ( false ) ;
1516 let last_is_measure_end = line. ends_with ( '|' ) ;
1617 let ret = first_is_alphanumeric && second_is_measure_sep && last_is_measure_end;
1718 traceln ! ( "line_is_valid({line}) -> {ret}" ) ;
@@ -76,19 +77,17 @@ impl ParseResult {
7677pub fn parse ( lines : & [ String ] ) -> ParseResult {
7778 let mut r = ParseResult :: new ( ) ;
7879 let mut part_first_line = 0 ;
79- while part_first_line + 5 < lines . len ( ) {
80+ ' outer : loop {
8081 // find a part
81- while part_first_line + 5 < lines. len ( ) {
82+ loop {
83+ if part_first_line + 5 >= lines. len ( ) {
84+ break ' outer;
85+ }
8286 if line_is_valid ( & lines[ part_first_line] ) && line_is_valid ( & lines[ part_first_line + 5 ] )
8387 {
8488 break ;
8589 }
86- part_first_line += 1 ;
87- }
88- // hack: the loop above will fail if there is extra content after the last part, so we just exit out here
89- if part_first_line + 5 >= lines. len ( ) {
90- traceln ! ( "extra content after last part, shutdown" ) ;
91- break ;
90+ part_first_line += 1
9291 }
9392 traceln ! ( "parse3: Found part {part_first_line}..={}" , part_first_line + 5 ) ;
9493 r. offsets . push ( ( part_first_line as u32 , r. tick_stream . len ( ) as u32 ) ) ;
@@ -102,14 +101,12 @@ pub fn parse(lines: &[String]) -> ParseResult {
102101 // parse prelude and last char
103102 for ( line_idx, line) in part. iter_mut ( ) . enumerate ( ) {
104103 let Ok ( ( rem, string_name) ) = string_name ( ) ( line) else {
105- r. error =
106- Some ( BackendError :: parse3_invalid_string_name ( part_first_line + line_idx) ) ;
104+ r. error = Some ( BackendError :: invalid_string_name ( part_first_line + line_idx) ) ;
107105 return r;
108106 } ;
109107 r. base_notes . push ( string_name) ;
110108 let Ok ( ( rem, _) ) = super :: char ( '|' ) ( rem) else {
111- r. error =
112- Some ( BackendError :: parse3_invalid_string_name ( part_first_line + line_idx) ) ;
109+ r. error = Some ( BackendError :: invalid_string_name ( part_first_line + line_idx) ) ;
113110 return r;
114111 } ;
115112 * line = rem;
@@ -147,9 +144,8 @@ pub fn parse(lines: &[String]) -> ParseResult {
147144 if let Some ( TabElementError :: FretTooLarge ) = err {
148145 r. error = Some ( BackendError :: large_fret ( line, char) ) ;
149146 } else {
150- let invalid_src = part[ s] . chars ( ) . next ( ) . unwrap_or ( '\0' ) ; // TODO: do not use null byte here
151- let err =
152- BackendError :: parse3_invalid_character ( line, char, invalid_src) ;
147+ let invalid_src = part[ s] . chars ( ) . next ( ) ;
148+ let err = BackendError :: invalid_character ( line, char, invalid_src) ;
153149 r. error = Some ( err) ;
154150 }
155151 return r;
@@ -176,7 +172,8 @@ pub fn parse(lines: &[String]) -> ParseResult {
176172 if let TabElement :: Rest = elem {
177173 traceln ! ( depth = 2 , "this is a rest so we try to parse the next element" ) ;
178174 let len_before = part[ s] . len ( ) ;
179- let next = tab_element3 ( part[ s] ) . unwrap ( ) ;
175+ let next = tab_element3 ( part[ s] ) . unwrap ( ) ; // TODO: the unwrap here is ICE,
176+ // should error instead
180177 if len_before - next. 0 . len ( ) > 1 {
181178 let ( m_line, m_char) = source_location_from_stream ( & r, elem_idx as u32 ) ;
182179 // just for a nicer error, show another multi line too
@@ -186,14 +183,10 @@ pub fn parse(lines: &[String]) -> ParseResult {
186183 Some ( BackendError :: both_slots_multichar ( m_line, m_char, other) ) ;
187184 return r;
188185 }
186+ traceln ! ( depth = 1 , "replaced this Rest with {:?}" , next. 1 ) ;
189187 let len = r. tick_stream . len ( ) ; // to make the borrow checker happy about borrowing &mut and &
190188 r. tick_stream [ len - ( 6 - s) ] = next. 1 ;
191189 part[ s] = next. 0 ;
192- traceln ! (
193- depth = 1 ,
194- "replaced this Rest with {:?}" ,
195- r. tick_stream[ r. tick_stream. len( ) - ( 6 - s) ]
196- ) ;
197190 } else {
198191 traceln ! ( depth = 2 , "this is not a Rest, so we check the next element" ) ;
199192 if part[ s] . starts_with ( "-" ) {
@@ -224,6 +217,7 @@ pub fn parse(lines: &[String]) -> ParseResult {
224217 r
225218}
226219
220+ /// A specialized, faster [source_location_from_stream]
227221pub fn source_location_while_parsing (
228222 r : & ParseResult , part_first_line : u32 , line_in_part : u32 ,
229223) -> ( u32 , u32 ) {
0 commit comments