mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-06-23 19:21:26 +02:00
Fixed integration with expressions like xdx
This commit is contained in:
parent
eaa520fa67
commit
aaa3c6cf61
@ -112,7 +112,7 @@ pub enum CalcError {
|
|||||||
impl ToString for CalcError {
|
impl ToString for CalcError {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
CalcError::ExpectedDx => format!("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx)."),
|
CalcError::ExpectedDx => format!("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx). You may need to put parenthesis around the expression before dx/dy/du/etc."),
|
||||||
CalcError::IncorrectAmountOfArguments(expected, func, got) => format!(
|
CalcError::IncorrectAmountOfArguments(expected, func, got) => format!(
|
||||||
"Expected {} arguments for function {}, but got {}.",
|
"Expected {} arguments for function {}, but got {}.",
|
||||||
expected, func, got
|
expected, func, got
|
||||||
@ -527,8 +527,22 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, CalcError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Eg. dx inside an integral, should be parsed as *one* identifier
|
// Eg. dx inside an integral, should be parsed as *one* identifier
|
||||||
if context.is_in_integral && identifier.full_name.starts_with("d") {
|
// Reverse the identifier and take two. This gets the last two characters (in reversed order).
|
||||||
return Ok(Expr::Var(identifier));
|
// Now reverse this to finally get the last two characters in correct order.
|
||||||
|
// It's a bit weird, but it should work for more than ASCII.
|
||||||
|
let last_two_chars_rev: String = identifier.full_name.chars().rev().take(2).collect();
|
||||||
|
let last_two_chars: String = last_two_chars_rev.chars().rev().collect();
|
||||||
|
let mut dx = None;
|
||||||
|
if context.is_in_integral && last_two_chars.starts_with("d") {
|
||||||
|
// If the token contains more than just "dx",
|
||||||
|
// save the dx/dy/du/etc. in a variable, that can be
|
||||||
|
// used further down when splitting the identifier into multiple variables.
|
||||||
|
if identifier.full_name.len() > 2 {
|
||||||
|
// This variable will be used further down in order to separate dx from the rest.
|
||||||
|
dx = Some(last_two_chars);
|
||||||
|
} else {
|
||||||
|
return Ok(Expr::Var(Identifier::from_full_name(&last_two_chars)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eg. x
|
// Eg. x
|
||||||
@ -547,14 +561,19 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, CalcError> {
|
|||||||
return Ok(Expr::Var(identifier));
|
return Ok(Expr::Var(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut chars = identifier.pure_name.chars();
|
let mut chars: Vec<char> = identifier.pure_name.chars().collect();
|
||||||
let mut left = Expr::Var(Identifier::from_full_name(
|
let mut left = Expr::Var(Identifier::from_full_name(&chars[0].to_string()));
|
||||||
&chars.next().unwrap().to_string(),
|
|
||||||
));
|
// If there is a an infinitesimal at the end,
|
||||||
|
// remove it from 'chars', since it should be separate.
|
||||||
|
if let Some(_) = dx {
|
||||||
|
chars.pop();
|
||||||
|
chars.pop();
|
||||||
|
}
|
||||||
|
|
||||||
// Turn each individual character into its own variable reference.
|
// Turn each individual character into its own variable reference.
|
||||||
// This parses eg `xy` as `x*y` instead of *one* variable.
|
// This parses eg `xy` as `x*y` instead of *one* variable.
|
||||||
let mut right_chars = chars.peekable();
|
let mut right_chars = chars.iter().skip(1).peekable();
|
||||||
while let Some(c) = right_chars.next() {
|
while let Some(c) = right_chars.next() {
|
||||||
// If last iteration
|
// If last iteration
|
||||||
let right = if right_chars.peek().is_none() {
|
let right = if right_chars.peek().is_none() {
|
||||||
@ -588,7 +607,14 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, CalcError> {
|
|||||||
left = Expr::Binary(Box::new(left), TokenKind::Star, Box::new(right));
|
left = Expr::Binary(Box::new(left), TokenKind::Star, Box::new(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: When implementing derivation for variables, make sure to add the derivation here.
|
if let Some(dx) = dx {
|
||||||
|
left = Expr::Binary(
|
||||||
|
Box::new(left),
|
||||||
|
TokenKind::Star,
|
||||||
|
Box::new(Expr::Var(Identifier::from_full_name(&dx))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(left)
|
Ok(left)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user