candidate increment/decrement implementation
This commit is contained in:
parent
0b9865b24c
commit
e042e1e31d
@ -152,6 +152,8 @@ pub enum Token {
|
||||
Fn,
|
||||
Break,
|
||||
Return,
|
||||
PlusEquals,
|
||||
MinusEquals,
|
||||
LexErr(LexError),
|
||||
}
|
||||
|
||||
@ -350,8 +352,24 @@ impl<'a> Iterator for TokenIterator<'a> {
|
||||
')' => return Some(Token::RParen),
|
||||
'[' => return Some(Token::LSquare),
|
||||
']' => return Some(Token::RSquare),
|
||||
'+' => return Some(Token::Plus),
|
||||
'-' => return Some(Token::Minus),
|
||||
'+' => {
|
||||
return match self.char_stream.peek() {
|
||||
Some(&'=') => {
|
||||
self.char_stream.next();
|
||||
Some(Token::PlusEquals)
|
||||
},
|
||||
_ => Some(Token::Plus)
|
||||
}
|
||||
},
|
||||
'-' => {
|
||||
return match self.char_stream.peek() {
|
||||
Some(&'=') => {
|
||||
self.char_stream.next();
|
||||
Some(Token::MinusEquals)
|
||||
},
|
||||
_ => Some(Token::Minus)
|
||||
}
|
||||
},
|
||||
'*' => return Some(Token::Multiply),
|
||||
'/' => return Some(Token::Divide),
|
||||
';' => return Some(Token::Semicolon),
|
||||
@ -427,7 +445,9 @@ pub fn lex(input: &str) -> TokenIterator {
|
||||
|
||||
fn get_precedence(token: &Token) -> i32 {
|
||||
match *token {
|
||||
Token::Equals => 10,
|
||||
Token::Equals
|
||||
| Token::PlusEquals
|
||||
| Token::MinusEquals => 10,
|
||||
Token::Or => 11,
|
||||
Token::And => 12,
|
||||
Token::LessThan
|
||||
@ -458,7 +478,7 @@ fn parse_call_expr<'a>(id: String,
|
||||
input: &mut Peekable<TokenIterator<'a>>)
|
||||
-> Result<Expr, ParseError> {
|
||||
let mut args = Vec::new();
|
||||
|
||||
|
||||
if let Some(&Token::RParen) = input.peek() {
|
||||
input.next();
|
||||
return Ok(Expr::FnCall(id, args));
|
||||
@ -609,6 +629,20 @@ fn parse_binop<'a>(input: &mut Peekable<TokenIterator<'a>>,
|
||||
Token::Multiply => Expr::FnCall("*".to_string(), vec![lhs_curr, rhs]),
|
||||
Token::Divide => Expr::FnCall("/".to_string(), vec![lhs_curr, rhs]),
|
||||
Token::Equals => Expr::Assignment(Box::new(lhs_curr), Box::new(rhs)),
|
||||
Token::PlusEquals => {
|
||||
let lhs_copy = lhs_curr.clone();
|
||||
Expr::Assignment(
|
||||
Box::new(lhs_curr),
|
||||
Box::new(Expr::FnCall("+".to_string(), vec![lhs_copy, rhs]))
|
||||
)
|
||||
},
|
||||
Token::MinusEquals => {
|
||||
let lhs_copy = lhs_curr.clone();
|
||||
Expr::Assignment(
|
||||
Box::new(lhs_curr),
|
||||
Box::new(Expr::FnCall("-".to_string(), vec![lhs_copy, rhs]))
|
||||
)
|
||||
},
|
||||
Token::Period => Expr::Dot(Box::new(lhs_curr), Box::new(rhs)),
|
||||
Token::EqualTo => Expr::FnCall("==".to_string(), vec![lhs_curr, rhs]),
|
||||
Token::NotEqualTo => Expr::FnCall("!=".to_string(), vec![lhs_curr, rhs]),
|
||||
|
34
src/tests.rs
34
src/tests.rs
@ -401,3 +401,37 @@ fn test_array_with_structs() {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_increment() {
|
||||
let mut engine = Engine::new();
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("let x = 1; x += 2; x") {
|
||||
assert_eq!(result, 3);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(result) = engine.eval::<String>("let s = \"test\"; s += \"ing\"; s") {
|
||||
assert_eq!(result, "testing".to_owned());
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decrement() {
|
||||
let mut engine = Engine::new();
|
||||
|
||||
if let Ok(result) = engine.eval::<i64>("let x = 10; x -= 7; x") {
|
||||
assert_eq!(result, 3);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
if let Ok(_) = engine.eval::<String>("let s = \"test\"; s -= \"ing\"; s") {
|
||||
assert!(false);
|
||||
} else {
|
||||
assert!(true);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user