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))),
|
(Value::Float(x), Value::Float(y)) => Ok(Value::Float(x.powf(y))),
|
||||||
_ => Err(RuntimeError::NoOverloadForTypes),
|
_ => 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)?) {
|
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::Int(y)) => Ok(Value::Bool(x == y)),
|
||||||
(Value::Int(x), Value::Float(y)) => Ok(Value::Bool(x as f64 == 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>),
|
Mul(Box<ParseTree>, Box<ParseTree>),
|
||||||
Div(Box<ParseTree>, Box<ParseTree>),
|
Div(Box<ParseTree>, Box<ParseTree>),
|
||||||
Exp(Box<ParseTree>, Box<ParseTree>),
|
Exp(Box<ParseTree>, Box<ParseTree>),
|
||||||
|
Mod(Box<ParseTree>, Box<ParseTree>),
|
||||||
|
|
||||||
// Boolean Operations
|
// Boolean Operations
|
||||||
EqualTo(Box<ParseTree>, Box<ParseTree>),
|
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)?),
|
||||||
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 => {
|
Op::Equ | Op::LazyEqu | Op::GlobalEqu | Op::LazyGlobalEqu => {
|
||||||
let token = tokens.next()
|
let token = tokens.next()
|
||||||
.ok_or(ParseError::UnexpectedEndInput)?
|
.ok_or(ParseError::UnexpectedEndInput)?
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ pub enum Op {
|
|||||||
Div,
|
Div,
|
||||||
Exp,
|
Exp,
|
||||||
Equ,
|
Equ,
|
||||||
|
Mod,
|
||||||
LazyEqu,
|
LazyEqu,
|
||||||
GlobalEqu,
|
GlobalEqu,
|
||||||
LazyGlobalEqu,
|
LazyGlobalEqu,
|
||||||
@@ -90,8 +91,9 @@ impl Token {
|
|||||||
"+" => Ok(Token::Operator(Op::Add)),
|
"+" => Ok(Token::Operator(Op::Add)),
|
||||||
"-" => Ok(Token::Operator(Op::Sub)),
|
"-" => Ok(Token::Operator(Op::Sub)),
|
||||||
"*" => Ok(Token::Operator(Op::Mul)),
|
"*" => Ok(Token::Operator(Op::Mul)),
|
||||||
"**" => Ok(Token::Operator(Op::Exp)),
|
|
||||||
"/" => Ok(Token::Operator(Op::Div)),
|
"/" => Ok(Token::Operator(Op::Div)),
|
||||||
|
"**" => Ok(Token::Operator(Op::Exp)),
|
||||||
|
"%" => Ok(Token::Operator(Op::Mod)),
|
||||||
"=" => Ok(Token::Operator(Op::Equ)),
|
"=" => Ok(Token::Operator(Op::Equ)),
|
||||||
"." => Ok(Token::Operator(Op::LazyEqu)),
|
"." => Ok(Token::Operator(Op::LazyEqu)),
|
||||||
"=>" => Ok(Token::Operator(Op::GlobalEqu)),
|
"=>" => Ok(Token::Operator(Op::GlobalEqu)),
|
||||||
@@ -170,8 +172,8 @@ impl<R: BufRead> std::iter::Iterator for Tokenizer<R> {
|
|||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
|
|
||||||
match self.reader.read_to_string(&mut input) {
|
match self.reader.read_to_string(&mut input) {
|
||||||
Ok(0) => return None,
|
Ok(0) => None,
|
||||||
Err(e) => return Some(Err(TokenizeError::IO(e))),
|
Err(e) => Some(Err(TokenizeError::IO(e))),
|
||||||
_ => {
|
_ => {
|
||||||
let re = regex::Regex::new(r#"[a-zA-Z0-9\.'_]+|[`~!@#\$%\^&\*\(\)\+-=\[\]\{\}\\|;:,<\.>/\?]+|("[^"]+")"#).expect("This wont fail promise :3");
|
let re = regex::Regex::new(r#"[a-zA-Z0-9\.'_]+|[`~!@#\$%\^&\*\(\)\+-=\[\]\{\}\\|;:,<\.>/\?]+|("[^"]+")"#).expect("This wont fail promise :3");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user