diff --git a/src/handlers.rs b/src/handlers.rs index 6abdd73..200ff1b 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -34,18 +34,23 @@ impl crate::Lexer { pub fn consume_number(&mut self) -> crate::Token { let mut number = String::new(); let mut is_float = false; + let mut is_swizzle = false; while let Some(c) = self.current_char { if c.is_digit(10) { number.push(c); self.advance(); - } else if c == '.' { + } else if c == '.' && self.peek().map_or(false, |c| c.is_digit(10)) + || self.peek() == Some('f') + { if number.is_empty() { number.push('0'); } number.push(c); is_float = true; self.advance(); + } else if c.is_alphabetic() { + is_swizzle = true; } else { break; } diff --git a/src/lib.rs b/src/lib.rs index 292ad1c..e6d2db8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,6 +83,20 @@ impl Lexer { } /// Parses the source given the [`Lexer`] upon initialization and returns a vector of [`Token`]. + /// # Example: + /// ``` + /// use glsl_lexer::*; + /// let source = r#" + /// #version 440 + /// uniform float time; + /// void main() { + /// gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0); + /// } + /// "#; + /// let mut lexer = glsl_lexer::Lexer::new(&source); + /// let tokens = lexer.get_tokens(); + /// dbg!("{}", tokens); + /// ``` pub fn get_tokens(&mut self) -> Vec { let mut tokens = Vec::new(); while let Some(c) = self.current_char { @@ -101,9 +115,11 @@ impl Lexer { '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '!' | '=' | '<' | '>' | '?' => { tokens.push(self.consume_operator()); } + '{' | '}' | '(' | ')' | '#' | ',' | ';' => { tokens.push(self.consume_symbol()); } + '.' => { tokens.push(self.consume_number()); } @@ -225,6 +241,24 @@ mod tests { assert_eq!(tokens, vec![Token::FloatLiteral(0.4504), Token::EOF]); } + #[test] + fn test_swizzling() { + init(); + let source_code = "abcd.xyz"; + let mut lexer = Lexer::new(source_code); + let tokens = lexer.get_tokens(); + info!("[Swizzling] Tokens: {:#?}", tokens); + assert_eq!( + tokens, + vec![ + Token::Identifier("abcd".to_string()), + Token::Symbol('.'), + Token::Identifier("xyz".to_string()), + Token::EOF + ] + ); + } + #[test] fn test_operator() { init();