mirror of https://github.com/rm-dr/daisy
parent
579f7f2ece
commit
145084b88f
|
@ -79,7 +79,7 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
|
|
||||||
// Tokenize input.
|
// Tokenize input.
|
||||||
// Fail if we encounter invalid characters.
|
// Fail if we encounter invalid characters.
|
||||||
let mut exp = match parser::tokenize::tokenize(&input) {
|
let mut g = match parser::tokenize::tokenize(&input) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
continue;
|
continue;
|
||||||
|
@ -92,9 +92,9 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
stdout.reset()?;
|
stdout.reset()?;
|
||||||
write!(stdout, "Got {input}\n\n\n")?;
|
write!(stdout, "Got {input}\n\n\n")?;
|
||||||
|
|
||||||
parser::treefold::treefold(&mut exp).expect("Could not fold");
|
parser::parse(&mut g).expect("Could not fold");
|
||||||
|
|
||||||
writeln!(stdout, "Tokenized: {exp:#?}")?;
|
writeln!(stdout, "Tokenized: {g:#?}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(stdout, "Exiting.")?;
|
writeln!(stdout, "Exiting.")?;
|
||||||
|
|
|
@ -1,2 +1,14 @@
|
||||||
pub mod tokenize;
|
pub mod tokenize;
|
||||||
pub mod treefold;
|
mod replace_words;
|
||||||
|
mod fold_operators;
|
||||||
|
|
||||||
|
use crate::parser::tokenize::Token;
|
||||||
|
use crate::parser::replace_words::replace_words;
|
||||||
|
use crate::parser::fold_operators::fold_operators;
|
||||||
|
|
||||||
|
pub fn parse(g: &mut Token) -> Result<(), ()> {
|
||||||
|
replace_words(g)?;
|
||||||
|
fold_operators(g)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use crate::parser::tokenize::Token;
|
||||||
|
|
||||||
|
enum OperatorType {
|
||||||
|
Binary, // A binary operator, like a + b
|
||||||
|
UnaryLeft, // A left operator, like a!
|
||||||
|
UnaryRight // A right operator, like -a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_operators_once(
|
||||||
|
g_main: &mut Token, // Must be a group
|
||||||
|
op_type: &OperatorType,
|
||||||
|
check: fn(&str) -> bool,
|
||||||
|
new_token: fn(&str, VecDeque<Token>) -> Token,
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
|
||||||
|
// Groups to process
|
||||||
|
let mut t_vec: VecDeque<&mut Token> = VecDeque::with_capacity(32);
|
||||||
|
t_vec.push_back(g_main);
|
||||||
|
|
||||||
|
while t_vec.len() > 0 {
|
||||||
|
|
||||||
|
// The group we're currently working with
|
||||||
|
let g: &mut Token = t_vec.pop_front().unwrap();
|
||||||
|
let g_inner: &mut VecDeque<Token> = match g {
|
||||||
|
Token::PreGroup(ref mut x) => x,
|
||||||
|
_ => panic!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut new: VecDeque<Token> = VecDeque::with_capacity(8);
|
||||||
|
|
||||||
|
// Build new group array
|
||||||
|
while g_inner.len() > 0 {
|
||||||
|
let t: Token = match g_inner.pop_front() {
|
||||||
|
Some(o) => o,
|
||||||
|
None => break
|
||||||
|
};
|
||||||
|
|
||||||
|
let s: &str;
|
||||||
|
if let Token::PreOperator(ref x) = t {
|
||||||
|
s = x;
|
||||||
|
} else {
|
||||||
|
new.push_back(t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if check(s) {
|
||||||
|
match op_type {
|
||||||
|
OperatorType::UnaryLeft => {
|
||||||
|
let mut last: Token = new.pop_back().unwrap();
|
||||||
|
|
||||||
|
if let Token::PreGroup(_) = last {
|
||||||
|
fold_operators_once(&mut last, op_type, check, new_token).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(1);
|
||||||
|
new_token_args.push_back(last);
|
||||||
|
new.push_back(new_token(s, new_token_args));
|
||||||
|
},
|
||||||
|
OperatorType::UnaryRight => {
|
||||||
|
let mut next: Token = g_inner.pop_front().unwrap();
|
||||||
|
|
||||||
|
if let Token::PreGroup(_) = next {
|
||||||
|
fold_operators_once(&mut next, op_type, check, new_token).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(1);
|
||||||
|
new_token_args.push_back(next);
|
||||||
|
new.push_back(new_token(s, new_token_args));
|
||||||
|
},
|
||||||
|
OperatorType::Binary => {
|
||||||
|
let mut last: Token = new.pop_back().unwrap();
|
||||||
|
let mut next: Token = g_inner.pop_front().unwrap();
|
||||||
|
|
||||||
|
// TODO: append to t_vec and do this without recursion.
|
||||||
|
if let Token::PreGroup(_) = last {
|
||||||
|
fold_operators_once(&mut last, op_type, check, new_token).unwrap();
|
||||||
|
}
|
||||||
|
if let Token::PreGroup(_) = next {
|
||||||
|
fold_operators_once(&mut next, op_type, check, new_token).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(2);
|
||||||
|
new_token_args.push_back(last);
|
||||||
|
new_token_args.push_back(next);
|
||||||
|
new.push_back(new_token(s, new_token_args));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
new.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*g_inner = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fold_operators(exp: &mut Token) -> Result<(), ()> {
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::UnaryLeft,
|
||||||
|
|s| s=="!",
|
||||||
|
|_s, x| Token::Factorial(x)
|
||||||
|
)?;
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::UnaryRight,
|
||||||
|
|s| s=="neg",
|
||||||
|
|_s, x| Token::Negative(x)
|
||||||
|
)?;
|
||||||
|
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::Binary,
|
||||||
|
|s| s=="^",
|
||||||
|
|_s, x| Token::Power(x)
|
||||||
|
)?;
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::Binary,
|
||||||
|
|s| s=="%",
|
||||||
|
|_s, x| Token::Modulo(x)
|
||||||
|
)?;
|
||||||
|
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::Binary,
|
||||||
|
|s| s=="*" || s == "/",
|
||||||
|
|s, x| match s {
|
||||||
|
"*" => Token::Multiply(x),
|
||||||
|
"/" => Token::Divide(x),
|
||||||
|
_=>panic!()
|
||||||
|
}
|
||||||
|
)?;
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::Binary,
|
||||||
|
|s| s=="+" || s == "-",
|
||||||
|
|s, x| match s {
|
||||||
|
"+" => Token::Add(x),
|
||||||
|
"-" => Token::Subtract(x),
|
||||||
|
_=>panic!()
|
||||||
|
}
|
||||||
|
)?;
|
||||||
|
|
||||||
|
|
||||||
|
fold_operators_once(
|
||||||
|
exp, &OperatorType::Binary,
|
||||||
|
|s| s=="mod",
|
||||||
|
|_s, x| Token::Modulo(x)
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use crate::parser::tokenize::Token;
|
||||||
|
|
||||||
|
pub fn replace_words(g: &mut Token) -> Result<(), ()> {
|
||||||
|
let g_inner: &mut VecDeque<Token> = match g {
|
||||||
|
Token::PreGroup(ref mut x) => x,
|
||||||
|
_ => panic!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut new: VecDeque<Token> = VecDeque::with_capacity(8);
|
||||||
|
|
||||||
|
while g_inner.len() > 0 {
|
||||||
|
let mut t: Token = match g_inner.pop_front() {
|
||||||
|
Some(o) => o,
|
||||||
|
None => break
|
||||||
|
};
|
||||||
|
|
||||||
|
match t {
|
||||||
|
Token::PreGroup(_) => {
|
||||||
|
replace_words(&mut t)?;
|
||||||
|
new.push_back(t);
|
||||||
|
},
|
||||||
|
Token::PreWord(ref s) => {
|
||||||
|
if s == "to" {
|
||||||
|
new.push_back(Token::PreOperator(String::from("to")));
|
||||||
|
} else if s == "mod" {
|
||||||
|
new.push_back(Token::PreOperator(String::from("mod")));
|
||||||
|
} else {
|
||||||
|
new.push_back(t);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => { new.push_back(t); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
*g_inner = new;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
|
@ -6,22 +6,22 @@ use std::collections::VecDeque;
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
|
|
||||||
// Only used after tokenizing
|
// Only used after tokenizing
|
||||||
Negative,
|
PreGroup(VecDeque<Token>),
|
||||||
Factorial,
|
PreOperator(String),
|
||||||
Group(VecDeque<Token>), // Will be expanded during tree folding
|
PreNumber(String),
|
||||||
Operator(String), // Will become Ops during tree folding
|
PreWord(String),
|
||||||
|
|
||||||
// Used in both
|
|
||||||
Number(String),
|
|
||||||
Word(String),
|
|
||||||
|
|
||||||
// Only used in tree
|
// Only used in tree
|
||||||
Multiply(VecDeque<Token>),
|
Multiply(VecDeque<Token>),
|
||||||
Divide(VecDeque<Token>),
|
Divide(VecDeque<Token>),
|
||||||
Add(VecDeque<Token>),
|
Add(VecDeque<Token>),
|
||||||
Subtract(VecDeque<Token>),
|
Subtract(VecDeque<Token>),
|
||||||
Fac(VecDeque<Token>),
|
Factorial(VecDeque<Token>),
|
||||||
Neg(VecDeque<Token>)
|
Negative(VecDeque<Token>),
|
||||||
|
Power(VecDeque<Token>),
|
||||||
|
Modulo(VecDeque<Token>),
|
||||||
|
|
||||||
|
//Function(String, VecDeque<Token>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,21 +37,21 @@ pub enum Token {
|
||||||
pub fn tokenize(input: &String) -> Result<Token, ()> {
|
pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
let mut t: Option<Token> = None; // The current token we're reading
|
let mut t: Option<Token> = None; // The current token we're reading
|
||||||
let mut g: Vec<Token> = Vec::with_capacity(8); // Vector of "grouping levels"
|
let mut g: Vec<Token> = Vec::with_capacity(8); // Vector of "grouping levels"
|
||||||
g.push(Token::Group(VecDeque::with_capacity(8)));
|
g.push(Token::PreGroup(VecDeque::with_capacity(8)));
|
||||||
|
|
||||||
|
|
||||||
for c in input.chars() {
|
for c in input.chars() {
|
||||||
|
|
||||||
// The grouping level we're on now
|
// The grouping level we're on now
|
||||||
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
||||||
Token::Group(ref mut x) => x,
|
Token::PreGroup(ref mut x) => x,
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
};
|
};
|
||||||
|
|
||||||
match c {
|
match c {
|
||||||
'!' => {
|
'!' => {
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
||||||
g_now.push_back(Token::Factorial);
|
g_now.push_back(Token::PreOperator(String::from("!")));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Minus sign can be both a Negative and an Operator.
|
// Minus sign can be both a Negative and an Operator.
|
||||||
|
@ -61,14 +61,14 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
match g_now.back() {
|
match g_now.back() {
|
||||||
// If previous token was any of the following,
|
// If previous token was any of the following,
|
||||||
// this is the "minus" operator
|
// this is the "minus" operator
|
||||||
Some(Token::Number(_)) |
|
Some(Token::PreNumber(_)) |
|
||||||
Some(Token::Group(_)) |
|
Some(Token::PreGroup(_)) |
|
||||||
Some(Token::Word(_)) => {
|
Some(Token::PreWord(_)) => {
|
||||||
g_now.push_back(Token::Operator(String::from(c)));
|
g_now.push_back(Token::PreOperator(String::from(c)));
|
||||||
},
|
},
|
||||||
|
|
||||||
// Otherwise, this is a negative sign.
|
// Otherwise, this is a negative sign.
|
||||||
_ => { g_now.push_back(Token::Negative); }
|
_ => { g_now.push_back(Token::PreOperator(String::from("neg"))); }
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
match &mut t {
|
match &mut t {
|
||||||
// If we're already building a number,
|
// If we're already building a number,
|
||||||
// append.
|
// append.
|
||||||
Some(Token::Number(val)) => {
|
Some(Token::PreNumber(val)) => {
|
||||||
val.push(if c == ',' {'.'} else {c});
|
val.push(if c == ',' {'.'} else {c});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
// previous token and start one.
|
// previous token and start one.
|
||||||
_ => {
|
_ => {
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); }
|
if t.is_some() { g_now.push_back(t.unwrap()); }
|
||||||
t = Some(Token::Number(String::from(c)));
|
t = Some(Token::PreNumber(String::from(c)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -97,7 +97,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
match &mut t {
|
match &mut t {
|
||||||
// If we're already building a number,
|
// If we're already building a number,
|
||||||
// append.
|
// append.
|
||||||
Some(Token::Word(val)) => {
|
Some(Token::PreWord(val)) => {
|
||||||
val.push(c);
|
val.push(c);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
// previous token and start one.
|
// previous token and start one.
|
||||||
_ => {
|
_ => {
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); }
|
if t.is_some() { g_now.push_back(t.unwrap()); }
|
||||||
t = Some(Token::Word(String::from(c)));
|
t = Some(Token::PreWord(String::from(c)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -113,24 +113,28 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
|
|
||||||
// Operation
|
// Operation
|
||||||
// Always one character
|
// Always one character
|
||||||
'+' | '*' | '/' | '^' => {
|
'+' |
|
||||||
|
'*' |
|
||||||
|
'/' |
|
||||||
|
'^' |
|
||||||
|
'%' => {
|
||||||
// Finalize previous token
|
// Finalize previous token
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
||||||
g_now.push_back(Token::Operator(String::from(c)));
|
g_now.push_back(Token::PreOperator(String::from(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
// Always one character
|
// Always one character
|
||||||
'(' => {
|
'(' => {
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
||||||
g.push(Token::Group(VecDeque::with_capacity(8)));
|
g.push(Token::PreGroup(VecDeque::with_capacity(8)));
|
||||||
},
|
},
|
||||||
')' => {
|
')' => {
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
if t.is_some() { g_now.push_back(t.unwrap()); t = None; }
|
||||||
let new_group: Token = g.pop().unwrap();
|
let new_group: Token = g.pop().unwrap();
|
||||||
|
|
||||||
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
||||||
Token::Group(ref mut x) => x,
|
Token::PreGroup(ref mut x) => x,
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,7 +153,7 @@ pub fn tokenize(input: &String) -> Result<Token, ()> {
|
||||||
|
|
||||||
|
|
||||||
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
let g_now: &mut VecDeque<Token> = match g.last_mut().unwrap() {
|
||||||
Token::Group(ref mut x) => x,
|
Token::PreGroup(ref mut x) => x,
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
};
|
};
|
||||||
if t.is_some() { g_now.push_back(t.unwrap()); }
|
if t.is_some() { g_now.push_back(t.unwrap()); }
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
use crate::parser::tokenize::Token;
|
|
||||||
|
|
||||||
fn treefold_one(
|
|
||||||
exp: &mut Token, // Must be a group
|
|
||||||
check: fn(&Token) -> bool,
|
|
||||||
op_type: u8,
|
|
||||||
new_token: fn(VecDeque<Token>) -> Token,
|
|
||||||
) -> Result<(), ()> {
|
|
||||||
|
|
||||||
// Groups to process
|
|
||||||
let mut t_vec: VecDeque<&mut Token> = VecDeque::with_capacity(32);
|
|
||||||
t_vec.push_back(exp);
|
|
||||||
|
|
||||||
while t_vec.len() > 0 {
|
|
||||||
|
|
||||||
// The group we're currently working with
|
|
||||||
let g: &mut Token = t_vec.pop_front().unwrap();
|
|
||||||
let g_inner: &mut VecDeque<Token> = match g {
|
|
||||||
Token::Group(ref mut x) => x,
|
|
||||||
_ => panic!()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut new: VecDeque<Token> = VecDeque::with_capacity(8);
|
|
||||||
|
|
||||||
// Build new group array
|
|
||||||
while g_inner.len() > 0 {
|
|
||||||
let t: Token = match g_inner.pop_front() {
|
|
||||||
Some(o) => o,
|
|
||||||
None => break
|
|
||||||
};
|
|
||||||
|
|
||||||
if check(&t) {
|
|
||||||
match op_type {
|
|
||||||
0 => {
|
|
||||||
let mut last: Token = new.pop_back().unwrap();
|
|
||||||
|
|
||||||
if let Token::Group(_) = last {
|
|
||||||
treefold_one(&mut last, check, op_type, new_token).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(1);
|
|
||||||
new_token_args.push_back(last);
|
|
||||||
new.push_back(new_token(new_token_args));
|
|
||||||
},
|
|
||||||
1 => {
|
|
||||||
let mut next: Token = g_inner.pop_front().unwrap().clone();
|
|
||||||
|
|
||||||
if let Token::Group(_) = next {
|
|
||||||
treefold_one(&mut next, check, op_type, new_token).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(1);
|
|
||||||
new_token_args.push_back(next);
|
|
||||||
new.push_back(new_token(new_token_args));
|
|
||||||
},
|
|
||||||
2 => {
|
|
||||||
let mut last: Token = new.pop_back().unwrap();
|
|
||||||
let mut next: Token = g_inner.pop_front().unwrap().clone();
|
|
||||||
|
|
||||||
// TODO: append to t_vec, do this without recursion.
|
|
||||||
if let Token::Group(_) = last {
|
|
||||||
treefold_one(&mut last, check, op_type, new_token).unwrap();
|
|
||||||
}
|
|
||||||
if let Token::Group(_) = next {
|
|
||||||
treefold_one(&mut next, check, op_type, new_token).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(2);
|
|
||||||
new_token_args.push_back(last);
|
|
||||||
new_token_args.push_back(next);
|
|
||||||
new.push_back(new_token(new_token_args));
|
|
||||||
},
|
|
||||||
_ => panic!()
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
new.push_back(t.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*g_inner = new;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn is_mult(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Operator(s) => {s == "*"},
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_mult(v: VecDeque<Token>) -> Token { Token::Multiply(v) }
|
|
||||||
|
|
||||||
fn is_add(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Operator(s) => {s == "+"},
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_add(v: VecDeque<Token>) -> Token { Token::Add(v) }
|
|
||||||
|
|
||||||
fn is_div(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Operator(s) => {s == "/"},
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_div(v: VecDeque<Token>) -> Token { Token::Divide(v) }
|
|
||||||
|
|
||||||
fn is_sub(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Operator(s) => {s == "-"},
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_sub(v: VecDeque<Token>) -> Token { Token::Subtract(v) }
|
|
||||||
|
|
||||||
fn is_fac(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Factorial => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_fac(v: VecDeque<Token>) -> Token { Token::Fac(v) }
|
|
||||||
|
|
||||||
fn is_neg(t: &Token) -> bool {
|
|
||||||
match t {
|
|
||||||
Token::Negative => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn new_neg(v: VecDeque<Token>) -> Token { Token::Neg(v) }
|
|
||||||
|
|
||||||
pub fn treefold(exp: &mut Token) -> Result<(), ()> {
|
|
||||||
treefold_one(exp, is_fac, 0, new_fac)?;
|
|
||||||
treefold_one(exp, is_neg, 1, new_neg)?;
|
|
||||||
treefold_one(exp, is_mult, 2, new_mult)?;
|
|
||||||
treefold_one(exp, is_div, 2, new_div)?;
|
|
||||||
treefold_one(exp, is_add, 2, new_add)?;
|
|
||||||
treefold_one(exp, is_sub, 2, new_sub)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
Loading…
Reference in New Issue