Skip to main content

rl_lang/interpreter/utils/
unary.rs

1//! Unary operator evaluation.
2//!
3//! | Operator | Operand       | Result                  |
4//! |----------|---------------|-------------------------|
5//! | `!`      | `bool`        | `bool`                  |
6//! | `-`      | `int`         | `int`                   |
7//! | `-`      | `float`       | `float`                 |
8
9use crate::{
10    interpreter::evaluator::Evaluator,
11    interpreter::values::Value,
12    lexer::tokentypes::TokenType,
13    utils::{errors::Error, span::Span},
14};
15
16impl Evaluator {
17    fn type_mismatch_unary(
18        &self,
19        op: &str,
20        operand: &Value,
21        operand_span: Span,
22        span: Span,
23    ) -> Error {
24        self.err(format!("type mismatch on {}", op), span)
25            .with_label(operand_span, format!("this is {}", operand.type_name()))
26    }
27
28    pub fn match_unary_operator(
29        &mut self,
30        operand: Value,
31        operand_span: Span,
32        operator: &TokenType,
33        span: Span,
34    ) -> Result<Value, Error> {
35        let v = match operator {
36            TokenType::Bang => match &operand {
37                Value::Bool(b) => Value::Bool(!b),
38                _ => return Err(self.type_mismatch_unary("!", &operand, operand_span, span)),
39            },
40            TokenType::Minus => match &operand {
41                Value::Integer(i) => Value::Integer(-i),
42                Value::Float(f) => Value::Float(-f),
43                _ => return Err(self.type_mismatch_unary("-", &operand, operand_span, span)),
44            },
45            _ => return Err(self.err("unknown unary operator", span)),
46        };
47        Ok(v)
48    }
49}