diff --git a/src/command/mod.rs b/src/command/mod.rs new file mode 100644 index 0000000..974d2fd --- /dev/null +++ b/src/command/mod.rs @@ -0,0 +1,140 @@ +use std::io::Write; + +use termion::{ + raw::RawTerminal, + color, + style, + clear, + cursor +}; + +pub fn is_command( + s: &String +) -> bool { + match &s.trim()[..] { + "help" | "clear" + | "ops" | "operators" + | "fns" | "functions" + => true, + _ => false + } +} + + +#[inline(always)] +fn draw_greeter(stdout: &mut RawTerminal) -> Result<(), std::io::Error> { + write!( + stdout, + "\n \ + {a} ###### {b} @@@@@@\r\n \ + {a}# ##{b}@@ @\r\n \ + {a}## #{b}@ @@\r\n \ + {a} {b}@@@@@@@@@@@@@{a}\r\n \ + {b}@@ @{a}# ##\r\n \ + {b}@ @@{a}## #\r\n \ + {b} @@@@@@ {a} ###### {r}\r\n \ + \n {t}Daisy{r} {v}v{ver}{r}\r\n\n", + r = format!("{}{}", color::Fg(color::Reset), style::Reset), + a = color::Fg(color::Magenta), + b = color::Fg(color::White), + t = format!("{}{}", color::Fg(color::White), style::Bold), + v = format!("{}{}", color::Fg(color::White), style::Italic), + ver = env!("CARGO_PKG_VERSION"), + )?; + + return Ok(()); +} + + +#[inline(always)] +pub fn do_command( + stdout: &mut RawTerminal, + s: &String +) -> Result<(), std::io::Error> { + + match &s[..] { + "help" => { + draw_greeter(stdout)?; + + write!(stdout, + concat!( + "╞═════════════ {t}Commands{r} ═════════════╡\r\n", + " {c}help{r} Show this help\r\n", + " {c}clear{r} Clear the terminal\r\n", + " {c}quit{r} Exit daisy\r\n", + //" {c}units{r} List available units\r\n", + //" {c}const{r} List available constants\r\n", + " {c}ops{r} List built-in operators\r\n", + " {c}fns{r} List built-in functions\r\n" + ), + + r = format!("{}{}", color::Fg(color::Reset), style::Reset), + + c = format!("{}{}", color::Fg(color::LightBlack), style::Italic), + + t = format!("{}{}", color::Fg(color::Magenta), style::Bold) + )?; + }, + + "clear" => { + write!( + stdout, + "{}{}", + clear::All, + cursor::Goto(0, 0) + )?; + }, + + "ops" | "operators" => { + write!(stdout, + concat!( + "\r\n", + "Operators, sorted by priority (high to low).\r\n", + "High-piority operators are applied first.\r\n\n", + "╞═════ {t}Operator{r} ═════╪═════ {t}Syntax{r} ═════╡\r\n", + " function {c}sin, cos, etc{r}\r\n", + " factorial {c}!{r}\r\n", + " powers {c}^, **{r}\r\n", + " implicit multiply {c}3π, 3(2+1), etc{r}\r\n", + " square root {c}sqrt, rt, √{r}\r\n", + " negate {c}-3, -(1 + 2){r}\r\n", + " modulo (short) {c}%{r}\r\n", + " multiply, divide {c}*, /, ×, ÷{r}\r\n", + " add, subtract {c}+, -{r}\r\n", + " modulo (long) {c}mod{r}\r\n", + "\n" + ), + + r = format!("{}{}", color::Fg(color::Reset), style::Reset), + c = format!("{}{}", color::Fg(color::LightBlack), style::Italic), + t = format!("{}{}", color::Fg(color::Magenta), style::Bold) + )?; + }, + + "fns" | "functions" => { + write!(stdout, + concat!( + "\r\n╞═══════ {t}Function{r} ═══════╪══════ {t}Syntax{r} ══════╡\r\n", + " absolute value {c}abs{r}\r\n", + " floor, ceiling, round {c}floor, ceil, round{r}\r\n", + " log base e {c}ln{r}\r\n", + " log base 10 {c}log{r}\r\n", + " sin, arcsin, cosecant {c}sin, asin, csc{r}\r\n", + " cos, arccos, secant {c}cos, acos, secant{r}\r\n", + " tan, arctan, cotan {c}tan, atan, cot{r}\r\n", + " hyperbolic sin, etc {c}sinh, asinh, csch{r}\r\n", + " hyperbolic cos, etc {c}cosh, acosh, sech{r}\r\n", + " hyperbolic tan, etc {c}tanh, atanh, coth{r}\r\n", + "\n" + ), + + r = format!("{}{}", color::Fg(color::Reset), style::Reset), + c = format!("{}{}", color::Fg(color::LightBlack), style::Italic), + t = format!("{}{}", color::Fg(color::Magenta), style::Bold) + )?; + }, + _ => panic!("Bad command!") + }; + + return Ok(()); +} diff --git a/src/entry/unix/unix.rs b/src/entry/unix/unix.rs index 3745b9a..b26d69e 100644 --- a/src/entry/unix/unix.rs +++ b/src/entry/unix/unix.rs @@ -2,63 +2,104 @@ use std::io::Write; use std::io::stdout; use std::io::stdin; - -// We only need this for debug -#[cfg(debug_assertions)] -use termion::raw::RawTerminal; - use termion::{ event::Key, input::TermRead, raw::IntoRawMode, + raw::RawTerminal, color, style, }; -use crate::tokens::EvalError; - use super::promptbuffer::PromptBuffer; +use crate::tokens::EvalError; use crate::parser; +use crate::command; + + -/* #[inline(always)] -fn draw_greeter(stdout: &mut RawTerminal) -> Result<(), std::io::Error> { - write!( - stdout, - "\n \ - {a} ###### {b} @@@@@@\r\n \ - {a}# ##{b}@@ @\r\n \ - {a}## #{b}@ @@\r\n \ - {a} {b}@@@@@@@@@@@@@{a}\r\n \ - {b}@@ @{a}# ##\r\n \ - {b}@ @@{a}## #\r\n \ - {b} @@@@@@ {a} ###### {r}\r\n \ - \n {t}Daisy{r} {v}v{ver}{r}\r\n\n", - r = format!("{}{}", color::Fg(color::Reset), style::Reset), +fn do_expression( + stdout: &mut RawTerminal, + s: &String +) -> Result<(), std::io::Error> { + #[cfg(debug_assertions)] + RawTerminal::suspend_raw_mode(&stdout)?; + let g = parser::parse(&s); + #[cfg(debug_assertions)] + RawTerminal::activate_raw_mode(&stdout)?; - // Icon colors - a = color::Fg(color::Magenta), - b = color::Fg(color::White), + match g { + Ok(g) => { + #[cfg(debug_assertions)] + RawTerminal::suspend_raw_mode(&stdout)?; + let out_str = g.to_string(); + let g = g.evaluate(); + #[cfg(debug_assertions)] + RawTerminal::activate_raw_mode(&stdout)?; - // Title format - t = format!("{}{}", color::Fg(color::White), style::Bold), + write!( + stdout, " {}{}=>{}{} {}\r\n", + style::Bold, color::Fg(color::Magenta), + style::Reset, color::Fg(color::Reset), + out_str + )?; - // Version - v = format!("{}{}", color::Fg(color::White), style::Italic), - ver = env!("CARGO_PKG_VERSION"), - )?; + match g { + Ok(q) => { + write!( + stdout, "\n {}{}={} {}{}\r\n\n", + style::Bold, + color::Fg(color::Green), + style::Reset, + q.to_string_outer(), + color::Fg(color::Reset) + )?; + }, + + Err(EvalError::BadMath) => { + write!( + stdout, "\n {}{}Mathematical Error: {}Failed to evaluate expression{}\r\n\n", + style::Bold, + color::Fg(color::Red), + style::Reset, + color::Fg(color::Reset), + )?; + }, + + Err(EvalError::IncompatibleUnit) => { + write!( + stdout, "\n {}{}Evaluation Error: {}Incompatible units{}\r\n\n", + style::Bold, + color::Fg(color::Red), + style::Reset, + color::Fg(color::Reset), + )?; + } + } + }, + + // Show parse error + Err((l, e)) => { + write!( + stdout, "{}{}{} {}{}\r\n", + color::Fg(color::Red), + " ".repeat(l.pos + 4), + "^".repeat(l.len), + e.to_message(), + color::Fg(color::Reset), + )?; + } + }; return Ok(()); } -*/ #[inline(always)] pub fn main() -> Result<(), std::io::Error> { let mut stdout = stdout().into_raw_mode().unwrap(); - //draw_greeter(&mut stdout)?; - //let size = termion::terminal_size().unwrap(); //write!(stdout, "{:?}", size).unwrap(); @@ -77,74 +118,13 @@ pub fn main() -> Result<(), std::io::Error> { write!(stdout, "\r\n")?; if in_str == "" { break; } - #[cfg(debug_assertions)] - RawTerminal::suspend_raw_mode(&stdout)?; - let g = parser::parse(&in_str); - #[cfg(debug_assertions)] - RawTerminal::activate_raw_mode(&stdout)?; - - match g { - Ok(g) => { - #[cfg(debug_assertions)] - RawTerminal::suspend_raw_mode(&stdout)?; - let out_str = g.to_string(); - let g = g.evaluate(); - #[cfg(debug_assertions)] - 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 { - Ok(q) => { - write!( - stdout, "\n {}{}={} {}{}\r\n\n", - style::Bold, - color::Fg(color::Green), - style::Reset, - q.to_string_outer(), - color::Fg(color::Reset) - )?; - }, - - Err(EvalError::BadMath) => { - write!( - stdout, "\n {}{}Mathematical Error: {}Failed to evaluate expression{}\r\n\n", - style::Bold, - color::Fg(color::Red), - style::Reset, - color::Fg(color::Reset), - )?; - }, - - Err(EvalError::IncompatibleUnit) => { - write!( - stdout, "\n {}{}Evaluation Error: {}Incompatible units{}\r\n\n", - style::Bold, - color::Fg(color::Red), - style::Reset, - color::Fg(color::Reset), - )?; - } - } - }, - - // Show parse error - Err((l, e)) => { - write!( - stdout, "{}{}{} {}{}\r\n", - color::Fg(color::Red), - " ".repeat(l.pos + 4), - "^".repeat(l.len), - e.to_message(), - color::Fg(color::Reset), - )?; - } - }; + if in_str.trim() == "quit" { + break 'outer; + } else if command::is_command(&in_str) { + command::do_command(&mut stdout, &in_str)?; + } else { + do_expression(&mut stdout, &in_str)?; + } break; }, diff --git a/src/main.rs b/src/main.rs index 19b4b5c..56b8cde 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,12 @@ pub mod tokens; pub mod parser; +pub mod command; pub mod quantity; //use crate::tokens::Token; //use crate::parser::ParserError; //use crate::parser::LineLocation; - -/* - Greeter ascii art: - - ###### @@@@@@ - # ##@@ @ - ## #@ @@ - @@@@@@@@@@@@@ - @@ @# ## - @ @@## # - @@@@@@ ###### - - Daisy 0.0.0 -*/ - mod entry; use crate::entry::main_e;