Refactor ui code
This commit is contained in:
parent
5772147ef1
commit
4600f5d31e
206
src/calc.rs
206
src/calc.rs
@ -5,10 +5,11 @@ pub mod operations;
|
|||||||
use constants::{
|
use constants::{
|
||||||
CalculatorConstant, CalculatorConstants, CalculatorConstantsIter, CalculatorMacro,
|
CalculatorConstant, CalculatorConstants, CalculatorConstantsIter, CalculatorMacro,
|
||||||
CalculatorMacros, CalculatorMacrosIter, CalculatorRegisters, CalculatorRegistersIter,
|
CalculatorMacros, CalculatorMacrosIter, CalculatorRegisters, CalculatorRegistersIter,
|
||||||
|
CalculatorState, RegisterState,
|
||||||
};
|
};
|
||||||
use errors::{CalculatorError, CalculatorResult};
|
use errors::{CalculatorError, CalculatorResult};
|
||||||
use operations::CalculatorOperation;
|
use operations::CalculatorOperation;
|
||||||
use std::collections::VecDeque;
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
enum OpArgs {
|
enum OpArgs {
|
||||||
Unary(f64),
|
Unary(f64),
|
||||||
@ -22,20 +23,26 @@ struct CalculatorStateChange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Calculator<'a> {
|
pub struct Calculator<'a> {
|
||||||
|
l: String,
|
||||||
stack: VecDeque<f64>,
|
stack: VecDeque<f64>,
|
||||||
macros: CalculatorMacros<'a>,
|
macros: CalculatorMacros<'a>,
|
||||||
|
active_macros: HashSet<char>,
|
||||||
constants: CalculatorConstants<'a>,
|
constants: CalculatorConstants<'a>,
|
||||||
registers: CalculatorRegisters,
|
registers: CalculatorRegisters,
|
||||||
undo_buf: Vec<CalculatorStateChange>,
|
undo_buf: Vec<CalculatorStateChange>,
|
||||||
redo_buf: Vec<CalculatorStateChange>,
|
redo_buf: Vec<CalculatorStateChange>,
|
||||||
|
state: CalculatorState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for Calculator<'a> {
|
impl<'a> Default for Calculator<'a> {
|
||||||
fn default() -> Calculator<'a> {
|
fn default() -> Calculator<'a> {
|
||||||
Calculator {
|
Calculator {
|
||||||
|
l: String::new(),
|
||||||
stack: vec![1.2, 1.3].into_iter().collect(),
|
stack: vec![1.2, 1.3].into_iter().collect(),
|
||||||
|
state: CalculatorState::Normal,
|
||||||
undo_buf: vec![],
|
undo_buf: vec![],
|
||||||
redo_buf: vec![],
|
redo_buf: vec![],
|
||||||
|
active_macros: HashSet::new(),
|
||||||
registers: CalculatorRegisters::new(),
|
registers: CalculatorRegisters::new(),
|
||||||
macros: [
|
macros: [
|
||||||
(
|
(
|
||||||
@ -94,6 +101,150 @@ impl<'a> Default for Calculator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Calculator<'a> {
|
impl<'a> Calculator<'a> {
|
||||||
|
pub fn take_input(&mut self, c: char) -> CalculatorResult<()> {
|
||||||
|
//for c in input.chars() {
|
||||||
|
match &self.state {
|
||||||
|
CalculatorState::Normal => match c {
|
||||||
|
c @ '0'..='9' | c @ '.' | c @ 'e' => self.entry(c),
|
||||||
|
//'!' => self.op(CalculatorOperation::Factorial),
|
||||||
|
'+' => self.op(CalculatorOperation::Add),
|
||||||
|
'-' => self.op(CalculatorOperation::Subtract),
|
||||||
|
'*' => self.op(CalculatorOperation::Multiply),
|
||||||
|
'/' => self.op(CalculatorOperation::Divide),
|
||||||
|
'n' => self.op(CalculatorOperation::Negate),
|
||||||
|
'|' => self.op(CalculatorOperation::AbsoluteValue),
|
||||||
|
'i' => self.op(CalculatorOperation::Inverse),
|
||||||
|
'%' => self.op(CalculatorOperation::Modulo),
|
||||||
|
'\\' => self.op(CalculatorOperation::Drop),
|
||||||
|
'?' => self.op(CalculatorOperation::IntegerDivide),
|
||||||
|
' ' => self.op(CalculatorOperation::Dup),
|
||||||
|
'>' => self.op(CalculatorOperation::Swap),
|
||||||
|
's' => self.op(CalculatorOperation::Sin),
|
||||||
|
'c' => self.op(CalculatorOperation::Cos),
|
||||||
|
't' => self.op(CalculatorOperation::Tan),
|
||||||
|
'S' => self.op(CalculatorOperation::ASin),
|
||||||
|
'C' => self.op(CalculatorOperation::ACos),
|
||||||
|
'T' => self.op(CalculatorOperation::ATan),
|
||||||
|
'v' => self.op(CalculatorOperation::Sqrt),
|
||||||
|
'^' => self.op(CalculatorOperation::Pow),
|
||||||
|
'l' => self.op(CalculatorOperation::Log),
|
||||||
|
'L' => self.op(CalculatorOperation::Ln),
|
||||||
|
//'e' => self.op(CalculatorOperation::E),
|
||||||
|
// Special
|
||||||
|
'u' => self.op(CalculatorOperation::Undo),
|
||||||
|
'U' => self.op(CalculatorOperation::Redo),
|
||||||
|
// State modifiers
|
||||||
|
'm' => {
|
||||||
|
self.state = CalculatorState::WaitingForMacro;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
'r' => {
|
||||||
|
self.state = CalculatorState::WaitingForRegister(RegisterState::Load);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
'R' => {
|
||||||
|
self.state = CalculatorState::WaitingForRegister(RegisterState::Load);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(CalculatorError::NoSuchOperator(c));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CalculatorState::WaitingForConstant => {
|
||||||
|
let f = self
|
||||||
|
.constants
|
||||||
|
.get(&c)
|
||||||
|
.ok_or(CalculatorError::NoSuchConstant(c))?
|
||||||
|
.value;
|
||||||
|
|
||||||
|
self.push(f)
|
||||||
|
}
|
||||||
|
CalculatorState::WaitingForMacro => {
|
||||||
|
let value = self
|
||||||
|
.macros
|
||||||
|
.get(&c)
|
||||||
|
.ok_or(CalculatorError::NoSuchMacro(c))?
|
||||||
|
.value;
|
||||||
|
|
||||||
|
if self.active_macros.contains(&c) {
|
||||||
|
return Err(CalculatorError::RecursiveMacro(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The macro needs to run in normal mode
|
||||||
|
self.state = CalculatorState::Normal;
|
||||||
|
|
||||||
|
// Record that we are running macro c
|
||||||
|
self.active_macros.insert(c);
|
||||||
|
for c in value.chars() {
|
||||||
|
self.take_input(c).or_else(|e| {
|
||||||
|
self.cancel();
|
||||||
|
Err(e)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
// Macro c should be over now
|
||||||
|
self.active_macros.remove(&c);
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
// self.push(value)
|
||||||
|
}
|
||||||
|
CalculatorState::WaitingForRegister(register_state) => {
|
||||||
|
match register_state {
|
||||||
|
RegisterState::Save => {
|
||||||
|
let f = self.pop()?;
|
||||||
|
self.registers.insert(c, f);
|
||||||
|
}
|
||||||
|
RegisterState::Load => {
|
||||||
|
let f = self
|
||||||
|
.registers
|
||||||
|
.get(&c)
|
||||||
|
.ok_or(CalculatorError::NoSuchRegister(c))?;
|
||||||
|
let f = *f;
|
||||||
|
self.push(f)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state = CalculatorState::Normal;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
//Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cancel(&mut self) {
|
||||||
|
self.state = CalculatorState::Normal;
|
||||||
|
self.active_macros.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn entry(&mut self, c: char) -> CalculatorResult<()> {
|
||||||
|
match c {
|
||||||
|
'0'..='9' => {
|
||||||
|
self.l.push(c);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
'e' => {
|
||||||
|
if self.l.is_empty() {
|
||||||
|
let f = self.pop().or(Err(CalculatorError::NotEnoughStackEntries))?;
|
||||||
|
|
||||||
|
self.l = f.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.l.contains('e') {
|
||||||
|
self.l.push('e');
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
'.' => {
|
||||||
|
if !self.l.contains('.') && !self.l.contains('e') {
|
||||||
|
self.l.push('.');
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Err(CalculatorError::ParseError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_constants_iter(&'a self) -> CalculatorConstantsIter<'a> {
|
pub fn get_constants_iter(&'a self) -> CalculatorConstantsIter<'a> {
|
||||||
self.constants.iter()
|
self.constants.iter()
|
||||||
}
|
}
|
||||||
@ -110,31 +261,40 @@ impl<'a> Calculator<'a> {
|
|||||||
let value = *value;
|
let value = *value;
|
||||||
self.push(value)
|
self.push(value)
|
||||||
}
|
}
|
||||||
None => Err(CalculatorError::NoSuchConstant),
|
None => Err(CalculatorError::NoSuchConstant(key)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn push_register(&mut self, key: char) -> CalculatorResult<()> {
|
// pub fn push_register(&mut self, key: char) -> CalculatorResult<()> {
|
||||||
match self.registers.get(&key) {
|
// match self.registers.get(&key) {
|
||||||
Some(f) => {
|
// Some(f) => {
|
||||||
let f = *f;
|
// let f = *f;
|
||||||
self.push(f)
|
// self.push(f)
|
||||||
}
|
// }
|
||||||
None => Err(CalculatorError::NoSuchRegister),
|
// None => Err(CalculatorError::NoSuchRegister),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
// TODO: Use hashmap
|
// pub fn save_register(&mut self, key: char) -> CalculatorResult<()> {
|
||||||
pub fn save_register(&mut self, key: char) -> CalculatorResult<()> {
|
// let f = self.pop()?;
|
||||||
let f = self.pop()?;
|
// self.registers.insert(key, f);
|
||||||
self.registers.insert(key, f);
|
// Ok(())
|
||||||
Ok(())
|
// }
|
||||||
}
|
|
||||||
pub fn get_macro(&mut self, key: char) -> Result<&CalculatorMacro<'a>, CalculatorError> {
|
pub fn get_macro(&mut self, key: char) -> Result<&CalculatorMacro<'a>, CalculatorError> {
|
||||||
match self.macros.get(&key) {
|
match self.macros.get(&key) {
|
||||||
Some(m) => Ok(m),
|
Some(m) => Ok(m),
|
||||||
None => Err(CalculatorError::NoSuchMacro),
|
None => Err(CalculatorError::NoSuchMacro(key)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flush_l(&mut self) -> CalculatorResult<bool> {
|
||||||
|
if self.l.is_empty() {
|
||||||
|
Ok(false)
|
||||||
|
} else {
|
||||||
|
let f = self.l.parse::<f64>().or(Err(CalculatorError::ParseError))?;
|
||||||
|
self.push(f)?;
|
||||||
|
self.l.clear();
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn push(&mut self, f: f64) -> CalculatorResult<()> {
|
pub fn push(&mut self, f: f64) -> CalculatorResult<()> {
|
||||||
self.direct_state_change(CalculatorStateChange {
|
self.direct_state_change(CalculatorStateChange {
|
||||||
pop: OpArgs::None,
|
pop: OpArgs::None,
|
||||||
@ -154,6 +314,12 @@ impl<'a> Calculator<'a> {
|
|||||||
}
|
}
|
||||||
//TODO: VecDeque could have other types
|
//TODO: VecDeque could have other types
|
||||||
pub fn op(&mut self, op: CalculatorOperation) -> CalculatorResult<()> {
|
pub fn op(&mut self, op: CalculatorOperation) -> CalculatorResult<()> {
|
||||||
|
// Dup is special -- don't actually run it if l needs to be flushed
|
||||||
|
if self.flush_l()? {
|
||||||
|
if let CalculatorOperation::Dup = op {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
let state_change = match op {
|
let state_change = match op {
|
||||||
CalculatorOperation::Add => self.binary_op(|[a, b]| OpArgs::Unary(b + a)),
|
CalculatorOperation::Add => self.binary_op(|[a, b]| OpArgs::Unary(b + a)),
|
||||||
CalculatorOperation::Subtract => self.binary_op(|[a, b]| OpArgs::Unary(b - a)),
|
CalculatorOperation::Subtract => self.binary_op(|[a, b]| OpArgs::Unary(b - a)),
|
||||||
@ -198,6 +364,10 @@ impl<'a> Calculator<'a> {
|
|||||||
.ok_or_else(|| CalculatorError::EmptyHistory(String::from("redo")))?;
|
.ok_or_else(|| CalculatorError::EmptyHistory(String::from("redo")))?;
|
||||||
return self.apply_state_change(s, true);
|
return self.apply_state_change(s, true);
|
||||||
}
|
}
|
||||||
|
// TODO: This should not happen -- need to pull all macro/register accesses into their own enum
|
||||||
|
CalculatorOperation::Macro(_) => {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.direct_state_change(state_change?)
|
self.direct_state_change(state_change?)
|
||||||
|
@ -1,6 +1,19 @@
|
|||||||
use std::collections::hash_map::Iter;
|
use std::collections::hash_map::Iter;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub enum RegisterState {
|
||||||
|
Save,
|
||||||
|
Load,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CalculatorState {
|
||||||
|
Normal,
|
||||||
|
//Macro,
|
||||||
|
WaitingForConstant,
|
||||||
|
WaitingForMacro,
|
||||||
|
WaitingForRegister(RegisterState),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct CalculatorConstant<'a> {
|
pub struct CalculatorConstant<'a> {
|
||||||
pub help: &'a str,
|
pub help: &'a str,
|
||||||
|
@ -7,11 +7,12 @@ pub enum CalculatorError {
|
|||||||
NotEnoughStackEntries,
|
NotEnoughStackEntries,
|
||||||
CorruptStateChange(String),
|
CorruptStateChange(String),
|
||||||
EmptyHistory(String),
|
EmptyHistory(String),
|
||||||
NoSuchConstant,
|
NoSuchConstant(char),
|
||||||
NoSuchRegister,
|
NoSuchRegister(char),
|
||||||
NoSuchMacro,
|
NoSuchMacro(char),
|
||||||
|
NoSuchOperator(char),
|
||||||
|
RecursiveMacro(char),
|
||||||
ParseError,
|
ParseError,
|
||||||
NoSuchOperator,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CalculatorError {
|
impl fmt::Display for CalculatorError {
|
||||||
@ -23,10 +24,11 @@ impl fmt::Display for CalculatorError {
|
|||||||
write!(f, "Corrupt state change: {}", msg)
|
write!(f, "Corrupt state change: {}", msg)
|
||||||
}
|
}
|
||||||
CalculatorError::EmptyHistory(msg) => write!(f, "No history to {}", msg),
|
CalculatorError::EmptyHistory(msg) => write!(f, "No history to {}", msg),
|
||||||
CalculatorError::NoSuchOperator => write!(f, "No such operator"),
|
CalculatorError::NoSuchOperator(c) => write!(f, "No such operator '{}'", c),
|
||||||
CalculatorError::NoSuchConstant => write!(f, "No such constant"),
|
CalculatorError::NoSuchConstant(c) => write!(f, "No such constant '{}'", c),
|
||||||
CalculatorError::NoSuchRegister => write!(f, "No such register"),
|
CalculatorError::NoSuchRegister(c) => write!(f, "No such register '{}'", c),
|
||||||
CalculatorError::NoSuchMacro => write!(f, "No such macro"),
|
CalculatorError::NoSuchMacro(c) => write!(f, "No such macro '{}'", c),
|
||||||
|
CalculatorError::RecursiveMacro(c) => write!(f, "Recursive macro '{}'", c),
|
||||||
CalculatorError::ParseError => write!(f, "Parse error"),
|
CalculatorError::ParseError => write!(f, "Parse error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::errors::{CalculatorError, CalculatorResult};
|
use super::constants::CalculatorMacro;
|
||||||
|
// use super::errors::{CalculatorError, CalculatorResult};
|
||||||
|
|
||||||
pub enum CalculatorOperation {
|
pub enum CalculatorOperation<'a> {
|
||||||
Add,
|
Add,
|
||||||
Subtract,
|
Subtract,
|
||||||
Multiply,
|
Multiply,
|
||||||
@ -28,77 +29,51 @@ pub enum CalculatorOperation {
|
|||||||
Log,
|
Log,
|
||||||
Ln,
|
Ln,
|
||||||
E,
|
E,
|
||||||
|
Macro(CalculatorMacro<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CalculatorOperation {
|
// impl CalculatorOperation<'_> {
|
||||||
pub fn from_char(key: char) -> CalculatorResult<CalculatorOperation> {
|
// pub fn from_char<'a>(key: char) -> CalculatorResult<CalculatorOperation<'a>> {
|
||||||
match key {
|
// match key {
|
||||||
'+' => Ok(CalculatorOperation::Add),
|
// _ => Err(CalculatorError::NoSuchOperator),
|
||||||
'-' => Ok(CalculatorOperation::Subtract),
|
// }
|
||||||
'*' => Ok(CalculatorOperation::Multiply),
|
// }
|
||||||
'/' => Ok(CalculatorOperation::Divide),
|
|
||||||
'n' => Ok(CalculatorOperation::Negate),
|
|
||||||
'|' => Ok(CalculatorOperation::AbsoluteValue),
|
|
||||||
'i' => Ok(CalculatorOperation::Inverse),
|
|
||||||
'%' => Ok(CalculatorOperation::Modulo),
|
|
||||||
//'r' => Ok(CalculatorOperation::Remainder),
|
|
||||||
'\\' => Ok(CalculatorOperation::Drop),
|
|
||||||
'?' => Ok(CalculatorOperation::IntegerDivide),
|
|
||||||
'\n' => Ok(CalculatorOperation::Dup),
|
|
||||||
'>' => Ok(CalculatorOperation::Swap),
|
|
||||||
's' => Ok(CalculatorOperation::Sin),
|
|
||||||
'c' => Ok(CalculatorOperation::Cos),
|
|
||||||
't' => Ok(CalculatorOperation::Tan),
|
|
||||||
'S' => Ok(CalculatorOperation::ASin),
|
|
||||||
'C' => Ok(CalculatorOperation::ACos),
|
|
||||||
'T' => Ok(CalculatorOperation::ATan),
|
|
||||||
'v' => Ok(CalculatorOperation::Sqrt),
|
|
||||||
//TODO: Should not be calculator states probably
|
|
||||||
'u' => Ok(CalculatorOperation::Undo),
|
|
||||||
'U' => Ok(CalculatorOperation::Redo),
|
|
||||||
'^' => Ok(CalculatorOperation::Pow),
|
|
||||||
//'!' => Ok(CalculatorOperation::Factorial),
|
|
||||||
'l' => Ok(CalculatorOperation::Log),
|
|
||||||
'L' => Ok(CalculatorOperation::Ln),
|
|
||||||
'e' => Ok(CalculatorOperation::E),
|
|
||||||
_ => Err(CalculatorError::NoSuchOperator),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn num_stack(&self) -> usize {
|
// pub fn num_stack(&self) -> usize {
|
||||||
match self {
|
// match self {
|
||||||
CalculatorOperation::Add
|
// CalculatorOperation::Add
|
||||||
| CalculatorOperation::Subtract
|
// | CalculatorOperation::Subtract
|
||||||
| CalculatorOperation::Multiply
|
// | CalculatorOperation::Multiply
|
||||||
| CalculatorOperation::Divide
|
// | CalculatorOperation::Divide
|
||||||
| CalculatorOperation::Modulo
|
// | CalculatorOperation::Modulo
|
||||||
| CalculatorOperation::IntegerDivide
|
// | CalculatorOperation::IntegerDivide
|
||||||
| CalculatorOperation::Swap
|
// | CalculatorOperation::Swap
|
||||||
| CalculatorOperation::Pow
|
// | CalculatorOperation::Pow
|
||||||
| CalculatorOperation::E
|
// | CalculatorOperation::E
|
||||||
//| CalculatorOperation::Remainder
|
// //| CalculatorOperation::Remainder
|
||||||
=> 2,
|
// => 2,
|
||||||
CalculatorOperation::Negate
|
// CalculatorOperation::Negate
|
||||||
| CalculatorOperation::AbsoluteValue
|
// | CalculatorOperation::AbsoluteValue
|
||||||
| CalculatorOperation::Inverse
|
// | CalculatorOperation::Inverse
|
||||||
| CalculatorOperation::Drop
|
// | CalculatorOperation::Drop
|
||||||
|
|
||||||
| CalculatorOperation::Sin
|
// | CalculatorOperation::Sin
|
||||||
| CalculatorOperation::Cos
|
// | CalculatorOperation::Cos
|
||||||
| CalculatorOperation::Tan
|
// | CalculatorOperation::Tan
|
||||||
| CalculatorOperation::ASin
|
// | CalculatorOperation::ASin
|
||||||
| CalculatorOperation::ACos
|
// | CalculatorOperation::ACos
|
||||||
| CalculatorOperation::ATan
|
// | CalculatorOperation::ATan
|
||||||
| CalculatorOperation::Sqrt
|
// | CalculatorOperation::Sqrt
|
||||||
| CalculatorOperation::Dup
|
// | CalculatorOperation::Dup
|
||||||
|
|
||||||
//|CalculatorOperation::Factorial
|
// //|CalculatorOperation::Factorial
|
||||||
| CalculatorOperation::Log
|
// | CalculatorOperation::Log
|
||||||
| CalculatorOperation::Ln
|
// | CalculatorOperation::Ln
|
||||||
=> 1,
|
// => 1,
|
||||||
CalculatorOperation::Undo
|
// CalculatorOperation::Macro(_)
|
||||||
| CalculatorOperation::Redo
|
// |CalculatorOperation::Undo
|
||||||
=> 0,
|
// | CalculatorOperation::Redo
|
||||||
}
|
// => 0,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
103
src/main.rs
103
src/main.rs
@ -5,7 +5,6 @@ mod calc;
|
|||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use calc::errors::{CalculatorError, CalculatorResult};
|
use calc::errors::{CalculatorError, CalculatorResult};
|
||||||
use calc::operations::CalculatorOperation;
|
|
||||||
use calc::Calculator;
|
use calc::Calculator;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@ -165,7 +164,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
<ret> => Dup l => Log\n\
|
<ret> => Dup l => Log\n\
|
||||||
> => Swap L => Ln\n\
|
> => Swap L => Ln\n\
|
||||||
e => E ^c => Constants\n\
|
e => E ^c => Constants\n\
|
||||||
m => Macros rR => Registers\
|
m => Macros rR => Registers\n\
|
||||||
|
uU => Undo/Redo\
|
||||||
",
|
",
|
||||||
},
|
},
|
||||||
f,
|
f,
|
||||||
@ -257,18 +257,18 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
Key::Char('q') => {
|
Key::Char('q') => {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
Key::Ctrl('c') => {
|
// Key::Ctrl('c') => {
|
||||||
app.state = AppState::Constants;
|
// app.state = AppState::Constants;
|
||||||
}
|
// }
|
||||||
Key::Char('r') => {
|
// Key::Char('r') => {
|
||||||
app.state = AppState::Registers(RegisterState::Load);
|
// app.state = AppState::Registers(RegisterState::Load);
|
||||||
}
|
// }
|
||||||
Key::Char('R') => {
|
// Key::Char('R') => {
|
||||||
app.state = AppState::Registers(RegisterState::Save);
|
// app.state = AppState::Registers(RegisterState::Save);
|
||||||
}
|
// }
|
||||||
Key::Char('m') => {
|
// Key::Char('m') => {
|
||||||
app.state = AppState::Macros;
|
// app.state = AppState::Macros;
|
||||||
}
|
// }
|
||||||
Key::Char('h') => {
|
Key::Char('h') => {
|
||||||
app.state = AppState::Help;
|
app.state = AppState::Help;
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
}
|
}
|
||||||
Key::Char('\n') | Key::Char(' ') => {
|
Key::Char('\n') | Key::Char(' ') => {
|
||||||
if app.input.is_empty() {
|
if app.input.is_empty() {
|
||||||
calc_operation(app, '\n')?;
|
calc_operation(app, ' ')?;
|
||||||
} else {
|
} else {
|
||||||
let mut tmp_input = app.input.clone();
|
let mut tmp_input = app.input.clone();
|
||||||
if tmp_input.ends_with('e') {
|
if tmp_input.ends_with('e') {
|
||||||
@ -313,6 +313,7 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
calc_operation(app, '>')?;
|
calc_operation(app, '>')?;
|
||||||
}
|
}
|
||||||
Key::Down => {
|
Key::Down => {
|
||||||
|
// TODO: Internal calculator function
|
||||||
if let Ok(x) = app.calculator.pop() {
|
if let Ok(x) = app.calculator.pop() {
|
||||||
app.input = x.to_string();
|
app.input = x.to_string();
|
||||||
}
|
}
|
||||||
@ -329,63 +330,68 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
AppState::Help => match key {
|
AppState::Help => match key {
|
||||||
Key::Esc => {
|
Key::Esc | Key::Char('q') => {
|
||||||
app.state = AppState::Calculator;
|
app.state = AppState::Calculator;
|
||||||
|
app.calculator.cancel();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
AppState::Constants => match key {
|
AppState::Constants => match key {
|
||||||
Key::Esc => {
|
Key::Esc => {
|
||||||
app.state = AppState::Calculator;
|
app.state = AppState::Calculator;
|
||||||
|
app.calculator.cancel();
|
||||||
}
|
}
|
||||||
Key::Char(c) => {
|
Key::Char(c) => {
|
||||||
app.calculator.push_constant(c)?;
|
app.calculator.push_constant(c)?;
|
||||||
app.input.clear();
|
app.input.clear();
|
||||||
app.state = AppState::Calculator;
|
app.state = AppState::Calculator;
|
||||||
|
app.calculator.cancel();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
AppState::Registers(task) => match key {
|
AppState::Registers(task) => match key {
|
||||||
Key::Esc => {
|
Key::Esc => {
|
||||||
app.state = AppState::Calculator;
|
app.state = AppState::Calculator;
|
||||||
|
app.calculator.cancel();
|
||||||
}
|
}
|
||||||
Key::Char(c) => {
|
// Key::Char(c) => {
|
||||||
match task {
|
// match task {
|
||||||
RegisterState::Save => {
|
// RegisterState::Save => {
|
||||||
app.calculator.save_register(c)?;
|
// app.calculator.save_register(c)?;
|
||||||
}
|
// }
|
||||||
RegisterState::Load => {
|
// RegisterState::Load => {
|
||||||
app.calculator.push_register(c)?;
|
// app.calculator.push_register(c)?;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
app.input.clear();
|
// app.input.clear();
|
||||||
app.state = AppState::Calculator;
|
// app.state = AppState::Calculator;
|
||||||
}
|
// }
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
AppState::Macros => match key {
|
AppState::Macros => match key {
|
||||||
Key::Esc => {
|
Key::Esc => {
|
||||||
app.state = AppState::Calculator;
|
app.state = AppState::Calculator;
|
||||||
|
app.calculator.cancel();
|
||||||
}
|
}
|
||||||
Key::Char(c) => {
|
// Key::Char(c) => {
|
||||||
if !app.input.is_empty() {
|
// if !app.input.is_empty() {
|
||||||
//TODO: A better way to do this
|
// //TODO: A better way to do this
|
||||||
//Can use calc_operation in the future. Already performs this check
|
// //Can use calc_operation in the future. Already performs this check
|
||||||
let f = app
|
// let f = app
|
||||||
.input
|
// .input
|
||||||
.parse::<f64>()
|
// .parse::<f64>()
|
||||||
.or(Err(CalculatorError::ParseError))?;
|
// .or(Err(CalculatorError::ParseError))?;
|
||||||
app.calculator.push(f).and_then(|()| {
|
// app.calculator.push(f).and_then(|()| {
|
||||||
app.input.clear();
|
// app.input.clear();
|
||||||
Ok(())
|
// Ok(())
|
||||||
})?;
|
// })?;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TODO: Handle macros internally to the calculator
|
// // TODO: Handle macros internally to the calculator
|
||||||
let mac = app.calculator.get_macro(c)?;
|
// let mac = app.calculator.get_macro(c)?;
|
||||||
events.fill_event_buf(mac.value);
|
// events.fill_event_buf(mac.value);
|
||||||
app.state = AppState::Calculator;
|
// app.state = AppState::Calculator;
|
||||||
}
|
// }
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -393,7 +399,6 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn calc_operation(app: &mut App, c: char) -> CalculatorResult<()> {
|
fn calc_operation(app: &mut App, c: char) -> CalculatorResult<()> {
|
||||||
let op = CalculatorOperation::from_char(c)?;
|
|
||||||
if !app.input.is_empty() {
|
if !app.input.is_empty() {
|
||||||
let f = app
|
let f = app
|
||||||
.input
|
.input
|
||||||
@ -403,7 +408,9 @@ fn calc_operation(app: &mut App, c: char) -> CalculatorResult<()> {
|
|||||||
app.input.clear();
|
app.input.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.calculator.op(op)
|
//let op = CalculatorOperation::from_char(c)?;
|
||||||
|
app.calculator.take_input(c)
|
||||||
|
//app.calculator.op(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClippyRectangle<'a> {
|
struct ClippyRectangle<'a> {
|
||||||
|
Loading…
Reference in New Issue
Block a user