Compare commits

..
3 changed files with 7 additions and 54 deletions

View file

@ -18,47 +18,9 @@ fn main() {
} }
}; };
println!("{}", parse_and_calc_humanreadable(input));
}
pub fn parse_and_calc_humanreadable(mut input: String) -> String {
let should_add_back_equals = if let Some((i, _)) = input
.chars()
.enumerate()
.filter(|(_, c)| !matches!(c, ' ' | '&' | '\n'))
.find(|(_, c)| *c == '=')
{
input.remove(i);
true
} else {
false
};
// no need to remove the character here,
// as we ignore the ampersand in all other logic already
let should_add_back_alignment = input.contains('&');
let result = parse_and_calc(&input); let result = parse_and_calc(&input);
format!( println!("{result:.0$}", get_significant_digits(&result));
"{0}{result:.1$}",
if should_add_back_equals && should_add_back_alignment {
"& = "
} else if should_add_back_equals {
"= "
} else if should_add_back_alignment {
"& "
} else {
""
},
get_significant_digits(&result),
)
}
#[test]
fn test_equals_readdition() {
assert_eq!(parse_and_calc_humanreadable(" = 11".into()), "= 11");
assert_eq!(parse_and_calc_humanreadable(" &= 11".into()), "& = 11");
assert_eq!(parse_and_calc_humanreadable(" & 11".into()), "& 11");
} }
pub fn parse_and_calc(s: &str) -> Float { pub fn parse_and_calc(s: &str) -> Float {

View file

@ -22,7 +22,7 @@ impl TryFrom<char> for Operator {
fn try_from(value: char) -> Result<Self, Self::Error> { fn try_from(value: char) -> Result<Self, Self::Error> {
match value { match value {
'+' => Ok(Self::Plus), '+' => Ok(Self::Plus),
'-' | '' => Ok(Self::Minus), '-' => Ok(Self::Minus),
'*' | '×' => Ok(Self::Mult), '*' | '×' => Ok(Self::Mult),
'/' | '÷' => Ok(Self::Div), '/' | '÷' => Ok(Self::Div),
'^' => Ok(Self::Exp), '^' => Ok(Self::Exp),
@ -79,12 +79,11 @@ impl FromStr for Nodes {
} }
/// A function to check if the given `char` should be used by the parser. /// A function to check if the given `char` should be used by the parser.
/// ///
/// We ignore whitespace since it has no semantic significance in typst /// We ignore whitespace since it has no semantic significance in typst aside from variables,
/// (aside from variables, which are not implemented) /// (which are not implemented)
/// and `&` because it is only used for visual alignment. /// and `&` because it is only used for visual alignment.
/// ///
/// Newlines are also ignored because they're likely accidental; /// Newlines are also ignored because they're likely accidental; like in the case of `echo 1+1 | tylc`.
/// like in the case of `echo 1+1 | tylc`.
fn is_not_ignored_char(c: &char) -> bool { fn is_not_ignored_char(c: &char) -> bool {
!matches!(c, ' ' | '&' | '\n') !matches!(c, ' ' | '&' | '\n')
} }
@ -113,10 +112,7 @@ impl FromStr for Nodes {
} }
} }
ParsingState::ReadingNumber(start_index) => { ParsingState::ReadingNumber(start_index) => {
if !is_number_char(c) if !is_number_char(c) {
// don't stop reading number on a special case, eg "1e-1"
&& !(filtered_string.chars().nth(i - 1) == Some('e') && c == '-')
{
nodes.push(Node::Number( nodes.push(Node::Number(
Float::parse(&filtered_string[start_index..i]) Float::parse(&filtered_string[start_index..i])
.map_err(|e| { .map_err(|e| {
@ -185,6 +181,6 @@ impl FromStr for Nodes {
} }
} }
Ok(Self(nodes)) Ok(Nodes(nodes))
} }
} }

View file

@ -5,11 +5,6 @@ use rug::Float;
use crate::nodes::{Function, Node, Nodes, Operator, PREC}; use crate::nodes::{Function, Node, Nodes, Operator, PREC};
#[test]
fn e_edge_case() {
assert_eq!(Nodes::from_str("1e-1").unwrap().evaluate().to_f64(), 0.1)
}
#[test] #[test]
fn implicit_mult() { fn implicit_mult() {
assert_eq!( assert_eq!(