mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 11:28:30 +08:00
Add math-parser library (#2033)
* start of parser * ops forgot * reorder files and work on executer * start of parser * ops forgot * reorder files and work on executer * Cleanup and fix tests * Integrate into the editor * added unit checking at parse time * fix tests * fix issues * fix editor intergration * update pest grammer to support units * units should be working, need to set up tests to know * make unit type store exponants as i32 * remove scale, insted just multiply the literal by the scale * unit now contains empty unit,remove options * add more tests and implement almost all unary operators * add evaluation context and variables * function calling, api might be refined later * add constants, change function call to not be as built into the parser and add tests * add function definitions * remove meval * remove raw-rs from workspace * add support for numberless units * fix unit handleing logic, add some "unit" tests(haha) * make it so units cant do implcit mul with idents * add bench and better tests * fix editor api * remove old test * change hashmap context to use deref * change constants to use hashmap instad of function --------- Co-authored-by: hypercube <0hypercube@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
128
libraries/math-parser/src/value.rs
Normal file
128
libraries/math-parser/src/value.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
use std::f64::consts::PI;
|
||||
|
||||
use num_complex::ComplexFloat;
|
||||
|
||||
use crate::ast::{BinaryOp, UnaryOp};
|
||||
|
||||
pub type Complex = num_complex::Complex<f64>;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Value {
|
||||
Number(Number),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn from_f64(x: f64) -> Self {
|
||||
Self::Number(Number::Real(x))
|
||||
}
|
||||
|
||||
pub fn as_real(&self) -> Option<f64> {
|
||||
match self {
|
||||
Self::Number(Number::Real(val)) => Some(*val),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Value {
|
||||
fn from(x: f64) -> Self {
|
||||
Self::from_f64(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Value::Number(num) => num.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Number {
|
||||
Real(f64),
|
||||
Complex(Complex),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Number {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Number::Real(real) => real.fmt(f),
|
||||
Number::Complex(complex) => complex.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Number {
|
||||
pub fn binary_op(self, op: BinaryOp, other: Number) -> Number {
|
||||
match (self, other) {
|
||||
(Number::Real(lhs), Number::Real(rhs)) => {
|
||||
let result = match op {
|
||||
BinaryOp::Add => lhs + rhs,
|
||||
BinaryOp::Sub => lhs - rhs,
|
||||
BinaryOp::Mul => lhs * rhs,
|
||||
BinaryOp::Div => lhs / rhs,
|
||||
BinaryOp::Pow => lhs.powf(rhs),
|
||||
};
|
||||
Number::Real(result)
|
||||
}
|
||||
|
||||
(Number::Complex(lhs), Number::Complex(rhs)) => {
|
||||
let result = match op {
|
||||
BinaryOp::Add => lhs + rhs,
|
||||
BinaryOp::Sub => lhs - rhs,
|
||||
BinaryOp::Mul => lhs * rhs,
|
||||
BinaryOp::Div => lhs / rhs,
|
||||
BinaryOp::Pow => lhs.powc(rhs),
|
||||
};
|
||||
Number::Complex(result)
|
||||
}
|
||||
|
||||
(Number::Real(lhs), Number::Complex(rhs)) => {
|
||||
let lhs_complex = Complex::new(lhs, 0.0);
|
||||
let result = match op {
|
||||
BinaryOp::Add => lhs_complex + rhs,
|
||||
BinaryOp::Sub => lhs_complex - rhs,
|
||||
BinaryOp::Mul => lhs_complex * rhs,
|
||||
BinaryOp::Div => lhs_complex / rhs,
|
||||
BinaryOp::Pow => lhs_complex.powc(rhs),
|
||||
};
|
||||
Number::Complex(result)
|
||||
}
|
||||
|
||||
(Number::Complex(lhs), Number::Real(rhs)) => {
|
||||
let rhs_complex = Complex::new(rhs, 0.0);
|
||||
let result = match op {
|
||||
BinaryOp::Add => lhs + rhs_complex,
|
||||
BinaryOp::Sub => lhs - rhs_complex,
|
||||
BinaryOp::Mul => lhs * rhs_complex,
|
||||
BinaryOp::Div => lhs / rhs_complex,
|
||||
BinaryOp::Pow => lhs.powf(rhs),
|
||||
};
|
||||
Number::Complex(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unary_op(self, op: UnaryOp) -> Number {
|
||||
match self {
|
||||
Number::Real(real) => match op {
|
||||
UnaryOp::Neg => Number::Real(-real),
|
||||
UnaryOp::Sqrt => Number::Real(real.sqrt()),
|
||||
|
||||
UnaryOp::Fac => todo!("Implement factorial"),
|
||||
},
|
||||
|
||||
Number::Complex(complex) => match op {
|
||||
UnaryOp::Neg => Number::Complex(-complex),
|
||||
UnaryOp::Sqrt => Number::Complex(complex.sqrt()),
|
||||
|
||||
UnaryOp::Fac => todo!("Implement factorial"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_f64(x: f64) -> Self {
|
||||
Self::Real(x)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user