Add 'base' command for setting output radix, closes #109

This commit is contained in:
PaddiM8 2023-01-24 19:11:35 +01:00
parent 85bd77f99f
commit b13c459aee
6 changed files with 40 additions and 12 deletions

View File

@ -15,10 +15,12 @@ Overview of features
Different number bases: Either with a format like 0b1101, 0o5.3, 0xff
or a format like 1101_2. The latter does not support letters, as they
would be interpreted as variables
would be interpreted as variables. The "base" command can be used to
tell the REPL to also show output in another number base. For example,
"base 16" would make it show results in hexadecimal as well as decimal.
Root finding using Newton's method (eg. x^2 = 64). Note: estimation and
limited to one root
limited to one root.
Derivation (prime notation) and integration (eg. integral(a, b, x dx)
The value of an integral is estimated using Simpson's 3/8 rule,

View File

@ -68,7 +68,12 @@ fn default_action(context: &Context) {
repl::start(&mut parser_context, precision);
} else {
// Direct output
output::eval(&mut parser_context, &context.args.join(" "), precision);
output::eval(
&mut parser_context,
&context.args.join(" "),
precision,
10u8,
);
}
}

View File

@ -3,9 +3,11 @@ use kalk::parser;
pub(crate) const DEFAULT_PRECISION: u32 = 63;
pub fn eval(parser: &mut parser::Context, input: &str, precision: u32) {
pub fn eval(parser: &mut parser::Context, input: &str, precision: u32, base: u8) {
match parser::eval(parser, input, precision) {
Ok(Some(result)) => {
Ok(Some(mut result)) => {
result.set_radix(base);
if precision == DEFAULT_PRECISION {
println!("{}", result.to_string_pretty())
} else {
@ -19,5 +21,5 @@ pub fn eval(parser: &mut parser::Context, input: &str, precision: u32) {
pub fn print_err(msg: &str) {
Red.paint(msg).to_string();
println!("{}", msg);
eprintln!("{}", msg);
}

View File

@ -20,6 +20,10 @@ use std::collections::HashMap;
use std::fs;
use std::process;
struct Context {
base: u8,
}
pub fn start(parser: &mut parser::Context, precision: u32) {
let mut editor = Editor::<RLHelper>::new();
editor.set_helper(Some(RLHelper {
@ -50,6 +54,7 @@ pub fn start(parser: &mut parser::Context, precision: u32) {
);
}
let mut repl = Context { base: 10u8 };
loop {
let prompt = if cfg!(windows) {
String::from(">> ")
@ -61,7 +66,7 @@ pub fn start(parser: &mut parser::Context, precision: u32) {
match readline {
Ok(input) => {
editor.add_history_entry(input.as_str());
eval_repl(parser, &input, precision);
eval_repl(&mut repl, parser, &input, precision);
}
Err(ReadlineError::Interrupted) => break,
_ => break,
@ -73,22 +78,35 @@ pub fn start(parser: &mut parser::Context, precision: u32) {
}
}
fn eval_repl(parser: &mut parser::Context, input: &str, precision: u32) {
fn eval_repl(repl: &mut self::Context, parser: &mut parser::Context, input: &str, precision: u32) {
if let Some(file_name) = input.strip_prefix("load ") {
if let Some(file_path) = crate::get_input_file_by_name(file_name) {
crate::load_input_file(&file_path, precision, parser);
} else {
println!("Unable to find '{}'", file_name);
eprintln!("Unable to find '{}'", file_name);
}
return;
}
if let Some(base_str) = input.strip_prefix("base ") {
if !base_str.is_empty() && base_str.chars().next().unwrap().is_ascii_digit() {
if let Ok(base) = base_str.parse::<u8>() {
repl.base = base;
} else {
eprintln!("Invalid number base");
}
return;
}
}
match input {
"" => eprint!(""),
"clear" => print!("\x1B[2J"),
"exit" => process::exit(0),
"help" => print_cli_help(),
_ => output::eval(parser, input, precision),
_ => output::eval(parser, input, precision, repl.base),
}
}

View File

@ -65,7 +65,8 @@ impl CalculationResult {
self.value.imaginary_to_f64()
}
pub(crate) fn set_radix(&mut self, radix: u8) {
#[wasm_bindgen(js_name = setRadix)]
pub fn set_radix(&mut self, radix: u8) {
self.radix = radix;
}

View File

@ -288,7 +288,7 @@ impl KalkValue {
}
}
pub(crate) fn to_string_pretty_radix(&self, radix: u8) -> String {
pub fn to_string_pretty_radix(&self, radix: u8) -> String {
let (real, imaginary, unit) = match self {
KalkValue::Number(real, imaginary, unit) => (real, imaginary, unit),
_ => return self.to_string(),