This commit is contained in:
Sebastian Schmidt 2019-03-15 19:22:14 +02:00
parent bb74bee382
commit 406bfe0e05
5 changed files with 46 additions and 42 deletions

View File

@ -60,7 +60,7 @@ impl Error {
} }
pub fn unmatched_partial_token(first: PartialToken, second: Option<PartialToken>) -> Self { pub fn unmatched_partial_token(first: PartialToken, second: Option<PartialToken>) -> Self {
Error::UnmatchedPartialToken {first, second} Error::UnmatchedPartialToken { first, second }
} }
} }

View File

@ -92,7 +92,10 @@ mod test {
#[test] #[test]
fn test_boolean_examples() { fn test_boolean_examples() {
assert_eq!(eval("true && false"), Ok(Value::Boolean(false))); assert_eq!(eval("true && false"), Ok(Value::Boolean(false)));
assert_eq!(eval("true && false || true && true"), Ok(Value::Boolean(true))); assert_eq!(
eval("true && false || true && true"),
Ok(Value::Boolean(true))
);
assert_eq!(eval("5 > 4 && 1 <= 1"), Ok(Value::Boolean(true))); assert_eq!(eval("5 > 4 && 1 <= 1"), Ok(Value::Boolean(true)));
assert_eq!(eval("5.0 <= 4.9 || !(4 > 3.5)"), Ok(Value::Boolean(false))); assert_eq!(eval("5.0 <= 4.9 || !(4 > 3.5)"), Ok(Value::Boolean(false)));
} }

View File

@ -400,11 +400,11 @@ impl Operator for And {
let a = expect_boolean(&arguments[0])?; let a = expect_boolean(&arguments[0])?;
let b = expect_boolean(&arguments[1])?; let b = expect_boolean(&arguments[1])?;
if a && b { if a && b {
Ok(Value::Boolean(true)) Ok(Value::Boolean(true))
} else { } else {
Ok(Value::Boolean(false)) Ok(Value::Boolean(false))
} }
} }
} }

View File

@ -1,5 +1,5 @@
use value::{FloatType, IntType};
use error::Error; use error::Error;
use value::{FloatType, IntType};
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum Token { pub enum Token {
@ -139,7 +139,10 @@ fn resolve_literals(mut tokens: &[PartialToken]) -> Result<Vec<Token>, Error> {
let mut cutoff = 2; let mut cutoff = 2;
result.push(match first { result.push(match first {
PartialToken::Token(token) => {cutoff = 1; token}, PartialToken::Token(token) => {
cutoff = 1;
token
}
PartialToken::Literal(literal) => { PartialToken::Literal(literal) => {
cutoff = 1; cutoff = 1;
if let Ok(number) = literal.parse::<IntType>() { if let Ok(number) = literal.parse::<IntType>() {
@ -151,42 +154,39 @@ fn resolve_literals(mut tokens: &[PartialToken]) -> Result<Vec<Token>, Error> {
} else { } else {
Token::Identifier(literal.to_string()) Token::Identifier(literal.to_string())
} }
}
PartialToken::Eq => match second {
Some(PartialToken::Eq) => Token::Eq,
_ => return Err(Error::unmatched_partial_token(first, second)),
}, },
PartialToken::Eq => { PartialToken::ExclamationMark => match second {
match second { Some(PartialToken::Eq) => Token::Eq,
Some(PartialToken::Eq) => Token::Eq, _ => {
_ => return Err(Error::unmatched_partial_token(first, second)), cutoff = 1;
Token::Not
} }
}, },
PartialToken::ExclamationMark => { PartialToken::Gt => match second {
match second { Some(PartialToken::Eq) => Token::Geq,
Some(PartialToken::Eq) => Token::Eq, _ => {
_ => {cutoff = 1; Token::Not}, cutoff = 1;
Token::Gt
} }
}, },
PartialToken::Gt => { PartialToken::Lt => match second {
match second { Some(PartialToken::Eq) => Token::Leq,
Some(PartialToken::Eq) => Token::Geq, _ => {
_ => {cutoff = 1; Token::Gt}, cutoff = 1;
Token::Lt
} }
}, },
PartialToken::Lt => { PartialToken::Ampersand => match second {
match second { Some(PartialToken::Ampersand) => Token::And,
Some(PartialToken::Eq) => Token::Leq, _ => return Err(Error::unmatched_partial_token(first, second)),
_ => {cutoff = 1; Token::Lt},
}
}, },
PartialToken::Ampersand => { PartialToken::VerticalBar => match second {
match second { Some(PartialToken::VerticalBar) => Token::Or,
Some(PartialToken::Ampersand) => Token::And, _ => return Err(Error::unmatched_partial_token(first, second)),
_ => return Err(Error::unmatched_partial_token(first, second)),
}
},
PartialToken::VerticalBar => {
match second {
Some(PartialToken::VerticalBar) => Token::Or,
_ => return Err(Error::unmatched_partial_token(first, second)),
}
}, },
}); });

View File

@ -43,7 +43,8 @@ impl Node {
if self.operator().is_leaf() { if self.operator().is_leaf() {
Err(Error::AppendedToLeafNode) Err(Error::AppendedToLeafNode)
} else if self.has_correct_amount_of_children() { } else if self.has_correct_amount_of_children() {
if self.children.last_mut().unwrap().operator().precedence() < node.operator().precedence() if self.children.last_mut().unwrap().operator().precedence()
< node.operator().precedence()
{ {
self.children self.children
.last_mut() .last_mut()
@ -102,7 +103,7 @@ pub fn tokens_to_operator_tree(tokens: Vec<Token>) -> Result<Node, Error> {
Token::LBrace => { Token::LBrace => {
root.push(Node::root_node()); root.push(Node::root_node());
None None
}, }
Token::RBrace => { Token::RBrace => {
if root.len() < 2 { if root.len() < 2 {
return Err(Error::UnmatchedRBrace); return Err(Error::UnmatchedRBrace);