mirror of https://github.com/rm-dr/daisy
Added sin function and expression printing
parent
3d5dcf0694
commit
3126b4c616
18
src/main.rs
18
src/main.rs
|
@ -80,13 +80,13 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
if let Key::Char(q) = c.as_ref().unwrap() {
|
if let Key::Char(q) = c.as_ref().unwrap() {
|
||||||
match q {
|
match q {
|
||||||
'\n' => {
|
'\n' => {
|
||||||
let s = pb.enter();
|
let in_str = pb.enter();
|
||||||
write!(stdout, "\r\n")?;
|
write!(stdout, "\r\n")?;
|
||||||
if s == "" { break; }
|
if in_str == "" { break; }
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
RawTerminal::suspend_raw_mode(&stdout)?;
|
RawTerminal::suspend_raw_mode(&stdout)?;
|
||||||
let g = parser::parse(&s);
|
let g = parser::parse(&in_str);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
RawTerminal::activate_raw_mode(&stdout)?;
|
RawTerminal::activate_raw_mode(&stdout)?;
|
||||||
|
|
||||||
|
@ -94,14 +94,22 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
Ok(g) => {
|
Ok(g) => {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
RawTerminal::suspend_raw_mode(&stdout)?;
|
RawTerminal::suspend_raw_mode(&stdout)?;
|
||||||
|
let out_str = g.print();
|
||||||
let g = evaluate::evaluate(g);
|
let g = evaluate::evaluate(g);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
RawTerminal::activate_raw_mode(&stdout)?;
|
RawTerminal::activate_raw_mode(&stdout)?;
|
||||||
|
|
||||||
|
write!(
|
||||||
|
stdout, " {}{}=>{}{} {}\r\n",
|
||||||
|
style::Bold, color::Fg(color::Magenta),
|
||||||
|
style::Reset, color::Fg(color::Reset),
|
||||||
|
out_str
|
||||||
|
)?;
|
||||||
|
|
||||||
match g {
|
match g {
|
||||||
Ok(Token::Number(v)) => {
|
Ok(Token::Number(v)) => {
|
||||||
write!(
|
write!(
|
||||||
stdout, "\r\n {}{}={} {v}{}\r\n\n",
|
stdout, "\n {}{}={} {v}{}\r\n\n",
|
||||||
style::Bold,
|
style::Bold,
|
||||||
color::Fg(color::Green),
|
color::Fg(color::Green),
|
||||||
style::Reset,
|
style::Reset,
|
||||||
|
@ -111,7 +119,7 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
write!(
|
write!(
|
||||||
stdout, "\r\n {}{}Mathematical Error: {}Failed to evaluate expression.is{}\r\n\n",
|
stdout, "\n {}{}Mathematical Error: {}Failed to evaluate expression.{}\r\n\n",
|
||||||
style::Bold,
|
style::Bold,
|
||||||
color::Fg(color::Red),
|
color::Fg(color::Red),
|
||||||
style::Reset,
|
style::Reset,
|
||||||
|
|
167
src/tokens.rs
167
src/tokens.rs
|
@ -16,7 +16,22 @@ pub enum Token {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
|
|
||||||
|
pub fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Token::Number(v) => v.to_string(),
|
||||||
|
Token::Constant(_,s) => s.clone(),
|
||||||
|
Token::Operator(o,a) => o.print(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
pub fn get_args(&self) -> Option<&VecDeque<Token>> {
|
||||||
|
match self {
|
||||||
|
Token::Operator(_, ref a) => Some(a),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_args_mut(&mut self) -> Option<&mut VecDeque<Token>> {
|
pub fn get_args_mut(&mut self) -> Option<&mut VecDeque<Token>> {
|
||||||
|
@ -57,18 +72,137 @@ pub enum Operator {
|
||||||
Add,
|
Add,
|
||||||
Divide,
|
Divide,
|
||||||
Multiply,
|
Multiply,
|
||||||
ImplicitMultiply,
|
|
||||||
Modulo, // Mod invoked with %
|
Modulo, // Mod invoked with %
|
||||||
Negative,
|
Negative,
|
||||||
Power,
|
|
||||||
Sqrt,
|
Sqrt,
|
||||||
|
ImplicitMultiply,
|
||||||
|
|
||||||
|
Power,
|
||||||
Factorial,
|
Factorial,
|
||||||
|
|
||||||
|
Function(String),
|
||||||
|
|
||||||
// Not accessible from prompt
|
// Not accessible from prompt
|
||||||
Flip,
|
Flip,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operator {
|
impl Operator {
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn add_parens_to_arg(&self, arg: &Token) -> String {
|
||||||
|
let mut astr: String = arg.print();
|
||||||
|
if let Token::Operator(o,_) = arg {
|
||||||
|
if o.as_int() < self.as_int() {
|
||||||
|
astr = format!("({})", astr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return astr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(&self, args: &VecDeque<Token>) -> String {
|
||||||
|
match self {
|
||||||
|
Operator::ImplicitMultiply |
|
||||||
|
Operator::Sqrt |
|
||||||
|
Operator::Divide |
|
||||||
|
Operator::Flip |
|
||||||
|
Operator::Subtract => { panic!() }
|
||||||
|
|
||||||
|
Operator::Negative => {
|
||||||
|
return format!("-{}", self.add_parens_to_arg(&args[0]));
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::ModuloLong => {
|
||||||
|
return format!(
|
||||||
|
"{} mod {}",
|
||||||
|
self.add_parens_to_arg(&args[0]),
|
||||||
|
self.add_parens_to_arg(&args[1])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Modulo => {
|
||||||
|
return format!(
|
||||||
|
"{} % {}",
|
||||||
|
self.add_parens_to_arg(&args[0]),
|
||||||
|
self.add_parens_to_arg(&args[1])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Power => {
|
||||||
|
return format!(
|
||||||
|
"{}^{}",
|
||||||
|
self.add_parens_to_arg(&args[0]),
|
||||||
|
self.add_parens_to_arg(&args[1])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Factorial => {
|
||||||
|
return format!("{}!", self.add_parens_to_arg(&args[0]));
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Operator::Add => {
|
||||||
|
let a = &args[0];
|
||||||
|
let mut b = &args[1];
|
||||||
|
let mut sub = false;
|
||||||
|
|
||||||
|
if let Token::Operator(o,ar) = b {
|
||||||
|
if let Operator::Negative = o {
|
||||||
|
sub = true;
|
||||||
|
b = &ar[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let (b, sub) = (b, sub);
|
||||||
|
|
||||||
|
if sub {
|
||||||
|
return format!("{} - {}", self.add_parens_to_arg(a), self.add_parens_to_arg(b));
|
||||||
|
} else {
|
||||||
|
return format!("{} + {}", self.add_parens_to_arg(a), self.add_parens_to_arg(b));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Multiply => {
|
||||||
|
let a = &args[0];
|
||||||
|
let mut b = &args[1];
|
||||||
|
let mut div = false;
|
||||||
|
|
||||||
|
if let Token::Operator(o,ar) = b {
|
||||||
|
if let Operator::Flip = o {
|
||||||
|
div = true;
|
||||||
|
b = &ar[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let (b, div) = (b, div);
|
||||||
|
|
||||||
|
|
||||||
|
let mut astr: String = a.print();
|
||||||
|
if let Token::Operator(o,_) = a {
|
||||||
|
if o.as_int() < self.as_int() {
|
||||||
|
astr = format!("({})", astr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bstr: String = b.print();
|
||||||
|
if let Token::Operator(o,_) = b {
|
||||||
|
if o.as_int() < self.as_int() {
|
||||||
|
bstr = format!("({})", astr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if div {
|
||||||
|
return format!("{} ÷ {}", astr, bstr);
|
||||||
|
} else {
|
||||||
|
return format!("{} × {}", astr, bstr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Operator::Function(s) => {
|
||||||
|
return format!("{}({})", s, args[0].print());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from_string(s: &str) -> Option<Operator> {
|
pub fn from_string(s: &str) -> Option<Operator> {
|
||||||
match s {
|
match s {
|
||||||
|
@ -83,6 +217,7 @@ impl Operator {
|
||||||
"^"|"**" => {Some( Operator::Power )},
|
"^"|"**" => {Some( Operator::Power )},
|
||||||
"!" => {Some( Operator::Factorial )},
|
"!" => {Some( Operator::Factorial )},
|
||||||
"sqrt"|"rt"|"√" => {Some( Operator::Sqrt )},
|
"sqrt"|"rt"|"√" => {Some( Operator::Sqrt )},
|
||||||
|
"sin" => {Some( Operator::Function(String::from("sin")) )}
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +228,7 @@ impl Operator {
|
||||||
Operator::Negative
|
Operator::Negative
|
||||||
| Operator::Factorial
|
| Operator::Factorial
|
||||||
| Operator::Sqrt
|
| Operator::Sqrt
|
||||||
|
| Operator::Function(_)
|
||||||
=> false,
|
=> false,
|
||||||
_ => true
|
_ => true
|
||||||
}
|
}
|
||||||
|
@ -103,6 +239,7 @@ impl Operator {
|
||||||
match self {
|
match self {
|
||||||
Operator::Negative
|
Operator::Negative
|
||||||
| Operator::Sqrt
|
| Operator::Sqrt
|
||||||
|
| Operator::Function(_)
|
||||||
=> false,
|
=> false,
|
||||||
_ => true
|
_ => true
|
||||||
}
|
}
|
||||||
|
@ -154,16 +291,15 @@ impl Operator {
|
||||||
Operator::ImplicitMultiply
|
Operator::ImplicitMultiply
|
||||||
=> { Token::Operator(Operator::Multiply, args) },
|
=> { Token::Operator(Operator::Multiply, args) },
|
||||||
|
|
||||||
Operator::ModuloLong
|
Operator::Function(_)
|
||||||
=> { Token::Operator(Operator::Modulo, args) },
|
| Operator::Factorial
|
||||||
|
|
||||||
Operator::Factorial
|
|
||||||
| Operator::Negative
|
| Operator::Negative
|
||||||
| Operator::Flip
|
| Operator::Flip
|
||||||
| Operator::Add
|
| Operator::Add
|
||||||
| Operator::Multiply
|
| Operator::Multiply
|
||||||
| Operator::Modulo
|
| Operator::Modulo
|
||||||
| Operator::Power
|
| Operator::Power
|
||||||
|
| Operator::ModuloLong
|
||||||
=> { Token::Operator(self, args) },
|
=> { Token::Operator(self, args) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +310,6 @@ impl Operator{
|
||||||
match self {
|
match self {
|
||||||
Operator::ImplicitMultiply |
|
Operator::ImplicitMultiply |
|
||||||
Operator::Sqrt |
|
Operator::Sqrt |
|
||||||
Operator::ModuloLong |
|
|
||||||
Operator::Divide |
|
Operator::Divide |
|
||||||
Operator::Subtract => { panic!() }
|
Operator::Subtract => { panic!() }
|
||||||
|
|
||||||
|
@ -222,8 +357,9 @@ impl Operator{
|
||||||
}
|
}
|
||||||
return Ok(Token::Number(prod));
|
return Ok(Token::Number(prod));
|
||||||
},
|
},
|
||||||
|
|
||||||
Operator::Modulo => {
|
Operator::ModuloLong
|
||||||
|
| Operator::Modulo => {
|
||||||
if args.len() != 2 {panic!()};
|
if args.len() != 2 {panic!()};
|
||||||
let a = args[0].as_number();
|
let a = args[0].as_number();
|
||||||
let b = args[1].as_number();
|
let b = args[1].as_number();
|
||||||
|
@ -271,6 +407,19 @@ impl Operator{
|
||||||
return Ok(Token::Number(prod));
|
return Ok(Token::Number(prod));
|
||||||
} else { panic!(); }
|
} else { panic!(); }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Operator::Function(s) => {
|
||||||
|
match &s[..] {
|
||||||
|
"sin" => {
|
||||||
|
if args.len() != 1 {panic!()};
|
||||||
|
let a = args[0].as_number();
|
||||||
|
let Token::Number(v) = a else {panic!()};
|
||||||
|
return Ok(Token::Number(v.sin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => panic!()
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue