mirror of https://github.com/rm-dr/daisy
Added nounit and tobase functions
parent
aa02b35cc5
commit
061f58ba53
|
@ -11,6 +11,13 @@ pub fn eval_function(f: &Function, args: &VecDeque<Token>) -> Result<Token, Eval
|
||||||
let a = &args[0];
|
let a = &args[0];
|
||||||
let Token::Quantity(q) = a else {panic!()};
|
let Token::Quantity(q) = a else {panic!()};
|
||||||
|
|
||||||
|
|
||||||
|
match f {
|
||||||
|
Function::NoUnit => { return Ok(Token::Quantity(q.without_unit())); }
|
||||||
|
Function::ToBase => { return Ok(Token::Quantity(q.convert_to_base())); }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
if !q.unitless() {
|
if !q.unitless() {
|
||||||
return Err(EvalError::IncompatibleUnit);
|
return Err(EvalError::IncompatibleUnit);
|
||||||
}
|
}
|
||||||
|
@ -89,5 +96,8 @@ pub fn eval_function(f: &Function, args: &VecDeque<Token>) -> Result<Token, Eval
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Function::ToBase
|
||||||
|
| Function::NoUnit
|
||||||
|
=> panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,10 +28,14 @@ pub enum Function {
|
||||||
Csch,
|
Csch,
|
||||||
Sech,
|
Sech,
|
||||||
Coth,
|
Coth,
|
||||||
|
|
||||||
|
NoUnit,
|
||||||
|
ToBase
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
|
||||||
pub fn to_string(&self) -> String {
|
impl ToString for Function {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Function::Abs => { String::from("abs") },
|
Function::Abs => { String::from("abs") },
|
||||||
Function::Floor => { String::from("floor") },
|
Function::Floor => { String::from("floor") },
|
||||||
|
@ -57,6 +61,45 @@ impl Function {
|
||||||
Function::Csch => { String::from("csch") },
|
Function::Csch => { String::from("csch") },
|
||||||
Function::Sech => { String::from("sech") },
|
Function::Sech => { String::from("sech") },
|
||||||
Function::Coth => { String::from("coth") },
|
Function::Coth => { String::from("coth") },
|
||||||
|
Function::NoUnit => { String::from("nounit") },
|
||||||
|
Function::ToBase => { String::from("tobase") },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Function {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn from_string(s: &str) -> Option<Function> {
|
||||||
|
match s {
|
||||||
|
"abs" => {Some(Function::Abs)},
|
||||||
|
"floor" => {Some(Function::Floor)},
|
||||||
|
"ceil" => {Some(Function::Ceil)},
|
||||||
|
"round" => {Some(Function::Round)},
|
||||||
|
"ln" => {Some(Function::NaturalLog)},
|
||||||
|
"log" => {Some(Function::TenLog)},
|
||||||
|
"sin" => {Some(Function::Sin)},
|
||||||
|
"cos" => {Some(Function::Cos)},
|
||||||
|
"tan" => {Some(Function::Tan)},
|
||||||
|
"asin" => {Some(Function::Asin)},
|
||||||
|
"acos" => {Some(Function::Acos)},
|
||||||
|
"atan" => {Some(Function::Atan)},
|
||||||
|
"csc" => {Some(Function::Csc)},
|
||||||
|
"secant" => {Some(Function::Sec)},
|
||||||
|
"cot" => {Some(Function::Cot)},
|
||||||
|
"sinh" => {Some(Function::Sinh)},
|
||||||
|
"cosh" => {Some(Function::Cosh)},
|
||||||
|
"tanh" => {Some(Function::Tanh)},
|
||||||
|
"asinh" => {Some(Function::Asinh)},
|
||||||
|
"acosh" => {Some(Function::Acosh)},
|
||||||
|
"atanh" => {Some(Function::Atanh)},
|
||||||
|
"csch" => {Some(Function::Csch)},
|
||||||
|
"sech" => {Some(Function::Sech)},
|
||||||
|
"coth" => {Some(Function::Coth)},
|
||||||
|
|
||||||
|
"nounit" => {Some(Function::NoUnit)},
|
||||||
|
"tobase" => {Some(Function::ToBase)}
|
||||||
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -61,7 +61,13 @@ impl Operator {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from_string(s: &str) -> Option<Operator> {
|
pub fn from_string(s: &str) -> Option<Operator> {
|
||||||
match s {
|
|
||||||
|
let f = Function::from_string(s);
|
||||||
|
if let Some(f) = f {
|
||||||
|
return Some(Operator::Function(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
return match s {
|
||||||
"+" => {Some( Operator::Add )},
|
"+" => {Some( Operator::Add )},
|
||||||
"-" => {Some( Operator::Subtract )},
|
"-" => {Some( Operator::Subtract )},
|
||||||
"neg" => {Some( Operator::Negative )},
|
"neg" => {Some( Operator::Negative )},
|
||||||
|
@ -76,32 +82,8 @@ impl Operator {
|
||||||
"!" => {Some( Operator::Factorial )},
|
"!" => {Some( Operator::Factorial )},
|
||||||
"sqrt"|"rt"|"√" => {Some( Operator::Sqrt )},
|
"sqrt"|"rt"|"√" => {Some( Operator::Sqrt )},
|
||||||
|
|
||||||
"abs" => {Some( Operator::Function(Function::Abs) )},
|
|
||||||
"floor" => {Some( Operator::Function(Function::Floor) )},
|
|
||||||
"ceil" => {Some( Operator::Function(Function::Ceil) )},
|
|
||||||
"round" => {Some( Operator::Function(Function::Round) )},
|
|
||||||
"ln" => {Some( Operator::Function(Function::NaturalLog) )},
|
|
||||||
"log" => {Some( Operator::Function(Function::TenLog) )},
|
|
||||||
"sin" => {Some( Operator::Function(Function::Sin) )},
|
|
||||||
"cos" => {Some( Operator::Function(Function::Cos) )},
|
|
||||||
"tan" => {Some( Operator::Function(Function::Tan) )},
|
|
||||||
"asin" => {Some( Operator::Function(Function::Asin) )},
|
|
||||||
"acos" => {Some( Operator::Function(Function::Acos) )},
|
|
||||||
"atan" => {Some( Operator::Function(Function::Atan) )},
|
|
||||||
"csc" => {Some( Operator::Function(Function::Csc) )},
|
|
||||||
"secant" => {Some( Operator::Function(Function::Sec) )},
|
|
||||||
"cot" => {Some( Operator::Function(Function::Cot) )},
|
|
||||||
"sinh" => {Some( Operator::Function(Function::Sinh) )},
|
|
||||||
"cosh" => {Some( Operator::Function(Function::Cosh) )},
|
|
||||||
"tanh" => {Some( Operator::Function(Function::Tanh) )},
|
|
||||||
"asinh" => {Some( Operator::Function(Function::Asinh) )},
|
|
||||||
"acosh" => {Some( Operator::Function(Function::Acosh) )},
|
|
||||||
"atanh" => {Some( Operator::Function(Function::Atanh) )},
|
|
||||||
"csch" => {Some( Operator::Function(Function::Csch) )},
|
|
||||||
"sech" => {Some( Operator::Function(Function::Sech) )},
|
|
||||||
"coth" => {Some( Operator::Function(Function::Coth) )},
|
|
||||||
_ => None
|
_ => None
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -99,16 +99,19 @@ impl Quantity {
|
||||||
|
|
||||||
pub fn insert_unit(&mut self, ui: FreeUnit, pi: Scalar) { self.unit.insert(ui, pi) }
|
pub fn insert_unit(&mut self, ui: FreeUnit, pi: Scalar) { self.unit.insert(ui, pi) }
|
||||||
pub fn set_unit(&mut self, u: Unit) { self.unit = u; }
|
pub fn set_unit(&mut self, u: Unit) { self.unit = u; }
|
||||||
|
pub fn without_unit(&self) -> Quantity { Quantity::from_scalar(self.scalar.clone()) }
|
||||||
|
|
||||||
|
pub fn convert_to(&self, other: Quantity) -> Option<Quantity> {
|
||||||
pub fn convert_to(self, other: Quantity) -> Option<Quantity> {
|
|
||||||
if !self.unit.compatible_with(&other.unit) { return None; }
|
if !self.unit.compatible_with(&other.unit) { return None; }
|
||||||
|
|
||||||
|
let n = self.clone();
|
||||||
let fa = self.unit.to_base_factor();
|
let fa = self.unit.to_base_factor();
|
||||||
let fb = other.unit.to_base_factor();
|
let fb = other.unit.to_base_factor();
|
||||||
|
|
||||||
return Some(self.mul_no_convert(fa).div_no_convert(fb))
|
return Some(n.mul_no_convert(fa).div_no_convert(fb))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_to_base(&self) -> Quantity { self.convert_to(self.unit.to_base()).unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl FreeUnit {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get this unit in terms of base units
|
// Get this unit in terms of base units
|
||||||
pub fn get_base(&self) -> Quantity {
|
pub fn to_base(&self) -> Quantity {
|
||||||
let q = self.whole.base_factor();
|
let q = self.whole.base_factor();
|
||||||
let mut q = q.unwrap_or(Quantity::new_rational_from_string("1").unwrap());
|
let mut q = q.unwrap_or(Quantity::new_rational_from_string("1").unwrap());
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ impl Unit {
|
||||||
flag = false;
|
flag = false;
|
||||||
for (uo, po) in other.get_val() {
|
for (uo, po) in other.get_val() {
|
||||||
if {
|
if {
|
||||||
us.get_base().unit.compatible_with(&uo.get_base().unit)
|
us.to_base().unit.compatible_with(&uo.to_base().unit)
|
||||||
} {
|
} {
|
||||||
factor.insert_unit(us.clone(), po.clone());
|
factor.insert_unit(us.clone(), po.clone());
|
||||||
flag = true;
|
flag = true;
|
||||||
|
@ -141,7 +141,7 @@ impl Unit {
|
||||||
flag = false;
|
flag = false;
|
||||||
for (us, _) in self.get_val() {
|
for (us, _) in self.get_val() {
|
||||||
if {
|
if {
|
||||||
us.get_base().unit.compatible_with(&uo.get_base().unit)
|
us.to_base().unit.compatible_with(&uo.to_base().unit)
|
||||||
} {
|
} {
|
||||||
factor.insert_unit(us.clone(), po.clone());
|
factor.insert_unit(us.clone(), po.clone());
|
||||||
flag = true;
|
flag = true;
|
||||||
|
@ -186,11 +186,21 @@ impl Unit {
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_base(&self) -> Quantity {
|
||||||
|
let mut q = Quantity::new_rational(1f64).unwrap();
|
||||||
|
|
||||||
|
for (u, p) in self.get_val().iter() {
|
||||||
|
let b = u.to_base();
|
||||||
|
q.mul_assign_no_convert(b.pow(Quantity::from_scalar(p.clone())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return q;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unit {
|
impl Unit {
|
||||||
pub fn from_string(s: &str) -> Option<Quantity> {
|
pub fn from_string(s: &str) -> Option<Quantity> {
|
||||||
|
|
||||||
let b = freeunit_from_string(s);
|
let b = freeunit_from_string(s);
|
||||||
if b.is_none() { return None; }
|
if b.is_none() { return None; }
|
||||||
let b = Unit::from_free(b.unwrap());
|
let b = Unit::from_free(b.unwrap());
|
||||||
|
|
Loading…
Reference in New Issue