Skip to content

Commit

Permalink
Allow big numbers as input, #130
Browse files Browse the repository at this point in the history
  • Loading branch information
PaddiM8 committed Apr 2, 2024
1 parent 8ffc0e1 commit f846a5b
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 38 deletions.
7 changes: 2 additions & 5 deletions kalk/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::lexer::TokenKind;
use crate::{kalk_value::KalkFloat, lexer::TokenKind};

/// A tree structure of a statement.
#[derive(Debug, Clone, PartialEq)]
Expand All @@ -19,10 +19,7 @@ pub enum Expr {
Var(Identifier),
Group(Box<Expr>),
FnCall(Identifier, Vec<Expr>),
#[cfg(feature="rug")]
Literal(rug::Float),
#[cfg(not(feature="rug"))]
Literal(f64),
Literal(KalkFloat),
Boolean(bool),
Piecewise(Vec<ConditionalPiece>),
Vector(Vec<Expr>),
Expand Down
17 changes: 5 additions & 12 deletions kalk/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::ast::{Expr, Stmt};
use crate::ast::{Identifier, RangedVar};
use crate::calculation_result::CalculationResult;
use crate::errors::KalkError;
use crate::kalk_value::KalkFloat;
use crate::kalk_value::KalkValue;
use crate::lexer::TokenKind;
use crate::parser::DECL_UNIT;
Expand Down Expand Up @@ -323,28 +324,20 @@ fn eval_var_expr(
}

#[allow(unused_variables)]
#[cfg(feature = "rug")]
fn eval_literal_expr(
context: &mut Context,
value: rug::Float,
value: KalkFloat,
unit: Option<&String>,
) -> Result<KalkValue, KalkError> {

#[allow(unused_mut)]
let mut float = float!(value);
#[cfg(feature = "rug")]
float.set_prec(context.precision);

Ok(KalkValue::Number(float, float!(0), unit.cloned()))
}

#[allow(unused_variables)]
#[cfg(not(feature = "rug"))]
fn eval_literal_expr(
context: &mut Context,
value: f64,
unit: Option<&String>,
) -> Result<KalkValue, KalkError> {
Ok(KalkValue::Number(float!(value), float!(0), unit.cloned()))
}

fn eval_group_expr(
context: &mut Context,
expr: &Expr,
Expand Down
6 changes: 6 additions & 0 deletions kalk/src/kalk_value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ use self::rounding::EstimationResult;

const ACCEPTABLE_COMPARISON_MARGIN: f64 = 0.00000001;

#[cfg(feature = "rug")]
pub(crate) type KalkFloat = rug::Float;

#[cfg(not(feature = "rug"))]
pub(crate) type KalkFloat = f64;

#[macro_export]
#[cfg(not(feature = "rug"))]
macro_rules! float {
Expand Down
23 changes: 5 additions & 18 deletions kalk/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::analysis;
use crate::ast::Identifier;
use crate::calculation_result::CalculationResult;
use crate::errors::KalkError;
use crate::kalk_value::KalkFloat;
use crate::{
ast::{Expr, Stmt},
interpreter,
Expand Down Expand Up @@ -770,33 +771,19 @@ fn skip_newlines(context: &mut Context) {
}
}

#[cfg(feature = "rug")]
fn string_to_num(value: &str) -> Result<rug::Float, KalkError> {
fn string_to_num(value: &str) -> Result<KalkFloat, KalkError> {
#[cfg(feature = "rug")]
use rug::ops::Pow;

if value.contains('E') {
let parts = value.split('E').collect::<Vec<_>>();
let left = crate::float!(string_to_num(parts[0])?);
let right = crate::float!(string_to_num(parts[1])?);

#[cfg(feature = "rug")]
return Ok(left * 10.pow(right));
}

let base = get_base(value)?;
if let Some(result) = crate::radix::parse_float_radix(&value.replace(' ', ""), base) {
Ok(crate::float!(result))
} else {
Err(KalkError::InvalidNumberLiteral(value.into()))
}
}

#[cfg(not(feature = "rug"))]
fn string_to_num(value: &str) -> Result<f64, KalkError> {
if value.contains('E') {
let parts = value.split('E').collect::<Vec<_>>();
let left = crate::float!(string_to_num(parts[0])?);
let right = crate::float!(string_to_num(parts[1])?);

#[cfg(not(feature = "rug"))]
return Ok(left * 10_f64.powf(right));
}

Expand Down
14 changes: 11 additions & 3 deletions kalk/src/radix.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
pub fn parse_float_radix(value: &str, radix: u8) -> Option<f64> {
use crate::{float, kalk_value::KalkFloat};

pub fn parse_float_radix(value: &str, radix: u8) -> Option<KalkFloat> {
if radix == 10 {
return if let Ok(result) = value.parse::<f64>() {
#[cfg(feature = "rug")]
let parsed = rug::Float::parse(value).map(|valid| crate::float!(valid));

#[cfg(not(feature = "rug"))]
let parsed = value.parse::<f64>();

return if let Ok(result) = parsed {
Some(result)
} else {
None
};
}

let mut sum = 0f64;
let mut sum = float!(0f64);
let length = value.find('_').unwrap_or(value.len());
let mut i = (value.find('.').unwrap_or(length) as i32) - 1;
for c in value.chars() {
Expand Down

0 comments on commit f846a5b

Please sign in to comment.