@@ -1118,13 +1118,68 @@ impl<'a> Lexer<'a> {
1118
1118
// Stack
1119
1119
"?" => {
1120
1120
self . end ( Primitive :: Stack , start) ;
1121
- let mut n = 0 ;
1122
1121
let start = self . loc ;
1123
- while self . next_char_exact ( "?" ) {
1124
- n += 1 ;
1122
+
1123
+ fn read_chain ( lexer : & mut Lexer ) -> ( i32 , Loc ) {
1124
+ let mut n = 0 ;
1125
+ let mut before_last = lexer. loc ;
1126
+ loop {
1127
+ let start = lexer. loc ;
1128
+ if lexer. next_char_exact ( "?" ) {
1129
+ n += 1 ;
1130
+ if lexer. peek_char ( ) != Some ( "?" ) {
1131
+ before_last = start;
1132
+ break ;
1133
+ }
1134
+ } else {
1135
+ break ;
1136
+ }
1137
+ }
1138
+ ( n, before_last)
1125
1139
}
1126
- if n > 0 {
1127
- self . end ( Subscr ( Subscript :: numeric ( n) ) , start) ;
1140
+
1141
+ let ( n, before_last_in_chain) = read_chain ( & mut self ) ;
1142
+
1143
+ let subscript = {
1144
+ if self . next_char_exact ( "," ) || self . next_chars_exact ( [ "_" ; 2 ] ) {
1145
+ Some ( self . subscript ( "," ) )
1146
+ } else if self . peek_char ( ) . map_or ( false , is_formatted_subscript) {
1147
+ let init = self . next_char ( ) . unwrap ( ) ;
1148
+ Some ( self . subscript ( init) )
1149
+ } else {
1150
+ None
1151
+ }
1152
+ } ;
1153
+ match subscript {
1154
+ Some ( Subscript {
1155
+ num : Some ( NumericSubscript :: N ( num) ) ,
1156
+ side : None ,
1157
+ } ) => {
1158
+ let ( m, before_last_2nd_chain) = read_chain ( & mut self ) ;
1159
+ let has_2nd_subscript = self . next_char_exact ( "," )
1160
+ || self . next_chars_exact ( [ "_" ; 2 ] )
1161
+ || self . peek_char ( ) . map_or ( false , is_formatted_subscript) ;
1162
+ if !has_2nd_subscript {
1163
+ self . end ( Subscr ( Subscript :: numeric ( n + num + m) ) , start) ;
1164
+ } else {
1165
+ let sub_num = n + num + ( m - 1 ) . max ( 0 ) ;
1166
+ self . loc = before_last_2nd_chain;
1167
+ self . end ( Subscr ( Subscript :: numeric ( sub_num) ) , start) ;
1168
+ }
1169
+ }
1170
+ Some ( _) => {
1171
+ // invalid subscript
1172
+ self . loc = before_last_in_chain;
1173
+ if n > 1 {
1174
+ self . end ( Subscr ( Subscript :: numeric ( n - 1 ) ) , start) ;
1175
+ }
1176
+ }
1177
+ None => {
1178
+ // no subscript
1179
+ if n != 0 {
1180
+ self . end ( Subscr ( Subscript :: numeric ( n) ) , start) ;
1181
+ }
1182
+ }
1128
1183
}
1129
1184
}
1130
1185
// Comments
@@ -1263,7 +1318,7 @@ impl<'a> Lexer<'a> {
1263
1318
}
1264
1319
}
1265
1320
// Formatted subscripts
1266
- c if "₋⌞⌟" . contains ( c ) || c . chars ( ) . all ( |c| SUBSCRIPT_DIGITS . contains ( & c ) ) => {
1321
+ c if is_formatted_subscript ( c ) => {
1267
1322
let sub = self . subscript ( c) ;
1268
1323
self . end ( Subscr ( sub) , start)
1269
1324
}
@@ -1706,6 +1761,10 @@ pub fn is_custom_glyph(c: &str) -> bool {
1706
1761
}
1707
1762
}
1708
1763
1764
+ fn is_formatted_subscript ( c : & str ) -> bool {
1765
+ "₋⌞⌟" . contains ( c) || c. chars ( ) . all ( |c| SUBSCRIPT_DIGITS . contains ( & c) )
1766
+ }
1767
+
1709
1768
pub ( crate ) fn canonicalize_ident ( ident : & str ) -> Ident {
1710
1769
canonicalize_subscripts ( canonicalize_exclams ( ident) )
1711
1770
}
0 commit comments