Add exponentiation operator

+ Add hat token
 + Add exponentiation operator
 + Document exponentiation operator
 + Test exponentiation operator

Implements #3
This commit is contained in:
Sebastian Schmidt 2019-03-19 18:42:50 +02:00
parent 93e8d867b4
commit 55e8b51228
4 changed files with 46 additions and 2 deletions

View File

@ -105,7 +105,7 @@ Supported binary operators:
| / | 100 | Division | | \>= | 80 | Greater than or equal | | / | 100 | Division | | \>= | 80 | Greater than or equal |
| % | 100 | Modulo | | == | 80 | Equal | | % | 100 | Modulo | | == | 80 | Equal |
| && | 75 | Logical and | | != | 80 | Not equal | | && | 75 | Logical and | | != | 80 | Not equal |
| || | 70 | Logical or | ^ | 120 | Exponentation | | || | 70 | Logical or | ^ | 120 | Exponentiation |
Supported unary operators: Supported unary operators:

View File

@ -94,7 +94,7 @@
//! | / | 100 | Division | | \>= | 80 | Greater than or equal | //! | / | 100 | Division | | \>= | 80 | Greater than or equal |
//! | % | 100 | Modulo | | == | 80 | Equal | //! | % | 100 | Modulo | | == | 80 | Equal |
//! | && | 75 | Logical and | | != | 80 | Not equal | //! | && | 75 | Logical and | | != | 80 | Not equal |
//! | || | 70 | Logical or | ^ | 120 | Exponentation | //! | || | 70 | Logical or | ^ | 120 | Exponentiation |
//! //!
//! Supported unary operators: //! Supported unary operators:
//! //!
@ -120,6 +120,7 @@
//! Operators that take numbers as arguments can either take integers or floating point numbers. //! Operators that take numbers as arguments can either take integers or floating point numbers.
//! If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well. //! If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well.
//! Otherwise, the result is an integer. //! Otherwise, the result is an integer.
//! An exception to this is the exponentiation operator that always returns a floating point number.
//! //!
//! Values have a precedence of 200. //! Values have a precedence of 200.
//! //!
@ -290,6 +291,14 @@ mod test {
assert_eq!(eval("1 % 4 + 2"), Ok(Value::Int(3))); assert_eq!(eval("1 % 4 + 2"), Ok(Value::Int(3)));
} }
#[test]
fn test_pow_examples() {
assert_eq!(eval("1 ^ 4"), Ok(Value::Float(1.0)));
assert_eq!(eval("6 ^ 4"), Ok(Value::Float(6.0f64.powf(4.0))));
assert_eq!(eval("1 ^ 4 + 2"), Ok(Value::Float(3.0)));
assert_eq!(eval("2 ^ (4 + 2)"), Ok(Value::Float(64.0)));
}
#[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)));

View File

@ -43,6 +43,12 @@ impl Display for Mod {
} }
} }
impl Display for Exp {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "^")
}
}
impl Display for Eq { impl Display for Eq {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "==") write!(f, "==")

View File

@ -45,7 +45,9 @@ pub struct Div;
#[derive(Debug)] #[derive(Debug)]
pub struct Mod; pub struct Mod;
#[derive(Debug)] #[derive(Debug)]
pub struct Exp;
#[derive(Debug)]
pub struct Eq; pub struct Eq;
#[derive(Debug)] #[derive(Debug)]
pub struct Neq; pub struct Neq;
@ -294,6 +296,33 @@ impl Operator for Mod {
} }
} }
impl Operator for Exp {
fn precedence(&self) -> i32 {
120
}
fn is_left_to_right(&self) -> bool {
true
}
fn argument_amount(&self) -> usize {
2
}
fn eval(&self, arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
expect_operator_argument_amount(arguments.len(), 2)?;
expect_number(&arguments[0])?;
expect_number(&arguments[1])?;
Ok(Value::Float(
arguments[0]
.as_float()
.unwrap()
.powf(arguments[1].as_float().unwrap()),
))
}
}
impl Operator for Eq { impl Operator for Eq {
fn precedence(&self) -> i32 { fn precedence(&self) -> i32 {
80 80