diff --git a/members/lexers/src/assignments/mod.rs b/members/lexers/src/assignments/mod.rs index 3006f23fda89e750d396b63b664255a1813ac71b..0d18025b25dd43ebbc7602abfb2b8568d1aeddd0 100644 --- a/members/lexers/src/assignments/mod.rs +++ b/members/lexers/src/assignments/mod.rs @@ -20,23 +20,31 @@ pub fn assignment_lexer(statement: &str) -> (Option<&str>, Option<Operator>, Opt let as_bytes = statement.as_bytes(); let mut bytes = statement.bytes().peekable(); let mut operator = None; + let mut delimiter_stack = Vec::new(); while let Some(byte) = bytes.next() { operator = Some(Operator::Equal); - if b'=' == byte { - if bytes.peek().is_none() { - return (Some(&statement[..read].trim()), Some(Operator::Equal), None); + + if is_open_delimiter(byte) { + delimiter_stack.push(byte); + } else if delimiter_stack.last().map_or(false, |open| delimiters_match(*open, byte)) { + delimiter_stack.pop(); + } else if delimiter_stack.is_empty() { + if b'=' == byte { + if bytes.peek().is_none() { + return (Some(&statement[..read].trim()), Some(Operator::Equal), None); + } + start = read; + read += 1; + break; } - start = read; - read += 1; - break; - } - if let Some((op, found)) = find_operator(as_bytes, read) { - operator = Some(op); - start = read; - read = found; - break; + if let Some((op, found)) = find_operator(as_bytes, read) { + operator = Some(op); + start = read; + read = found; + break; + } } read += 1; @@ -64,6 +72,15 @@ fn find_operator(bytes: &[u8], read: usize) -> Option<(Operator, usize)> { } } +fn is_open_delimiter(byte: u8) -> bool { byte == b'[' } + +fn delimiters_match(open: u8, close: u8) -> bool { + match (open, close) { + (b'[', b']') => true, + _ => false, + } +} + #[cfg(test)] mod tests { use super::*; @@ -159,4 +176,19 @@ mod tests { (Some("abc"), Some(Operator::Filter), Some("def")) ) } + + #[test] + fn map_assignment() { + assert_eq!(assignment_lexer("abc[=]"), (Some("abc[=]"), None, None)); + + assert_eq!( + assignment_lexer("abc['='] = '='"), + (Some("abc['=']"), Some(Operator::Equal), Some("'='")) + ); + + assert_eq!( + assignment_lexer("abc[=] = []=[]"), + (Some("abc[=]"), Some(Operator::Equal), Some("[]=[]")) + ); + } }