Add && and || operators
This commit is contained in:
parent
8c8fde94ce
commit
d0dba35285
@ -85,8 +85,7 @@ impl Statement {
|
|||||||
.map(|value| value.r#type(variables)),
|
.map(|value| value.r#type(variables)),
|
||||||
Statement::List(nodes) => nodes
|
Statement::List(nodes) => nodes
|
||||||
.first()
|
.first()
|
||||||
.map(|node| node.inner.expected_type(variables))
|
.and_then(|node| node.inner.expected_type(variables)),
|
||||||
.flatten(),
|
|
||||||
Statement::PropertyAccess(_, _) => None,
|
Statement::PropertyAccess(_, _) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,26 +196,35 @@ impl Display for Statement {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum BinaryOperator {
|
pub enum BinaryOperator {
|
||||||
|
// Math
|
||||||
Add,
|
Add,
|
||||||
Divide,
|
Divide,
|
||||||
|
Multiply,
|
||||||
|
Subtract,
|
||||||
|
|
||||||
|
// Comparison
|
||||||
Greater,
|
Greater,
|
||||||
GreaterOrEqual,
|
GreaterOrEqual,
|
||||||
Less,
|
Less,
|
||||||
LessOrEqual,
|
LessOrEqual,
|
||||||
Multiply,
|
|
||||||
Subtract,
|
// Logic
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for BinaryOperator {
|
impl Display for BinaryOperator {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
BinaryOperator::Add => write!(f, "+"),
|
BinaryOperator::Add => write!(f, "+"),
|
||||||
|
BinaryOperator::And => write!(f, "&&"),
|
||||||
BinaryOperator::Divide => write!(f, "/"),
|
BinaryOperator::Divide => 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, "<"),
|
||||||
BinaryOperator::LessOrEqual => write!(f, "<="),
|
BinaryOperator::LessOrEqual => write!(f, "<="),
|
||||||
BinaryOperator::Multiply => write!(f, "*"),
|
BinaryOperator::Multiply => write!(f, "*"),
|
||||||
|
BinaryOperator::Or => write!(f, "||"),
|
||||||
BinaryOperator::Subtract => write!(f, "-"),
|
BinaryOperator::Subtract => write!(f, "-"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,7 @@ impl<'a> Analyzer<'a> {
|
|||||||
fn analyze_node(&self, node: &Node<Statement>) -> Result<(), AnalyzerError> {
|
fn analyze_node(&self, node: &Node<Statement>) -> Result<(), AnalyzerError> {
|
||||||
match &node.inner {
|
match &node.inner {
|
||||||
Statement::Assignment {
|
Statement::Assignment {
|
||||||
identifier,
|
value_node: value, ..
|
||||||
value_node: value,
|
|
||||||
} => {
|
} => {
|
||||||
if let None = value.inner.expected_type(self.variables) {
|
if let None = value.inner.expected_type(self.variables) {
|
||||||
return Err(AnalyzerError::ExpectedValue {
|
return Err(AnalyzerError::ExpectedValue {
|
||||||
@ -95,6 +94,49 @@ impl<'a> Analyzer<'a> {
|
|||||||
} => {
|
} => {
|
||||||
self.analyze_node(left)?;
|
self.analyze_node(left)?;
|
||||||
self.analyze_node(right)?;
|
self.analyze_node(right)?;
|
||||||
|
|
||||||
|
let left_type = left.inner.expected_type(self.variables);
|
||||||
|
let right_type = right.inner.expected_type(self.variables);
|
||||||
|
|
||||||
|
if let BinaryOperator::Add
|
||||||
|
| BinaryOperator::Subtract
|
||||||
|
| BinaryOperator::Multiply
|
||||||
|
| BinaryOperator::Divide
|
||||||
|
| BinaryOperator::Greater
|
||||||
|
| BinaryOperator::GreaterOrEqual
|
||||||
|
| BinaryOperator::Less
|
||||||
|
| BinaryOperator::LessOrEqual = operator.inner
|
||||||
|
{
|
||||||
|
match (left_type, right_type) {
|
||||||
|
(Some(Type::Integer), Some(Type::Integer)) => {}
|
||||||
|
(Some(Type::Float), Some(Type::Float)) => {}
|
||||||
|
(Some(Type::String), Some(Type::String)) => {}
|
||||||
|
(Some(Type::Integer), _) => {
|
||||||
|
return Err(AnalyzerError::ExpectedInteger {
|
||||||
|
actual: right.as_ref().clone(),
|
||||||
|
position: right.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(Some(Type::Float), _) => {
|
||||||
|
return Err(AnalyzerError::ExpectedFloat {
|
||||||
|
actual: right.as_ref().clone(),
|
||||||
|
position: right.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(Some(Type::String), _) => {
|
||||||
|
return Err(AnalyzerError::ExpectedString {
|
||||||
|
actual: right.as_ref().clone(),
|
||||||
|
position: right.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(_, _) => {
|
||||||
|
return Err(AnalyzerError::ExpectedIntegerFloatOrString {
|
||||||
|
actual: right.as_ref().clone(),
|
||||||
|
position: right.position,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Statement::BuiltInFunctionCall { .. } => {}
|
Statement::BuiltInFunctionCall { .. } => {}
|
||||||
Statement::Constant(_) => {}
|
Statement::Constant(_) => {}
|
||||||
@ -181,6 +223,11 @@ pub enum AnalyzerError {
|
|||||||
actual: Node<Statement>,
|
actual: Node<Statement>,
|
||||||
position: Span,
|
position: Span,
|
||||||
},
|
},
|
||||||
|
ExpectedSameType {
|
||||||
|
left: Node<Statement>,
|
||||||
|
right: Node<Statement>,
|
||||||
|
position: Span,
|
||||||
|
},
|
||||||
ExpectedString {
|
ExpectedString {
|
||||||
actual: Node<Statement>,
|
actual: Node<Statement>,
|
||||||
position: (usize, usize),
|
position: (usize, usize),
|
||||||
@ -210,6 +257,7 @@ impl AnalyzerError {
|
|||||||
AnalyzerError::ExpectedInteger { position, .. } => *position,
|
AnalyzerError::ExpectedInteger { position, .. } => *position,
|
||||||
AnalyzerError::ExpectedIntegerOrFloat { position, .. } => *position,
|
AnalyzerError::ExpectedIntegerOrFloat { position, .. } => *position,
|
||||||
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => *position,
|
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => *position,
|
||||||
|
AnalyzerError::ExpectedSameType { position, .. } => *position,
|
||||||
AnalyzerError::ExpectedString { position, .. } => *position,
|
AnalyzerError::ExpectedString { position, .. } => *position,
|
||||||
AnalyzerError::UnexpectedIdentifier { position, .. } => *position,
|
AnalyzerError::UnexpectedIdentifier { position, .. } => *position,
|
||||||
AnalyzerError::UnexectedString { position, .. } => *position,
|
AnalyzerError::UnexectedString { position, .. } => *position,
|
||||||
@ -243,6 +291,9 @@ impl Display for AnalyzerError {
|
|||||||
AnalyzerError::ExpectedIntegerFloatOrString { actual, .. } => {
|
AnalyzerError::ExpectedIntegerFloatOrString { actual, .. } => {
|
||||||
write!(f, "Expected integer, float, or string, found {}", actual)
|
write!(f, "Expected integer, float, or string, found {}", actual)
|
||||||
}
|
}
|
||||||
|
AnalyzerError::ExpectedSameType { left, right, .. } => {
|
||||||
|
write!(f, "Expected same type, found {} and {}", left, right)
|
||||||
|
}
|
||||||
AnalyzerError::ExpectedString { actual, .. } => {
|
AnalyzerError::ExpectedString { actual, .. } => {
|
||||||
write!(f, "Expected string, found {}", actual)
|
write!(f, "Expected string, found {}", actual)
|
||||||
}
|
}
|
||||||
@ -266,15 +317,15 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_expects_same_types() {
|
fn float_plus_integer() {
|
||||||
let abstract_tree = AbstractSyntaxTree {
|
let abstract_tree = AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
left: Box::new(Node::new(Statement::Constant(Value::float(1.0)), (0, 1))),
|
||||||
operator: Node::new(BinaryOperator::Add, (1, 2)),
|
operator: Node::new(BinaryOperator::Add, (1, 2)),
|
||||||
right: Box::new(Node::new(Statement::Constant(Value::float(1.0)), (3, 4))),
|
right: Box::new(Node::new(Statement::Constant(Value::integer(1)), (3, 4))),
|
||||||
},
|
},
|
||||||
(0, 4),
|
(0, 2),
|
||||||
)]
|
)]
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
@ -283,15 +334,15 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
analyzer.analyze(),
|
analyzer.analyze(),
|
||||||
Err(AnalyzerError::ExpectedIntegerFloatOrString {
|
Err(AnalyzerError::ExpectedFloat {
|
||||||
actual: Node::new(Statement::Constant(Value::float(1.0)), (1, 2)),
|
actual: Node::new(Statement::Constant(Value::integer(1)), (3, 4)),
|
||||||
position: (1, 2)
|
position: (3, 4)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_expects_integer_float_or_string() {
|
fn integer_plus_boolean() {
|
||||||
let abstract_tree = AbstractSyntaxTree {
|
let abstract_tree = AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
@ -308,9 +359,9 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
analyzer.analyze(),
|
analyzer.analyze(),
|
||||||
Err(AnalyzerError::ExpectedIntegerFloatOrString {
|
Err(AnalyzerError::ExpectedInteger {
|
||||||
actual: Node::new(Statement::Constant(Value::boolean(true)), (0, 1)),
|
actual: Node::new(Statement::Constant(Value::boolean(true)), (3, 4)),
|
||||||
position: (0, 1)
|
position: (3, 4)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -376,58 +427,6 @@ mod tests {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn multiply_expect_integer_or_float() {
|
|
||||||
let abstract_tree = AbstractSyntaxTree {
|
|
||||||
nodes: [Node::new(
|
|
||||||
Statement::BinaryOperation {
|
|
||||||
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
|
||||||
operator: Node::new(BinaryOperator::Multiply, (1, 2)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::boolean(false)),
|
|
||||||
(3, 4),
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
(0, 2),
|
|
||||||
)]
|
|
||||||
.into(),
|
|
||||||
};
|
|
||||||
let variables = HashMap::new();
|
|
||||||
let analyzer = Analyzer::new(&abstract_tree, &variables);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
analyzer.analyze(),
|
|
||||||
Err(AnalyzerError::ExpectedIntegerOrFloat {
|
|
||||||
actual: Node::new(Statement::Constant(Value::boolean(false)), (1, 2)),
|
|
||||||
position: (1, 2)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assignment_expect_identifier() {
|
|
||||||
let abstract_tree = AbstractSyntaxTree {
|
|
||||||
nodes: [Node::new(
|
|
||||||
Statement::Assignment {
|
|
||||||
identifier: Identifier::new("x"),
|
|
||||||
value_node: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
|
||||||
},
|
|
||||||
(0, 2),
|
|
||||||
)]
|
|
||||||
.into(),
|
|
||||||
};
|
|
||||||
let variables = HashMap::new();
|
|
||||||
let analyzer = Analyzer::new(&abstract_tree, &variables);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
analyzer.analyze(),
|
|
||||||
Err(AnalyzerError::ExpectedIdentifier {
|
|
||||||
actual: Node::new(Statement::Constant(Value::integer(1)), (0, 1)),
|
|
||||||
position: (0, 1)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unexpected_identifier() {
|
fn unexpected_identifier() {
|
||||||
let abstract_tree = AbstractSyntaxTree {
|
let abstract_tree = AbstractSyntaxTree {
|
||||||
|
@ -582,7 +582,7 @@ mod tests {
|
|||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
||||||
operator: Node::new(BinaryOperator::Less, (2, 4)),
|
operator: Node::new(BinaryOperator::LessOrEqual, (2, 4)),
|
||||||
right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))),
|
right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))),
|
||||||
},
|
},
|
||||||
(0, 6)
|
(0, 6)
|
||||||
@ -602,7 +602,7 @@ mod tests {
|
|||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))),
|
||||||
operator: Node::new(BinaryOperator::Greater, (2, 4)),
|
operator: Node::new(BinaryOperator::GreaterOrEqual, (2, 4)),
|
||||||
right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))),
|
right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))),
|
||||||
},
|
},
|
||||||
(0, 6)
|
(0, 6)
|
||||||
@ -641,9 +641,9 @@ mod tests {
|
|||||||
Ok(AbstractSyntaxTree {
|
Ok(AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Node::new(Statement::Constant(Value::integer(1)), (1, 2)).into(),
|
left: Node::new(Statement::Constant(Value::integer(-1)), (0, 2)).into(),
|
||||||
operator: Node::new(BinaryOperator::Subtract, (3, 4)),
|
operator: Node::new(BinaryOperator::Subtract, (3, 4)),
|
||||||
right: Node::new(Statement::Constant(Value::integer(2)), (6, 7)).into()
|
right: Node::new(Statement::Constant(Value::integer(-2)), (5, 7)).into()
|
||||||
},
|
},
|
||||||
(0, 7)
|
(0, 7)
|
||||||
)]
|
)]
|
||||||
@ -663,15 +663,15 @@ mod tests {
|
|||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(
|
left: Box::new(Node::new(
|
||||||
Statement::Constant(Value::string("Hello, ")),
|
Statement::Constant(Value::string("Hello, ")),
|
||||||
(0, 8)
|
(0, 9)
|
||||||
)),
|
)),
|
||||||
operator: Node::new(BinaryOperator::Add, (9, 10)),
|
operator: Node::new(BinaryOperator::Add, (10, 11)),
|
||||||
right: Box::new(Node::new(
|
right: Box::new(Node::new(
|
||||||
Statement::Constant(Value::string("World!")),
|
Statement::Constant(Value::string("World!")),
|
||||||
(11, 19)
|
(12, 20)
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
(0, 19)
|
(0, 20)
|
||||||
)]
|
)]
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -26,6 +26,8 @@ pub enum Token<'src> {
|
|||||||
// Symbols
|
// Symbols
|
||||||
Comma,
|
Comma,
|
||||||
Dot,
|
Dot,
|
||||||
|
DoubleAmpersand,
|
||||||
|
DoublePipe,
|
||||||
Equal,
|
Equal,
|
||||||
Greater,
|
Greater,
|
||||||
GreaterEqual,
|
GreaterEqual,
|
||||||
@ -46,6 +48,8 @@ impl<'src> Token<'src> {
|
|||||||
Token::Boolean(boolean) => TokenOwned::Boolean(*boolean),
|
Token::Boolean(boolean) => TokenOwned::Boolean(*boolean),
|
||||||
Token::Comma => TokenOwned::Comma,
|
Token::Comma => TokenOwned::Comma,
|
||||||
Token::Dot => TokenOwned::Dot,
|
Token::Dot => TokenOwned::Dot,
|
||||||
|
Token::DoubleAmpersand => TokenOwned::DoubleAmpersand,
|
||||||
|
Token::DoublePipe => TokenOwned::DoublePipe,
|
||||||
Token::Eof => TokenOwned::Eof,
|
Token::Eof => TokenOwned::Eof,
|
||||||
Token::Equal => TokenOwned::Equal,
|
Token::Equal => TokenOwned::Equal,
|
||||||
Token::Float(float) => TokenOwned::Float(*float),
|
Token::Float(float) => TokenOwned::Float(*float),
|
||||||
@ -76,6 +80,8 @@ impl<'src> Token<'src> {
|
|||||||
Token::Boolean(_) => "boolean",
|
Token::Boolean(_) => "boolean",
|
||||||
Token::Comma => ",",
|
Token::Comma => ",",
|
||||||
Token::Dot => ".",
|
Token::Dot => ".",
|
||||||
|
Token::DoubleAmpersand => "&&",
|
||||||
|
Token::DoublePipe => "||",
|
||||||
Token::Eof => "EOF",
|
Token::Eof => "EOF",
|
||||||
Token::Equal => "=",
|
Token::Equal => "=",
|
||||||
Token::Float(_) => "float",
|
Token::Float(_) => "float",
|
||||||
@ -169,6 +175,8 @@ pub enum TokenOwned {
|
|||||||
// Symbols
|
// Symbols
|
||||||
Comma,
|
Comma,
|
||||||
Dot,
|
Dot,
|
||||||
|
DoubleAmpersand,
|
||||||
|
DoublePipe,
|
||||||
Equal,
|
Equal,
|
||||||
Greater,
|
Greater,
|
||||||
GreaterOrEqual,
|
GreaterOrEqual,
|
||||||
@ -189,6 +197,8 @@ impl Display for TokenOwned {
|
|||||||
TokenOwned::Boolean(boolean) => write!(f, "{boolean}"),
|
TokenOwned::Boolean(boolean) => write!(f, "{boolean}"),
|
||||||
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::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),
|
||||||
TokenOwned::Float(float) => write!(f, "{float}"),
|
TokenOwned::Float(float) => write!(f, "{float}"),
|
||||||
|
@ -207,6 +207,24 @@ impl Value {
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn and(&self, other: &Value) -> Result<Value, ValueError> {
|
||||||
|
match (self.inner().as_ref(), other.inner().as_ref()) {
|
||||||
|
(ValueInner::Boolean(left), ValueInner::Boolean(right)) => {
|
||||||
|
Ok(Value::boolean(*left && *right))
|
||||||
|
}
|
||||||
|
_ => Err(ValueError::CannotAnd(self.clone(), other.clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn or(&self, other: &Value) -> Result<Value, ValueError> {
|
||||||
|
match (self.inner().as_ref(), other.inner().as_ref()) {
|
||||||
|
(ValueInner::Boolean(left), ValueInner::Boolean(right)) => {
|
||||||
|
Ok(Value::boolean(*left || *right))
|
||||||
|
}
|
||||||
|
_ => Err(ValueError::CannotOr(self.clone(), other.clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Value {
|
impl Display for Value {
|
||||||
@ -734,15 +752,16 @@ impl Display for Function {
|
|||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum ValueError {
|
pub enum ValueError {
|
||||||
CannotAdd(Value, Value),
|
CannotAdd(Value, Value),
|
||||||
CannotMultiply(Value, Value),
|
CannotAnd(Value, Value),
|
||||||
CannotSubtract(Value, Value),
|
|
||||||
CannotLessThan(Value, Value),
|
|
||||||
CannotLessThanOrEqual(Value, Value),
|
|
||||||
CannotGreaterThan(Value, Value),
|
CannotGreaterThan(Value, Value),
|
||||||
CannotGreaterThanOrEqual(Value, Value),
|
CannotGreaterThanOrEqual(Value, Value),
|
||||||
|
CannotLessThan(Value, Value),
|
||||||
|
CannotLessThanOrEqual(Value, Value),
|
||||||
|
CannotMultiply(Value, Value),
|
||||||
|
CannotSubtract(Value, Value),
|
||||||
|
CannotOr(Value, Value),
|
||||||
ExpectedList(Value),
|
ExpectedList(Value),
|
||||||
IndexOutOfBounds { value: Value, index: i64 },
|
IndexOutOfBounds { value: Value, index: i64 },
|
||||||
PropertyNotFound { value: Value, property: Identifier },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ValueError {}
|
impl Error for ValueError {}
|
||||||
@ -751,6 +770,11 @@ impl Display for ValueError {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ValueError::CannotAdd(left, right) => write!(f, "Cannot add {} and {}", left, right),
|
ValueError::CannotAdd(left, right) => write!(f, "Cannot add {} and {}", left, right),
|
||||||
|
ValueError::CannotAnd(left, right) => write!(
|
||||||
|
f,
|
||||||
|
"Cannot use logical and operation on {} and {}",
|
||||||
|
left, right
|
||||||
|
),
|
||||||
ValueError::CannotMultiply(left, right) => {
|
ValueError::CannotMultiply(left, right) => {
|
||||||
write!(f, "Cannot multiply {} and {}", left, right)
|
write!(f, "Cannot multiply {} and {}", left, right)
|
||||||
}
|
}
|
||||||
@ -763,8 +787,12 @@ impl Display for ValueError {
|
|||||||
| ValueError::CannotGreaterThanOrEqual(left, right) => {
|
| ValueError::CannotGreaterThanOrEqual(left, right) => {
|
||||||
write!(f, "Cannot compare {} and {}", left, right)
|
write!(f, "Cannot compare {} and {}", left, right)
|
||||||
}
|
}
|
||||||
ValueError::PropertyNotFound { value, property } => {
|
ValueError::CannotOr(left, right) => {
|
||||||
write!(f, "{} does not have a property named {}", value, property)
|
write!(
|
||||||
|
f,
|
||||||
|
"Cannot use logical or operation on {} and {}",
|
||||||
|
left, right
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ValueError::IndexOutOfBounds { value, index } => {
|
ValueError::IndexOutOfBounds { value, index } => {
|
||||||
write!(f, "{} does not have an index of {}", value, index)
|
write!(f, "{} does not have an index of {}", value, index)
|
||||||
|
@ -94,6 +94,7 @@ impl Vm {
|
|||||||
|
|
||||||
let result = match operator.inner {
|
let result = match operator.inner {
|
||||||
BinaryOperator::Add => left_value.add(&right_value),
|
BinaryOperator::Add => left_value.add(&right_value),
|
||||||
|
BinaryOperator::And => left_value.and(&right_value),
|
||||||
BinaryOperator::Divide => todo!(),
|
BinaryOperator::Divide => todo!(),
|
||||||
BinaryOperator::Greater => left_value.greater_than(&right_value),
|
BinaryOperator::Greater => left_value.greater_than(&right_value),
|
||||||
BinaryOperator::GreaterOrEqual => {
|
BinaryOperator::GreaterOrEqual => {
|
||||||
@ -102,6 +103,7 @@ impl Vm {
|
|||||||
BinaryOperator::Less => left_value.less_than(&right_value),
|
BinaryOperator::Less => left_value.less_than(&right_value),
|
||||||
BinaryOperator::LessOrEqual => left_value.less_than_or_equal(&right_value),
|
BinaryOperator::LessOrEqual => left_value.less_than_or_equal(&right_value),
|
||||||
BinaryOperator::Multiply => left_value.multiply(&right_value),
|
BinaryOperator::Multiply => left_value.multiply(&right_value),
|
||||||
|
BinaryOperator::Or => left_value.or(&right_value),
|
||||||
BinaryOperator::Subtract => left_value.subtract(&right_value),
|
BinaryOperator::Subtract => left_value.subtract(&right_value),
|
||||||
}
|
}
|
||||||
.map_err(|value_error| VmError::ValueError {
|
.map_err(|value_error| VmError::ValueError {
|
||||||
|
Loading…
Reference in New Issue
Block a user