diff --git a/Cargo.lock b/Cargo.lock index c07dcdc..76e1cbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,7 +138,7 @@ dependencies = [ [[package]] name = "kalk" -version = "0.1.9" +version = "0.1.10" dependencies = [ "phf", "regex", @@ -148,7 +148,7 @@ dependencies = [ [[package]] name = "kalk_cli" -version = "0.1.8" +version = "0.1.9" dependencies = [ "ansi_term", "kalk", diff --git a/README.md b/README.md index 10eba17..886787b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ ![Build status](https://img.shields.io/travis/PaddiM8/kalk/master?label=build%20%26%20test) -Kalk is a calculator (both program and library) that supports user-defined variables and functions. +Kalk is a calculator (both program and library) that supports user-defined variables and functions. +[Project kanban board (Kolan)](https://kolan.smrk.me/Board/4RAdMjLDz) ![](example.png) diff --git a/kalk/Cargo.toml b/kalk/Cargo.toml index 1b59064..9fcd679 100644 --- a/kalk/Cargo.toml +++ b/kalk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kalk" -version = "0.1.9" +version = "0.1.10" authors = ["PaddiM8"] edition = "2018" readme = "README.md" diff --git a/kalk_cli/Cargo.toml b/kalk_cli/Cargo.toml index be92872..28a954e 100644 --- a/kalk_cli/Cargo.toml +++ b/kalk_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kalk_cli" -version = "0.1.8" +version = "0.1.9" authors = ["PaddiM8"] edition = "2018" readme = "../README.md" @@ -15,7 +15,7 @@ path = "src/main.rs" name = "kalk" [dependencies] -kalk = { path = "../kalk", version = "^0.1.9" } +kalk = { path = "../kalk", version = "^0.1.10" } rustyline = "6.1.2" ansi_term = "0.12" regex = "1" diff --git a/kalk_cli/src/main.rs b/kalk_cli/src/main.rs index e521eea..5440718 100644 --- a/kalk_cli/src/main.rs +++ b/kalk_cli/src/main.rs @@ -21,22 +21,37 @@ fn main() { break; }; - if arg == "-i" { - let file_name = &args.next().expect("Expected input file."); // The next argument will be the file name. - let mut file_content = String::new(); - File::open(&file_name) - .expect("Couldn't find file.") - .read_to_string(&mut file_content) - .expect("Failed to read input file."); + match arg.as_ref() { + "-h" | "--help" => { + // The indentation... Will have to do something more scalable in the future. + println!( + " +-= kalk help =-\n +kalk [OPTIONS] [INPUT] +-h, --help : show this +-i : load a file with predefined functions/variables + " + ); + return; + } + "-i" => { + let file_name = &args.next().expect("Expected input file."); // The next argument will be the file name. + let mut file_content = String::new(); + File::open(&file_name) + .expect("Couldn't find file.") + .read_to_string(&mut file_content) + .expect("Failed to read input file."); - // Parse the input file content, resulting in the symbol table being filled out. - // Output is not needed here. - parser::eval(&mut parser_context, &file_content, 53) - .expect("Failed to parse input file."); - } else { - // Main argument. This is expected to be a maths expression. - // After the loop is finished, this will be parsed and outputted. - expr_input = Some(arg); + // Parse the input file content, resulting in the symbol table being filled out. + // Output is not needed here. + parser::eval(&mut parser_context, &file_content, 53) + .expect("Failed to parse input file."); + } + _ => { + // Main argument. This is expected to be a maths expression. + // After the loop is finished, this will be parsed and outputted. + expr_input = Some(arg); + } } } diff --git a/kalk_cli/src/output.rs b/kalk_cli/src/output.rs index 25bc363..ba7260a 100644 --- a/kalk_cli/src/output.rs +++ b/kalk_cli/src/output.rs @@ -16,7 +16,11 @@ pub fn eval(parser: &mut parser::Context, input: &str) { let num = if exp <= 0 { // 0 < x < 1 - format!("0.{}{}", "0".repeat(exp.abs() as usize), digits) + round( + format!("0.{}{}", "0".repeat(exp.abs() as usize), digits) + .trim_end_matches('0'), + ) + .to_string() } else if use_sci_notation || result.fract() != 0 { // Insert the comma if there are supposed to be decimals. let mut chars: Vec = digits @@ -25,7 +29,7 @@ pub fn eval(parser: &mut parser::Context, input: &str) { .chars() .collect(); chars.insert(comma_pos, '.'); - chars.into_iter().collect::() + round(&chars.into_iter().collect::()).to_string() } else { // Regular number digits[..(exp as usize)].to_string() @@ -47,6 +51,39 @@ pub fn print_err(msg: &str) { println!("{}", Red.paint(msg)); } +fn round(value: &str) -> String { + let mut value_iter = value.chars().into_iter().rev().skip(1); + let last_char = value_iter.next().unwrap(); + let mut last_char_count = 1; + + // Find out how many repeating trailing (equal) characters there are + for c in value_iter { + if c == last_char { + last_char_count += 1; + } else { + break; + } + } + + // Don't round if there aren't that many + if last_char_count < 5 { + return value.to_string(); + } + + // Remove zeroes. + // If it's nines, round it up. + // Otherwise, only show 3 of them and then three dots: + match last_char { + '0' => value[..value.len() - last_char_count - 1].to_string(), + '9' => value.parse::().unwrap().ceil().to_string(), + _ => format!( + "{}{}...", + &value[..value.len() - last_char_count - 1], + last_char.to_string().repeat(3) + ), + } +} + fn print_calc_err(err: CalcError) { print_err(&match err { IncorrectAmountOfArguments(expected, func, got) => format!(