candidate increment/decrement implementation
This commit is contained in:
parent
0b9865b24c
commit
e042e1e31d
@ -152,6 +152,8 @@ pub enum Token {
|
|||||||
Fn,
|
Fn,
|
||||||
Break,
|
Break,
|
||||||
Return,
|
Return,
|
||||||
|
PlusEquals,
|
||||||
|
MinusEquals,
|
||||||
LexErr(LexError),
|
LexErr(LexError),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,8 +352,24 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
')' => return Some(Token::RParen),
|
')' => return Some(Token::RParen),
|
||||||
'[' => return Some(Token::LSquare),
|
'[' => return Some(Token::LSquare),
|
||||||
']' => return Some(Token::RSquare),
|
']' => 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::Multiply),
|
||||||
'/' => return Some(Token::Divide),
|
'/' => return Some(Token::Divide),
|
||||||
';' => return Some(Token::Semicolon),
|
';' => return Some(Token::Semicolon),
|
||||||
@ -427,7 +445,9 @@ pub fn lex(input: &str) -> TokenIterator {
|
|||||||
|
|
||||||
fn get_precedence(token: &Token) -> i32 {
|
fn get_precedence(token: &Token) -> i32 {
|
||||||
match *token {
|
match *token {
|
||||||
Token::Equals => 10,
|
Token::Equals
|
||||||
|
| Token::PlusEquals
|
||||||
|
| Token::MinusEquals => 10,
|
||||||
Token::Or => 11,
|
Token::Or => 11,
|
||||||
Token::And => 12,
|
Token::And => 12,
|
||||||
Token::LessThan
|
Token::LessThan
|
||||||
@ -458,7 +478,7 @@ fn parse_call_expr<'a>(id: String,
|
|||||||
input: &mut Peekable<TokenIterator<'a>>)
|
input: &mut Peekable<TokenIterator<'a>>)
|
||||||
-> Result<Expr, ParseError> {
|
-> Result<Expr, ParseError> {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
|
||||||
if let Some(&Token::RParen) = input.peek() {
|
if let Some(&Token::RParen) = input.peek() {
|
||||||
input.next();
|
input.next();
|
||||||
return Ok(Expr::FnCall(id, args));
|
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::Multiply => Expr::FnCall("*".to_string(), vec![lhs_curr, rhs]),
|
||||||
Token::Divide => 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::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::Period => Expr::Dot(Box::new(lhs_curr), Box::new(rhs)),
|
||||||
Token::EqualTo => Expr::FnCall("==".to_string(), vec![lhs_curr, rhs]),
|
Token::EqualTo => Expr::FnCall("==".to_string(), vec![lhs_curr, rhs]),
|
||||||
Token::NotEqualTo => 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);
|
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