mirror of
https://github.com/PaddiM8/kalker.git
synced 2024-12-12 17:40:52 +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.
|
/// A tree structure of a statement.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -19,10 +19,7 @@ pub enum Expr {
|
|||||||
Var(Identifier),
|
Var(Identifier),
|
||||||
Group(Box<Expr>),
|
Group(Box<Expr>),
|
||||||
FnCall(Identifier, Vec<Expr>),
|
FnCall(Identifier, Vec<Expr>),
|
||||||
#[cfg(feature="rug")]
|
Literal(KalkFloat),
|
||||||
Literal(rug::Float),
|
|
||||||
#[cfg(not(feature="rug"))]
|
|
||||||
Literal(f64),
|
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Piecewise(Vec<ConditionalPiece>),
|
Piecewise(Vec<ConditionalPiece>),
|
||||||
Vector(Vec<Expr>),
|
Vector(Vec<Expr>),
|
||||||
|
@ -2,6 +2,7 @@ use crate::ast::{Expr, Stmt};
|
|||||||
use crate::ast::{Identifier, RangedVar};
|
use crate::ast::{Identifier, RangedVar};
|
||||||
use crate::calculation_result::CalculationResult;
|
use crate::calculation_result::CalculationResult;
|
||||||
use crate::errors::KalkError;
|
use crate::errors::KalkError;
|
||||||
|
use crate::kalk_value::KalkFloat;
|
||||||
use crate::kalk_value::KalkValue;
|
use crate::kalk_value::KalkValue;
|
||||||
use crate::lexer::TokenKind;
|
use crate::lexer::TokenKind;
|
||||||
use crate::parser::DECL_UNIT;
|
use crate::parser::DECL_UNIT;
|
||||||
@ -323,28 +324,20 @@ fn eval_var_expr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[cfg(feature = "rug")]
|
|
||||||
fn eval_literal_expr(
|
fn eval_literal_expr(
|
||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
value: rug::Float,
|
value: KalkFloat,
|
||||||
unit: Option<&String>,
|
unit: Option<&String>,
|
||||||
) -> Result<KalkValue, KalkError> {
|
) -> Result<KalkValue, KalkError> {
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut float = float!(value);
|
let mut float = float!(value);
|
||||||
|
#[cfg(feature = "rug")]
|
||||||
float.set_prec(context.precision);
|
float.set_prec(context.precision);
|
||||||
|
|
||||||
Ok(KalkValue::Number(float, float!(0), unit.cloned()))
|
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(
|
fn eval_group_expr(
|
||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
|
@ -18,6 +18,12 @@ use self::rounding::EstimationResult;
|
|||||||
|
|
||||||
const ACCEPTABLE_COMPARISON_MARGIN: f64 = 0.00000001;
|
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]
|
#[macro_export]
|
||||||
#[cfg(not(feature = "rug"))]
|
#[cfg(not(feature = "rug"))]
|
||||||
macro_rules! float {
|
macro_rules! float {
|
||||||
|
@ -4,6 +4,7 @@ use crate::analysis;
|
|||||||
use crate::ast::Identifier;
|
use crate::ast::Identifier;
|
||||||
use crate::calculation_result::CalculationResult;
|
use crate::calculation_result::CalculationResult;
|
||||||
use crate::errors::KalkError;
|
use crate::errors::KalkError;
|
||||||
|
use crate::kalk_value::KalkFloat;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Expr, Stmt},
|
ast::{Expr, Stmt},
|
||||||
interpreter,
|
interpreter,
|
||||||
@ -770,8 +771,8 @@ fn skip_newlines(context: &mut Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rug")]
|
fn string_to_num(value: &str) -> Result<KalkFloat, KalkError> {
|
||||||
fn string_to_num(value: &str) -> Result<rug::Float, KalkError> {
|
#[cfg(feature = "rug")]
|
||||||
use rug::ops::Pow;
|
use rug::ops::Pow;
|
||||||
|
|
||||||
if value.contains('E') {
|
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 left = crate::float!(string_to_num(parts[0])?);
|
||||||
let right = crate::float!(string_to_num(parts[1])?);
|
let right = crate::float!(string_to_num(parts[1])?);
|
||||||
|
|
||||||
|
#[cfg(feature = "rug")]
|
||||||
return Ok(left * 10.pow(right));
|
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));
|
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 {
|
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)
|
Some(result)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sum = 0f64;
|
let mut sum = float!(0f64);
|
||||||
let length = value.find('_').unwrap_or(value.len());
|
let length = value.find('_').unwrap_or(value.len());
|
||||||
let mut i = (value.find('.').unwrap_or(length) as i32) - 1;
|
let mut i = (value.find('.').unwrap_or(length) as i32) - 1;
|
||||||
for c in value.chars() {
|
for c in value.chars() {
|
||||||
|
Loading…
Reference in New Issue
Block a user