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)));
|
||||
}
|
||||
|
||||
#[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]
|
||||
fn test_type_errors() {
|
||||
assert_eq!(
|
||||
|
@ -21,12 +21,14 @@ pub trait Operator {
|
||||
}
|
||||
|
||||
pub struct RootNode;
|
||||
pub struct Braced;
|
||||
|
||||
pub struct Add;
|
||||
pub struct Sub;
|
||||
pub struct Neg;
|
||||
pub struct Mul;
|
||||
pub struct Div;
|
||||
pub struct Braced;
|
||||
pub struct Mod;
|
||||
|
||||
pub struct Const {
|
||||
value: Value,
|
||||
@ -50,15 +52,16 @@ impl Identifier {
|
||||
|
||||
impl Operator for RootNode {
|
||||
fn precedence(&self) -> i32 {
|
||||
i32::min_value()
|
||||
200
|
||||
}
|
||||
|
||||
fn argument_amount(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn eval(&self, _arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
|
||||
Err(Error::EvaluatedRootNode)
|
||||
fn eval(&self, arguments: &[Value], _configuration: &Configuration) -> Result<Value, Error> {
|
||||
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 {
|
||||
fn precedence(&self) -> i32 {
|
||||
200
|
||||
@ -218,18 +247,3 @@ impl Operator for 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,
|
||||
Star,
|
||||
Slash,
|
||||
Percent,
|
||||
LBrace,
|
||||
RBrace,
|
||||
Whitespace,
|
||||
@ -30,6 +31,7 @@ fn char_to_token(c: char) -> PartialToken {
|
||||
'-' => PartialToken::Token(Token::Minus),
|
||||
'*' => PartialToken::Token(Token::Star),
|
||||
'/' => PartialToken::Token(Token::Slash),
|
||||
'%' => PartialToken::Token(Token::Percent),
|
||||
'(' => PartialToken::Token(Token::LBrace),
|
||||
')' => PartialToken::Token(Token::RBrace),
|
||||
c => {
|
||||
@ -50,6 +52,7 @@ impl Token {
|
||||
Token::Minus => false,
|
||||
Token::Star => false,
|
||||
Token::Slash => false,
|
||||
Token::Percent => false,
|
||||
Token::LBrace => false,
|
||||
Token::RBrace => true,
|
||||
Token::Whitespace => false,
|
||||
|
@ -18,10 +18,6 @@ impl Node {
|
||||
Self::new(RootNode)
|
||||
}
|
||||
|
||||
fn braced_node() -> Self {
|
||||
Self::new(Braced)
|
||||
}
|
||||
|
||||
pub fn eval(&self, configuration: &Configuration) -> Result<Value, Error> {
|
||||
let mut arguments = Vec::new();
|
||||
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::Slash => Some(Node::new(Div)),
|
||||
Token::Percent => Some(Node::new(Mod)),
|
||||
Token::LBrace => {
|
||||
root.push(Node::braced_node());
|
||||
root.push(Node::root_node());
|
||||
None
|
||||
},
|
||||
Token::RBrace => {
|
||||
|
Loading…
Reference in New Issue
Block a user