mirror of
https://github.com/PaddiM8/kalker.git
synced 2024-12-12 09:30:40 +01:00
Allow big numbers as input, #130
This commit is contained in:
parent
8ffc0e1e9d
commit
f846a5b59e
@ -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)]
|
||||
@ -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>),
|
||||
|
@ -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;
|
||||
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
@ -770,8 +771,8 @@ 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') {
|
||||
@ -779,24 +780,10 @@ fn string_to_num(value: &str) -> Result<rug::Float, KalkError> {
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user