Merge pull request #47 from rustysec/modulo_and_bugfix
bugfix for binary and, modulo, binary ops tests
This commit is contained in:
commit
1c6a3fa5fa
@ -7,7 +7,7 @@ use std::fmt;
|
||||
use parser::{lex, parse, Expr, Stmt, FnDef};
|
||||
use fn_register::FnRegister;
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, BitAnd, BitOr, BitXor, Shl, Shr};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, BitAnd, BitOr, BitXor, Shl, Shr, Rem};
|
||||
use std::cmp::{PartialOrd, PartialEq};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1417,6 +1417,7 @@ impl Engine {
|
||||
fn binary_xor<T: BitXor>(x: T, y: T) -> <T as BitXor>::Output { x ^ y }
|
||||
fn left_shift<T: Shl<T>>(x: T, y: T) -> <T as Shl<T>>::Output { x.shl(y) }
|
||||
fn right_shift<T: Shr<T>>(x: T, y: T) -> <T as Shr<T>>::Output { x.shr(y) }
|
||||
fn modulo<T: Rem<T>>(x: T, y: T) -> <T as Rem<T>>::Output { x % y}
|
||||
|
||||
reg_op!(engine, "+", add, i32, i64, u32, u64, f32, f64);
|
||||
reg_op!(engine, "-", sub, i32, i64, u32, u64, f32, f64);
|
||||
@ -1439,6 +1440,7 @@ impl Engine {
|
||||
reg_op!(engine, "^", binary_xor, i32, i64, u32, u64);
|
||||
reg_op!(engine, "<<", left_shift, i32, i64, u32, u64);
|
||||
reg_op!(engine, ">>", right_shift, i32, i64, u32, u64);
|
||||
reg_op!(engine, "%", modulo, i32, i64, u32, u64);
|
||||
|
||||
reg_un!(engine, "-", neg, i32, i64, f32, f64);
|
||||
reg_un!(engine, "!", not, bool);
|
||||
|
@ -168,6 +168,8 @@ pub enum Token {
|
||||
LeftShift,
|
||||
RightShift,
|
||||
XOr,
|
||||
Modulo,
|
||||
ModuloEquals,
|
||||
LexErr(LexError),
|
||||
}
|
||||
|
||||
@ -626,6 +628,15 @@ impl<'a> TokenIterator<'a> {
|
||||
}
|
||||
_ => return Some(Token::XOr)
|
||||
}
|
||||
},
|
||||
'%' => {
|
||||
match self.char_stream.peek() {
|
||||
Some(&'=') => {
|
||||
self.char_stream.next();
|
||||
return Some(Token::ModuloEquals);
|
||||
}
|
||||
_ => return Some(Token::Modulo)
|
||||
}
|
||||
}
|
||||
_x if _x.is_whitespace() => (),
|
||||
_ => return Some(Token::LexErr(LexError::UnexpectedChar)),
|
||||
@ -664,11 +675,13 @@ fn get_precedence(token: &Token) -> i32 {
|
||||
| Token::RightShiftEquals
|
||||
| Token::AndEquals
|
||||
| Token::OrEquals
|
||||
| Token::XOrEquals => 10,
|
||||
| Token::XOrEquals
|
||||
| Token::ModuloEquals => 10,
|
||||
Token::Or
|
||||
| Token::XOr
|
||||
| Token::Pipe => 11,
|
||||
Token::And => 12,
|
||||
Token::And
|
||||
| Token::Ampersand => 12,
|
||||
Token::LessThan
|
||||
| Token::LessThanEqual
|
||||
| Token::GreaterThan
|
||||
@ -681,6 +694,7 @@ fn get_precedence(token: &Token) -> i32 {
|
||||
| Token::Multiply => 40,
|
||||
Token::LeftShift
|
||||
| Token::RightShift => 50,
|
||||
Token::Modulo => 60,
|
||||
Token::Period => 100,
|
||||
_ => -1,
|
||||
}
|
||||
@ -947,6 +961,15 @@ fn parse_binop<'a>(input: &mut Peekable<TokenIterator<'a>>,
|
||||
Box::new(Expr::FnCall(">>".to_string(), vec![lhs_copy, rhs]))
|
||||
)
|
||||
},
|
||||
Token::Ampersand => Expr::FnCall("&".to_string(), vec![lhs_curr, rhs]),
|
||||
Token::Modulo => Expr::FnCall("%".to_string(), vec![lhs_curr, rhs]),
|
||||
Token::ModuloEquals => {
|
||||
let lhs_copy = lhs_curr.clone();
|
||||
Expr::Assignment(
|
||||
Box::new(lhs_curr),
|
||||
Box::new(Expr::FnCall("%".to_string(), vec![lhs_copy, rhs]))
|
||||
)
|
||||
}
|
||||
_ => return Err(ParseError::UnknownOperator),
|
||||
};
|
||||
}
|
||||
|
52
src/tests.rs
52
src/tests.rs
@ -688,4 +688,56 @@ fn test_right_shift_equals() {
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_modulo_equals() {
|
||||
let mut engine = Engine::new();
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("let x = 10; x %= 4; x") {
|
||||
assert_eq!(result, 2);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_binary_ops() {
|
||||
let mut engine = Engine::new();
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 % 4") {
|
||||
assert_eq!(result, 2);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 << 4") {
|
||||
assert_eq!(result, 160);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 >> 4") {
|
||||
assert_eq!(result, 0);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 & 4") {
|
||||
assert_eq!(result, 0);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 | 4") {
|
||||
assert_eq!(result, 14);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("10 ^ 4") {
|
||||
assert_eq!(result, 14);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user