Implement equality operation
This commit is contained in:
parent
24a2642f17
commit
f389f7e422
@ -238,6 +238,7 @@ pub enum BinaryOperator {
|
|||||||
Subtract,
|
Subtract,
|
||||||
|
|
||||||
// Comparison
|
// Comparison
|
||||||
|
Equal,
|
||||||
Greater,
|
Greater,
|
||||||
GreaterOrEqual,
|
GreaterOrEqual,
|
||||||
Less,
|
Less,
|
||||||
@ -254,6 +255,7 @@ impl Display for BinaryOperator {
|
|||||||
BinaryOperator::Add => write!(f, "+"),
|
BinaryOperator::Add => write!(f, "+"),
|
||||||
BinaryOperator::And => write!(f, "&&"),
|
BinaryOperator::And => write!(f, "&&"),
|
||||||
BinaryOperator::Divide => write!(f, "/"),
|
BinaryOperator::Divide => write!(f, "/"),
|
||||||
|
BinaryOperator::Equal => write!(f, "=="),
|
||||||
BinaryOperator::Greater => write!(f, ">"),
|
BinaryOperator::Greater => write!(f, ">"),
|
||||||
BinaryOperator::GreaterOrEqual => write!(f, ">="),
|
BinaryOperator::GreaterOrEqual => write!(f, ">="),
|
||||||
BinaryOperator::Less => write!(f, "<"),
|
BinaryOperator::Less => write!(f, "<"),
|
||||||
|
@ -143,9 +143,15 @@ impl Lexer {
|
|||||||
(Token::RightParenthesis, (self.position - 1, self.position))
|
(Token::RightParenthesis, (self.position - 1, self.position))
|
||||||
}
|
}
|
||||||
'=' => {
|
'=' => {
|
||||||
self.position += 1;
|
if let Some('=') = self.peek_second_char(source) {
|
||||||
|
self.position += 2;
|
||||||
|
|
||||||
(Token::Equal, (self.position - 1, self.position))
|
(Token::DoubleEqual, (self.position - 2, self.position))
|
||||||
|
} else {
|
||||||
|
self.position += 1;
|
||||||
|
|
||||||
|
(Token::Equal, (self.position - 1, self.position))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'[' => {
|
'[' => {
|
||||||
self.position += 1;
|
self.position += 1;
|
||||||
@ -435,6 +441,21 @@ impl From<ParseIntError> for LexError {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equal() {
|
||||||
|
let input = "42 == 42";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
lex(input),
|
||||||
|
Ok(vec![
|
||||||
|
(Token::Integer(42), (0, 2)),
|
||||||
|
(Token::DoubleEqual, (3, 5)),
|
||||||
|
(Token::Integer(42), (6, 8)),
|
||||||
|
(Token::Eof, (8, 8)),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modulo() {
|
fn modulo() {
|
||||||
let input = "42 % 2";
|
let input = "42 % 2";
|
||||||
|
@ -319,6 +319,23 @@ impl<'src> Parser<'src> {
|
|||||||
(left_start, right_end),
|
(left_start, right_end),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
(Token::DoubleEqual, _) => {
|
||||||
|
let operator = Node::new(BinaryOperator::Equal, self.current.1);
|
||||||
|
|
||||||
|
self.next_token()?;
|
||||||
|
|
||||||
|
let right_node = self.parse_node(self.current_precedence())?;
|
||||||
|
let right_end = right_node.position.1;
|
||||||
|
|
||||||
|
return Ok(Node::new(
|
||||||
|
Statement::BinaryOperation {
|
||||||
|
left: Box::new(left_node),
|
||||||
|
operator,
|
||||||
|
right: Box::new(right_node),
|
||||||
|
},
|
||||||
|
(left_start, right_end),
|
||||||
|
));
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,6 +556,7 @@ impl<'src> Parser<'src> {
|
|||||||
|
|
||||||
fn current_precedence(&self) -> u8 {
|
fn current_precedence(&self) -> u8 {
|
||||||
match self.current.0 {
|
match self.current.0 {
|
||||||
|
Token::DoubleEqual => 6,
|
||||||
Token::Greater | Token::GreaterEqual | Token::Less | Token::LessEqual => 5,
|
Token::Greater | Token::GreaterEqual | Token::Less | Token::LessEqual => 5,
|
||||||
Token::Dot => 4,
|
Token::Dot => 4,
|
||||||
Token::Percent => 3,
|
Token::Percent => 3,
|
||||||
@ -613,6 +631,26 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equal() {
|
||||||
|
let input = "42 == 42";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse(input),
|
||||||
|
Ok(AbstractSyntaxTree {
|
||||||
|
nodes: [Node::new(
|
||||||
|
Statement::BinaryOperation {
|
||||||
|
left: Box::new(Node::new(Statement::Constant(Value::integer(42)), (0, 2))),
|
||||||
|
operator: Node::new(BinaryOperator::Equal, (3, 5)),
|
||||||
|
right: Box::new(Node::new(Statement::Constant(Value::integer(42)), (6, 8)))
|
||||||
|
},
|
||||||
|
(0, 8)
|
||||||
|
)]
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modulo() {
|
fn modulo() {
|
||||||
let input = "42 % 2";
|
let input = "42 % 2";
|
||||||
|
@ -27,6 +27,7 @@ pub enum Token<'src> {
|
|||||||
Comma,
|
Comma,
|
||||||
Dot,
|
Dot,
|
||||||
DoubleAmpersand,
|
DoubleAmpersand,
|
||||||
|
DoubleEqual,
|
||||||
DoublePipe,
|
DoublePipe,
|
||||||
Equal,
|
Equal,
|
||||||
Greater,
|
Greater,
|
||||||
@ -53,6 +54,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Comma => TokenOwned::Comma,
|
Token::Comma => TokenOwned::Comma,
|
||||||
Token::Dot => TokenOwned::Dot,
|
Token::Dot => TokenOwned::Dot,
|
||||||
Token::DoubleAmpersand => TokenOwned::DoubleAmpersand,
|
Token::DoubleAmpersand => TokenOwned::DoubleAmpersand,
|
||||||
|
Token::DoubleEqual => TokenOwned::DoubleEqual,
|
||||||
Token::DoublePipe => TokenOwned::DoublePipe,
|
Token::DoublePipe => TokenOwned::DoublePipe,
|
||||||
Token::Eof => TokenOwned::Eof,
|
Token::Eof => TokenOwned::Eof,
|
||||||
Token::Equal => TokenOwned::Equal,
|
Token::Equal => TokenOwned::Equal,
|
||||||
@ -89,6 +91,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Comma => ",",
|
Token::Comma => ",",
|
||||||
Token::Dot => ".",
|
Token::Dot => ".",
|
||||||
Token::DoubleAmpersand => "&&",
|
Token::DoubleAmpersand => "&&",
|
||||||
|
Token::DoubleEqual => "==",
|
||||||
Token::DoublePipe => "||",
|
Token::DoublePipe => "||",
|
||||||
Token::Eof => "EOF",
|
Token::Eof => "EOF",
|
||||||
Token::Equal => "=",
|
Token::Equal => "=",
|
||||||
@ -136,6 +139,9 @@ impl<'src> PartialEq for Token<'src> {
|
|||||||
(Token::Boolean(left), Token::Boolean(right)) => left == right,
|
(Token::Boolean(left), Token::Boolean(right)) => left == right,
|
||||||
(Token::Comma, Token::Comma) => true,
|
(Token::Comma, Token::Comma) => true,
|
||||||
(Token::Dot, Token::Dot) => true,
|
(Token::Dot, Token::Dot) => true,
|
||||||
|
(Token::DoubleAmpersand, Token::DoubleAmpersand) => true,
|
||||||
|
(Token::DoubleEqual, Token::DoubleEqual) => true,
|
||||||
|
(Token::DoublePipe, Token::DoublePipe) => true,
|
||||||
(Token::Eof, Token::Eof) => true,
|
(Token::Eof, Token::Eof) => true,
|
||||||
(Token::Equal, Token::Equal) => true,
|
(Token::Equal, Token::Equal) => true,
|
||||||
(Token::Greater, Token::Greater) => true,
|
(Token::Greater, Token::Greater) => true,
|
||||||
@ -192,6 +198,7 @@ pub enum TokenOwned {
|
|||||||
Comma,
|
Comma,
|
||||||
Dot,
|
Dot,
|
||||||
DoubleAmpersand,
|
DoubleAmpersand,
|
||||||
|
DoubleEqual,
|
||||||
DoublePipe,
|
DoublePipe,
|
||||||
Equal,
|
Equal,
|
||||||
Greater,
|
Greater,
|
||||||
@ -218,6 +225,7 @@ impl Display for TokenOwned {
|
|||||||
TokenOwned::Comma => Token::Comma.fmt(f),
|
TokenOwned::Comma => Token::Comma.fmt(f),
|
||||||
TokenOwned::Dot => Token::Dot.fmt(f),
|
TokenOwned::Dot => Token::Dot.fmt(f),
|
||||||
TokenOwned::DoubleAmpersand => Token::DoubleAmpersand.fmt(f),
|
TokenOwned::DoubleAmpersand => Token::DoubleAmpersand.fmt(f),
|
||||||
|
TokenOwned::DoubleEqual => Token::DoubleEqual.fmt(f),
|
||||||
TokenOwned::DoublePipe => Token::DoublePipe.fmt(f),
|
TokenOwned::DoublePipe => Token::DoublePipe.fmt(f),
|
||||||
TokenOwned::Eof => Token::Eof.fmt(f),
|
TokenOwned::Eof => Token::Eof.fmt(f),
|
||||||
TokenOwned::Equal => Token::Equal.fmt(f),
|
TokenOwned::Equal => Token::Equal.fmt(f),
|
||||||
|
@ -96,6 +96,7 @@ impl Vm {
|
|||||||
BinaryOperator::Add => left_value.add(&right_value),
|
BinaryOperator::Add => left_value.add(&right_value),
|
||||||
BinaryOperator::And => left_value.and(&right_value),
|
BinaryOperator::And => left_value.and(&right_value),
|
||||||
BinaryOperator::Divide => left_value.divide(&right_value),
|
BinaryOperator::Divide => left_value.divide(&right_value),
|
||||||
|
BinaryOperator::Equal => Ok(Value::boolean(left_value == right_value)),
|
||||||
BinaryOperator::Greater => left_value.greater_than(&right_value),
|
BinaryOperator::Greater => left_value.greater_than(&right_value),
|
||||||
BinaryOperator::GreaterOrEqual => {
|
BinaryOperator::GreaterOrEqual => {
|
||||||
left_value.greater_than_or_equal(&right_value)
|
left_value.greater_than_or_equal(&right_value)
|
||||||
@ -433,6 +434,26 @@ impl Display for VmError {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn map_equal() {
|
||||||
|
let input = "{ y = 'foo' } == { y = 'foo' }";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
run(input, &mut HashMap::new()),
|
||||||
|
Ok(Some(Value::boolean(true)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn integer_equal() {
|
||||||
|
let input = "42 == 42";
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
run(input, &mut HashMap::new()),
|
||||||
|
Ok(Some(Value::boolean(true)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modulo() {
|
fn modulo() {
|
||||||
let input = "42 % 2";
|
let input = "42 % 2";
|
||||||
|
Loading…
Reference in New Issue
Block a user