@@ -18,6 +18,9 @@ use unicode_segmentation::UnicodeSegmentation;
1818
1919use crate :: { ast:: PlaceholderOp , ArraySwizzle , Inputs , Primitive , StackSwizzle , WILDCARD_CHAR } ;
2020
21+ /// Subscript digit characters
22+ pub const SUBSCRIPT_NUMS : [ char ; 10 ] = [ '₀' , '₁' , '₂' , '₃' , '₄' , '₅' , '₆' , '₇' , '₈' , '₉' ] ;
23+
2124/// Lex a Uiua source file
2225pub fn lex (
2326 input : & str ,
@@ -793,7 +796,7 @@ impl<'a> Lexer<'a> {
793796 "]" => self . end ( CloseBracket , start) ,
794797 "⟨" => self . end ( OpenAngle , start) ,
795798 "⟩" => self . end ( CloseAngle , start) ,
796- "_" => self . end ( Underscore , start) ,
799+ "_" if self . peek_char ( ) != Some ( "_" ) => self . end ( Underscore , start) ,
797800 "|" => self . end ( Bar , start) ,
798801 ";" => self . end ( Semicolon , start) ,
799802 "-" if self . next_chars_exact ( [ "-" , "-" ] ) => self . end ( TripleMinus , start) ,
@@ -1002,12 +1005,28 @@ impl<'a> Lexer<'a> {
10021005 }
10031006 }
10041007 // Identifiers and unformatted glyphs
1005- c if is_custom_glyph ( c) || c. chars ( ) . all ( is_ident_char) || c == "&" => {
1008+ c if is_custom_glyph ( c) || c. chars ( ) . all ( is_ident_char) || c == "&" || c == "_" => {
10061009 let mut ident = c. to_string ( ) ;
10071010 // Collect characters
10081011 if !is_custom_glyph ( c) {
1009- while let Some ( c) = self . next_char_if_all ( is_ident_char) {
1010- ident. push_str ( c) ;
1012+ // Handle identifiers beginning with __
1013+ if c == "_" && self . next_char_exact ( "_" ) {
1014+ ident. push_str ( "__" ) ;
1015+ while let Some ( dc) = self . next_char_if_all ( |c| c. is_ascii_digit ( ) ) {
1016+ ident. push_str ( dc) ;
1017+ }
1018+ }
1019+ loop {
1020+ if let Some ( c) = self . next_char_if_all ( is_ident_char) {
1021+ ident. push_str ( c) ;
1022+ } else if self . next_chars_exact ( [ "_" ; 2 ] ) {
1023+ ident. push_str ( "__" ) ;
1024+ while let Some ( dc) = self . next_char_if_all ( |c| c. is_ascii_digit ( ) ) {
1025+ ident. push_str ( dc) ;
1026+ }
1027+ } else {
1028+ break ;
1029+ }
10111030 }
10121031 }
10131032 let mut exclam_count = 0 ;
@@ -1376,7 +1395,7 @@ fn parse_format_fragments(s: &str) -> Vec<String> {
13761395
13771396/// Whether a character can be part of a Uiua identifier
13781397pub fn is_ident_char ( c : char ) -> bool {
1379- c. is_alphabetic ( ) && !"ⁿₙπτηℂλ" . contains ( c)
1398+ c. is_alphabetic ( ) && !"ⁿₙπτηℂλ" . contains ( c) || SUBSCRIPT_NUMS . contains ( & c )
13801399}
13811400
13821401/// Whether a string is a custom glyph
0 commit comments