Add tuple syntax parsing

next
Sayan Nandan 2 years ago
parent 68ed434c96
commit 132633c542
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -24,12 +24,15 @@
*
*/
use std::mem::{discriminant, Discriminant};
use super::lexer::{Lit, Symbol};
use {super::lexer::Token, crate::engine::memory::DataType};
use {
super::lexer::{Lit, Symbol, Token},
crate::engine::memory::DataType,
std::mem::{discriminant, Discriminant},
};
/// Parse a list
///
/// **NOTE:** This function will error if the `[` token is passed. Make sure this is forwarded by the caller
pub(super) fn parse_list(
tok: &[Token],
list: &mut Vec<DataType>,
@ -83,9 +86,63 @@ pub(super) fn parse_list(
#[cfg(test)]
pub(super) fn parse_list_full(tok: &[Token]) -> Option<Vec<DataType>> {
let mut l = Vec::new();
if let (_, _, true) = parse_list(tok, &mut l) {
if matches!(parse_list(tok, &mut l), (_, i, true) if i == tok.len()) {
Some(l)
} else {
None
}
}
#[cfg(test)]
/// Parse the tuple data passed in with an insert query.
///
/// **Note:** Make sure you pass the `(` token
pub(super) fn parse_data_tuple_syntax(tok: &[Token]) -> (Vec<DataType>, usize, bool) {
let l = tok.len();
let mut okay = l != 0;
let mut stop = okay && tok[0] == Token::Symbol(Symbol::TtCloseParen);
let mut i = stop as usize;
let mut data = Vec::new();
while i < l && okay && !stop {
match &tok[i] {
Token::Lit(Lit::Str(s)) => {
data.push(s.to_string().into());
}
Token::Lit(Lit::Num(n)) => {
data.push((*n).into());
}
Token::Lit(Lit::Bool(b)) => {
data.push((*b).into());
}
Token::Symbol(Symbol::TtOpenSqBracket) => {
// ah, a list
let mut l = Vec::new();
let (_, lst_i, lst_okay) = parse_list(&tok[i + 1..], &mut l);
data.push(l.into());
i += lst_i;
okay &= lst_okay;
}
_ => {
okay = false;
break;
}
}
i += 1;
let nx_comma = i < l && tok[i] == Symbol::SymComma;
let nx_csprn = i < l && tok[i] == Symbol::TtCloseParen;
okay &= nx_comma | nx_csprn;
i += okay as usize;
stop = nx_csprn;
}
(data, i, okay && stop)
}
#[cfg(test)]
pub(super) fn parse_data_tuple_syntax_full(tok: &[Token]) -> Option<Vec<DataType>> {
let (ret, cnt, okay) = parse_data_tuple_syntax(tok);
if cnt == tok.len() && okay {
Some(ret)
} else {
None
}
}

@ -1542,7 +1542,7 @@ mod dml_tests {
[1, 2],
[3, 4],
[5, 6],
[7, 8]
[]
]
")
.unwrap();
@ -1553,7 +1553,7 @@ mod dml_tests {
into_array![1, 2],
into_array![3, 4],
into_array![5, 6],
into_array![7, 8]
into_array![]
]
)
}
@ -1563,9 +1563,9 @@ mod dml_tests {
let tok = lex(b"
[
[[1, 1], [2, 2]],
[[3, 3], [4, 4]],
[[], [4, 4]],
[[5, 5], [6, 6]],
[[7, 7], [8, 8]]
[[7, 7], []]
]
")
.unwrap();
@ -1574,11 +1574,92 @@ mod dml_tests {
r.as_slice(),
into_array![
into_array![into_array![1, 1], into_array![2, 2]],
into_array![into_array![3, 3], into_array![4, 4]],
into_array![into_array![], into_array![4, 4]],
into_array![into_array![5, 5], into_array![6, 6]],
into_array![into_array![7, 7], into_array![8, 8]],
into_array![into_array![7, 7], into_array![]],
]
)
}
}
mod tuple_syntax {
use super::*;
use crate::engine::ql::dml::parse_data_tuple_syntax_full;
#[test]
fn tuple_mini() {
let tok = lex(b"()").unwrap();
let r = parse_data_tuple_syntax_full(&tok[1..]).unwrap();
assert_eq!(r, vec![]);
}
#[test]
fn tuple() {
let tok = lex(br#"
(1234, "email@example.com", true)
"#)
.unwrap();
let r = parse_data_tuple_syntax_full(&tok[1..]).unwrap();
assert_eq!(r.as_slice(), into_array![1234, "email@example.com", true]);
}
#[test]
fn tuple_pro() {
let tok = lex(br#"
(
1234,
"email@example.com",
true,
["hello", "world", "and", "the", "universe"]
)
"#)
.unwrap();
let r = parse_data_tuple_syntax_full(&tok[1..]).unwrap();
assert_eq!(
r.as_slice(),
into_array![
1234,
"email@example.com",
true,
into_array!["hello", "world", "and", "the", "universe"]
]
);
}
#[test]
fn tuple_pro_max() {
let tok = lex(br#"
(
1234,
"email@example.com",
true,
[
["h", "hello"],
["w", "world"],
["a", "and"],
["the"],
["universe"],
[]
]
)
"#)
.unwrap();
let r = parse_data_tuple_syntax_full(&tok[1..]).unwrap();
assert_eq!(
r.as_slice(),
into_array![
1234,
"email@example.com",
true,
into_array![
into_array!["h", "hello"],
into_array!["w", "world"],
into_array!["a", "and"],
into_array!["the"],
into_array!["universe"],
into_array![],
]
]
);
}
}
}

Loading…
Cancel
Save