Skip to content

Tracking Issue: Math expression parser/calculator #2026

@Keavon

Description

@Keavon

This is our library at /libraries/math-parser that uses a parsing framework (begun in #2033 with Pest but now switching to Chumsky) that takes a string at runtime and calculates its result, including units and dimensional analysis.

This would make a great solo contribution for somebody interested in developing a robust solution for this problem without needing to learn any of Graphite's code base. It would also make a good university team/solo "capstone" project, which our organization can serve as an "industry sponsor" for.

Roadmap

  • Real numbers
  • Complex numbers
  • Vec2/Vec3/Quaternions
  • Units
  • Documentation
  • Error reporting
  • Compiling into Graphene AST

Operators

  • Infix operators:
    • Addition: +
    • Subtraction: -
    • Multiplication: *
    • Division: /
    • Modulo: %
    • Exponentiation: ^
    • Equals: ==
    • Not Equals: !=,
    • Less Than or Equal To: <=,
    • Greater Than or Equal To: >=,
    • Less Than: <
    • Greater Than: >
    • Or: ||
    • And: &&
  • Prefix operators:
    • Unary Plus: +
    • Unary Minus: -
    • Square root:
    • Not: !
  • Postfix operators:
    • Factorial: !
  • Grouping operators:
    • Parentheses: ( )

Functions

  • Trig:
    • sin(), cos(), tan()
    • csc(), sec(), cot()
  • Inverse trig (aliases: ar- and arc- prefixes):
    • asin(), acos(), atan(), atan2()
    • acsc(), asec(), acot()
  • Hyperbolic:
    • sinh(), cosh(), tanh()
    • csch(), sech(), coth()
  • Inverse hyperbolic (aliases: ar- and arc- prefixes):
    • asinh(), acosh(), atanh()
    • acsch(), asech(), acoth()
  • Logarithm:
    • Natural log: ln()
    • Logarithm base N: logN() (alias: log_N())
      • Examples: log2(), log3.25(), log_10()
    • Logarithm with variable base: log(x, b)
  • Exponents:
    • Power of e: exp(n)
    • Power of N: pow(x, n)
      • Examples: pow2(5), pow3.25(5), pow_10(5)
    • Power with variable exponent: root(x, n)
  • Roots:
    • Square root: sqrt()
    • Cube root: cbrt()
    • Root base N: rootN(x) (alias: root_N(x))
      • Examples: root2(), root3.25(), root_10()
    • Root with variable degree: root(x, n)
  • Geometry:
    • Hypotenuse equation sqrt(a^2 + b^2): hypot()
  • Mapping:
    • Absolute value: abs() (magnitude of a real or complex number)
    • Floor: floor()
    • Ceiling: ceil()
    • Round: round()
    • Clamp: clamp(x, min, max)
    • Lerp: lerp(a, b, t)
    • Slerp: slerp(a, b, t) (quaternions only)
    • Remap: remap(value, inA, inB, outA, outB)
    • Truncate: trunc()
    • Fractional part: fract()
    • Sign: sign()
    • Greatest common denominator: gcd() (implemented here)
    • Least common multiple: lcm() (implemented here)
  • Logical
    • Is NaN: isnan()
    • If: if(cond, if_true, if_false)
  • Complex numbers:
    • Real part: real()
    • Imaginary part: imag()
    • Complex conjugate: conj()
    • Angle: arg() (angle from the +real axis in radians)

Constants

  • Infinity: inf, INF, infinity, INFINITY,
  • Basis vectors: i, j, k
  • Pi: pi, PI, π
  • Tau: tau, TAU, τ
  • Euler's Number: e
  • Golden Ratio: phi, PHI, φ

Variables

  • Single-letter variables (examples: x, y, z)
  • Multi-letter variables (examples: theta, alpha, beta, gamma)
  • Non-Latin letters and symbols (examples: λ, , א, 👍)
  • Special character prefixed variables (examples: #foo, $foo, ~foo, etc.)

Number and unit representations

  • Scientific notation (examples: 1e-6, 2.5E3)
  • Units (examples: 5m, 5 m, 3.5kg, 3.5 kg, 2.5m/s^2, 2.5 m/s^2)

Number systems

  • Basis 1: Real numbers (examples: 0, 42, -42, 0.5, 3.14159, -2.71828)
  • Bases 1, i: Complex numbers (examples: 3i, -2.5i, 1.5e-3i, 2.5e3 + 2.1e-2i)
  • Bases 1, i, j, k: Quaternions
    • Vec2 (examples: 3i + 2j, -3i - 2j)
    • Vec3 (examples: 3i + 2j + k, -3i - 2j - k)
    • Full quaternion (examples: 4 + 3i + 2j + k, 4 + 3i + 2j, 4 + 3i)

Reading results

  • Query as f{32, 64}/{u, i}{8, 16, 32, 64, 128} (1 basis -> x, the real part)
  • Query as Vec2 (1, i bases -> x, y, the complex parts)
  • Query as Vec3 (i, j, k bases -> x, y, z, the non-real parts)
  • Query as Vec4 (1, i, j, k bases -> w, x, y, z, all parts)
  • Query as NurbsPoint (1, i, j, k bases -> weight, x, y, z, all parts)
  • Query as Quaternion (1, i, j, k bases -> w, x, y, z, all parts)

Implicit multiplication

  • Automatically handle multiplication without explicit * operator
    • Between numbers and variables/constants (examples: 3x, 2pi)
    • Between numbers and functions (example: 4sin(90deg))
    • Between space-separated adjacent variables/constants (examples: x y, pi r^2)

Units

  • In addition to the unit abbreviations, full unit names can be used in either singular or plural form
  • Math expressions perform dimensional analysis
    • The scalar part is simplified while the unit part is kept as a fraction if it cannot be simplified
    • Units should only be combined if they are mixed with other units in either the numerator or denominator, defaulting to the unit that would best avoid loss of precision
      • Example: 5m + 3m -> 8m
      • Example: 5ft + 3ft -> 8ft
      • Example: 5m + 3ft -> 5.9144m (meters are chosen because 1ft = 0.3048m exactly, while its inverse can't be represented exactly)
  • Values can always be requested for conversion to a specific unit in the API

Unit list

  • Unitless
  • Pixels:
    • px
  • Length:
    • Meter m and its prefixes
    • thou, pc, pt, in/", ft/', yd, mi, nmi
  • Area:
    • length^2
    • acre, are, hectare
  • Volume:
    • length^3, area * length
    • Paper sizes: A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
    • floz, cup, pint, qt, gal
    • l and its prefixes
  • Mass:
    • Kilogram kg and its prefixes
    • gr, oz, lb, ton, tonne
  • Time:
    • Second s and its prefixes
    • min, hr, day
  • Angle:
    • Degrees: deg/°
    • Radians: rad (unitless is not an angle)
    • Turns: turn
  • Velocity:
    • length / time
    • m/s, km/h, mph, knot
  • Acceleration:
    • velocity / time, length / time^2
    • m/s^2, ft/s^2, g
  • Angular velocity:
    • angle / time
    • deg/s, rad/s, rpm, rps
  • Angular acceleration:
    • angular velocity / time, angle / time^2
    • deg/s^2, rad/s^2
  • Illumination
    • TODO: Research and lay out what these are, like candela, nits, etc.

Unit metric prefixes

  • Nano (n)
  • Micro (µ, u)
  • Milli (m)
  • Centi (c)
  • Deci (d)
  • Deca (da)
  • Hecto (h)
  • Kilo (k)
  • Mega (M)
  • Giga (G)
  • Tera (T)

API features

  • Parsing/construction separate from evaluation so the same expression can be run repeatedly with different variables without wasted performance
  • Setting the result of one expression to a variable for use in subsequent expressions
  • Custom supplied units, unit symbols, functions, and constants
  • Syntax highlighting

Metadata

Metadata

Assignees

Labels

Projects

Status

Ongoing Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions