add modulo operator
This commit is contained in:
@@ -90,6 +90,13 @@ impl<I: Iterator<Item = Result<ParseTree, ParseError>>> Executor<I> {
|
||||
(Value::Float(x), Value::Float(y)) => Ok(Value::Float(x.powf(y))),
|
||||
_ => Err(RuntimeError::NoOverloadForTypes),
|
||||
},
|
||||
ParseTree::Mod(x, y) => match (self.exec(*x, locals, in_function)?, self.exec(*y, locals, in_function)?) {
|
||||
(Value::Int(x), Value::Int(y)) => Ok(Value::Int(x % y)),
|
||||
(Value::Float(x), Value::Int(y)) => Ok(Value::Float(x % y as f64)),
|
||||
(Value::Int(x), Value::Float(y)) => Ok(Value::Float(x as f64 % y)),
|
||||
(Value::Float(x), Value::Float(y)) => Ok(Value::Float(x % y)),
|
||||
_ => Err(RuntimeError::NoOverloadForTypes),
|
||||
},
|
||||
ParseTree::EqualTo(x, y) => match (self.exec(*x, locals, in_function)?, self.exec(*y, locals, in_function)?) {
|
||||
(Value::Int(x), Value::Int(y)) => Ok(Value::Bool(x == y)),
|
||||
(Value::Int(x), Value::Float(y)) => Ok(Value::Bool(x as f64 == y)),
|
||||
@@ -257,3 +264,11 @@ impl<I: Iterator<Item = Result<ParseTree, ParseError>>> Iterator for Executor<I>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn recursion() {
|
||||
let program = ": countdown i ?? <= i i 0 countdown - i 1";
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ pub enum ParseTree {
|
||||
Mul(Box<ParseTree>, Box<ParseTree>),
|
||||
Div(Box<ParseTree>, Box<ParseTree>),
|
||||
Exp(Box<ParseTree>, Box<ParseTree>),
|
||||
Mod(Box<ParseTree>, Box<ParseTree>),
|
||||
|
||||
// Boolean Operations
|
||||
EqualTo(Box<ParseTree>, Box<ParseTree>),
|
||||
@@ -118,6 +119,10 @@ impl ParseTree {
|
||||
Box::new(ParseTree::parse(tokens, globals, locals)?),
|
||||
Box::new(ParseTree::parse(tokens, globals, locals)?)
|
||||
)),
|
||||
Op::Mod => Ok(ParseTree::Mod(
|
||||
Box::new(ParseTree::parse(tokens, globals, locals)?),
|
||||
Box::new(ParseTree::parse(tokens, globals, locals)?)
|
||||
)),
|
||||
Op::Equ | Op::LazyEqu | Op::GlobalEqu | Op::LazyGlobalEqu => {
|
||||
let token = tokens.next()
|
||||
.ok_or(ParseError::UnexpectedEndInput)?
|
||||
|
||||
@@ -40,6 +40,7 @@ pub enum Op {
|
||||
Div,
|
||||
Exp,
|
||||
Equ,
|
||||
Mod,
|
||||
LazyEqu,
|
||||
GlobalEqu,
|
||||
LazyGlobalEqu,
|
||||
@@ -90,8 +91,9 @@ impl Token {
|
||||
"+" => Ok(Token::Operator(Op::Add)),
|
||||
"-" => Ok(Token::Operator(Op::Sub)),
|
||||
"*" => Ok(Token::Operator(Op::Mul)),
|
||||
"**" => Ok(Token::Operator(Op::Exp)),
|
||||
"/" => Ok(Token::Operator(Op::Div)),
|
||||
"**" => Ok(Token::Operator(Op::Exp)),
|
||||
"%" => Ok(Token::Operator(Op::Mod)),
|
||||
"=" => Ok(Token::Operator(Op::Equ)),
|
||||
"." => Ok(Token::Operator(Op::LazyEqu)),
|
||||
"=>" => Ok(Token::Operator(Op::GlobalEqu)),
|
||||
@@ -170,8 +172,8 @@ impl<R: BufRead> std::iter::Iterator for Tokenizer<R> {
|
||||
let mut input = String::new();
|
||||
|
||||
match self.reader.read_to_string(&mut input) {
|
||||
Ok(0) => return None,
|
||||
Err(e) => return Some(Err(TokenizeError::IO(e))),
|
||||
Ok(0) => None,
|
||||
Err(e) => Some(Err(TokenizeError::IO(e))),
|
||||
_ => {
|
||||
let re = regex::Regex::new(r#"[a-zA-Z0-9\.'_]+|[`~!@#\$%\^&\*\(\)\+-=\[\]\{\}\\|;:,<\.>/\?]+|("[^"]+")"#).expect("This wont fail promise :3");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user