Implemented mod and replaced Braced with RootNode
This commit is contained in:
parent
1bc2909c1b
commit
a1ba054609
@ -82,6 +82,13 @@ mod test {
|
|||||||
assert_eq!(eval("7/(7/(7/(7/(7/(7)))))"), Ok(Value::Int(1)));
|
assert_eq!(eval("7/(7/(7/(7/(7/(7)))))"), Ok(Value::Int(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mod_examples() {
|
||||||
|
assert_eq!(eval("1 % 4"), Ok(Value::Int(1)));
|
||||||
|
assert_eq!(eval("6 % 4"), Ok(Value::Int(2)));
|
||||||
|
assert_eq!(eval("1 % 4 + 2"), Ok(Value::Int(3)));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_type_errors() {
|
fn test_type_errors() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -21,12 +21,14 @@ pub trait Operator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct RootNode;
|
pub struct RootNode;
|
||||||
|
pub struct Braced;
|
||||||
|
|
||||||
pub struct Add;
|
pub struct Add;
|
||||||
pub struct Sub;
|
pub struct Sub;
|
||||||
pub struct Neg;
|
pub struct Neg;
|
||||||
pub struct Mul;
|
pub struct Mul;
|
||||||
pub struct Div;
|
pub struct Div;
|
||||||
pub struct Braced;
|
pub struct Mod;
|
||||||
|
|
||||||
pub struct Const {
|
pub struct Const {
|
||||||
value: Value,
|
value: Value,
|
||||||
@ -50,15 +52,16 @@ impl Identifier {
|
|||||||
|
|
||||||
impl Operator for RootNode {
|
impl Operator for RootNode {
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
i32::min_value()
|
200
|
||||||
}
|
}
|
||||||
|
|
||||||
fn argument_amount(&self) -> usize {
|
fn argument_amount(&self) -> usize {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&self, _arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
|
fn eval(&self, arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
|
||||||
Err(Error::EvaluatedRootNode)
|
expect_argument_amount(arguments.len(), 1)?;
|
||||||
|
Ok(arguments[0].clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +190,32 @@ impl Operator for Div {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Operator for Mod {
|
||||||
|
fn precedence(&self) -> i32 {
|
||||||
|
100
|
||||||
|
}
|
||||||
|
|
||||||
|
fn argument_amount(&self) -> usize {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eval(&self, arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
|
||||||
|
expect_argument_amount(arguments.len(), 2)?;
|
||||||
|
expect_number(&arguments[0])?;
|
||||||
|
expect_number(&arguments[1])?;
|
||||||
|
|
||||||
|
if arguments[0].is_int() && arguments[1].is_int() {
|
||||||
|
Ok(Value::Int(
|
||||||
|
arguments[0].as_int().unwrap() % arguments[1].as_int().unwrap(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(Value::Float(
|
||||||
|
arguments[0].as_float().unwrap() % arguments[1].as_float().unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Operator for Const {
|
impl Operator for Const {
|
||||||
fn precedence(&self) -> i32 {
|
fn precedence(&self) -> i32 {
|
||||||
200
|
200
|
||||||
@ -218,18 +247,3 @@ impl Operator for Identifier {
|
|||||||
configuration.get_value(&self.identifier)
|
configuration.get_value(&self.identifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operator for Braced {
|
|
||||||
fn precedence(&self) -> i32 {
|
|
||||||
200
|
|
||||||
}
|
|
||||||
|
|
||||||
fn argument_amount(&self) -> usize {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eval(&self, arguments: &[Value], configuration: &Configuration) -> Result<Value, Error> {
|
|
||||||
expect_argument_amount(arguments.len(), 1)?;
|
|
||||||
Ok(arguments[0].clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -7,6 +7,7 @@ pub enum Token {
|
|||||||
Minus,
|
Minus,
|
||||||
Star,
|
Star,
|
||||||
Slash,
|
Slash,
|
||||||
|
Percent,
|
||||||
LBrace,
|
LBrace,
|
||||||
RBrace,
|
RBrace,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
@ -30,6 +31,7 @@ fn char_to_token(c: char) -> PartialToken {
|
|||||||
'-' => PartialToken::Token(Token::Minus),
|
'-' => PartialToken::Token(Token::Minus),
|
||||||
'*' => PartialToken::Token(Token::Star),
|
'*' => PartialToken::Token(Token::Star),
|
||||||
'/' => PartialToken::Token(Token::Slash),
|
'/' => PartialToken::Token(Token::Slash),
|
||||||
|
'%' => PartialToken::Token(Token::Percent),
|
||||||
'(' => PartialToken::Token(Token::LBrace),
|
'(' => PartialToken::Token(Token::LBrace),
|
||||||
')' => PartialToken::Token(Token::RBrace),
|
')' => PartialToken::Token(Token::RBrace),
|
||||||
c => {
|
c => {
|
||||||
@ -50,6 +52,7 @@ impl Token {
|
|||||||
Token::Minus => false,
|
Token::Minus => false,
|
||||||
Token::Star => false,
|
Token::Star => false,
|
||||||
Token::Slash => false,
|
Token::Slash => false,
|
||||||
|
Token::Percent => false,
|
||||||
Token::LBrace => false,
|
Token::LBrace => false,
|
||||||
Token::RBrace => true,
|
Token::RBrace => true,
|
||||||
Token::Whitespace => false,
|
Token::Whitespace => false,
|
||||||
|
@ -18,10 +18,6 @@ impl Node {
|
|||||||
Self::new(RootNode)
|
Self::new(RootNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn braced_node() -> Self {
|
|
||||||
Self::new(Braced)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn eval(&self, configuration: &Configuration) -> Result<Value, Error> {
|
pub fn eval(&self, configuration: &Configuration) -> Result<Value, Error> {
|
||||||
let mut arguments = Vec::new();
|
let mut arguments = Vec::new();
|
||||||
for child in self.children() {
|
for child in self.children() {
|
||||||
@ -91,8 +87,9 @@ pub fn tokens_to_operator_tree(tokens: Vec<Token>) -> Result<Node, Error> {
|
|||||||
}
|
}
|
||||||
Token::Star => Some(Node::new(Mul)),
|
Token::Star => Some(Node::new(Mul)),
|
||||||
Token::Slash => Some(Node::new(Div)),
|
Token::Slash => Some(Node::new(Div)),
|
||||||
|
Token::Percent => Some(Node::new(Mod)),
|
||||||
Token::LBrace => {
|
Token::LBrace => {
|
||||||
root.push(Node::braced_node());
|
root.push(Node::root_node());
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
Token::RBrace => {
|
Token::RBrace => {
|
||||||
|
Loading…
Reference in New Issue
Block a user