Skip to content

Math Parser

Endor H edited this page Jan 24, 2023 · 4 revisions

Lazulib provides a very flexible (albeit inefficient) general purpose recursive descent expression parser. This expression parser supports custom operator hierarchies, functions and variables to be declared.

Lazulib defines two built-in expression parser classes:

  • UnicodeMathDoubleExpressionParser, uses the "Unicode Math" set of names, functions and operators to evaluate a mathematical expression as a double number
  • UnicodeMathSyntaxHighlightParser, which evaluates "Unicode Math" expressions into formatted text, which can be used to provide syntax highlighting

Unicode Math Format

Lazulib defines its own format for mathematical expressions, which it refers to as "Unicode Math". This name is purely informal and is not related to Microsoft's "Unicode Nearly Plain-Text Encoding of Mathematics", sometimes also referred as "UnicodeMath", as the mod's one is merely limited to numerical expressions.

The format is best documented by the source code that declares it.

Operator Hierarchy

The Unicode Math format supports the following operators groups, in increasing order of priority:

  • Ternary operator (right associative ternary)

    • a ? b : c (evaluates to b if a ≠ 0 else to c) (classic ternary operator)
    • a if b else c (evaluates to a if b ≠ 0 else to c) (python if expression)
  • Logical disjunction (left associative binary)

    (evaluates to 1 if a ≠ 0 or `b ≠ 0')

    • a || b (classic C operator)
    • a ∨ b (logical or symbol)
    • a or b
  • Exclusive logical disjunction (left associative binary)

    (evaluates to 0 if a = 0 = b or a ≠ 0 ≠ b and to 1 otherwise)

    • a ⊻ b (logical xor symbol)
    • a xor b (idem)
  • Logical conjunction (left associative binary)

    (evaluates to 1 if a ≠ 0 and b ≠ 0 and to 0 otherwise)

    • a && b (classic C operator)
    • a ∧ b (logical and symbol)
    • a and b
  • Logical negation (prefix unary)

    (evaluates to 1 if a = 0 and to 0 otherwise)

    • !a (classic C operator)
    • ¬a (logical not symbol)
  • Comparison operators (left joined by conjunction binary)

    (a < b < c ≠ 0 ≠ d is joined as a < b && b < c && c ≠ 0 && 0 ≠ d)

    • a = b/a == b (equality)
    • a ≠ b/a != b (inequality)
    • a ≤ b/a <= b (less than or equal)
    • a ≥ b/a >= b (greater than or equal)
    • a < b/a ≨ b (less than)
    • a > b/a ≩ b (greater than)
    • a ≈ b (approximately equal) (floating point comparison)
    • a ≈ₙ b (equal to the n-th decimal place, where n is written as an Unicode subindex)
  • Coercion (left associative binary)

    • a ?: b (evaluates to a if a is finite and not NaN, otherwise to b) (Elvis operator)
  • Bitwise or (left associative binary)

    • a_|_b (requires spaces around the | symbol to disambiguate from abs parentheses)
    • a ¦ b (Broken bar symbol) (does not require spaces)
  • Bitwise xor (left associative binary)

    • a ⊕ b (direct sum symbol)
  • Bitwise and (left associative binary)

    • a & b
  • Bitshift (left associative binary)

    • a << b (logical left shift)
    • a >> b (logical right shift)
    • a >>> b (arithmetic right shift) (right shift with rotation)
  • Addition and Substraction (left associative binary)

    • a + b
    • a - b
  • Product and Divisions (left associative binary)

    • a * b/a ⋅ b/a · b (product)
    • a ÷ b/a // b (floor division)
    • a / b (division)
    • a % b (remainder)
  • Negation (prefix unary)

    • +a (evaluates to a)
    • -a (negation)
    • ~a (bitwise negation)
  • Root (prefix unary)

    • √a (square root)
    • ∛a (cubic root)
    • ∜a (quartic root)
    • ⁿ√a (n-th root, where n is written as an Unicode superscript)
  • Parentheses (surrounding unary)

    • (a) (evaluates to a)
    • |a| (absolute value)
    • ⌊a⌋ (floor function) (round down)
    • ⌈a⌉ (ceil function) (round up)
    • ⌊a⌉ (round function)
  • Exponentiation (right associative)

    • a^b (power)
    • a^-b (negative power)
  • Natural power (unary superscript postfix)

    • aⁿ (evaluates to a^n, where n is written as an Unicode superscript)

Built-in names

The Unicode Math format defines the following built-in names:

  • π (ratio of a circumference to its diameter)
  • e (base of the natural logarithm)
  • NaN (not a number)
  • (positive infinity)

Built-in functions

  • Roots
    • sqrt (square root)
    • cbrt (cubic root)
  • Trigonometric
    • sin
    • cos
    • tan
    • sec
    • csc
    • cot
    • asin
    • acos
    • atan (can also accept two arguments, acting as atan2)
    • atan2
    • asec
    • acsc
    • acot
  • Conversions
    • rad (degrees to radians)
    • deg (radians to degrees)
  • Trigonometric in degrees
    • sind
    • cosd
    • tand
    • secd
    • cscd
    • cotd
    • asind
    • acosd
    • atand (can also accept two arguments, acting as atan2)
    • asecd
    • acscd
    • acotd
  • Hyperbolic
    • sinh
    • cosh
    • tanh
    • sech
    • csch
    • tanh
    • asinh
    • acosh
    • atanh
    • acoth
    • asech
    • acsch
  • Exponentiation
    • exp
    • ln/log (base e)
    • log2 (base 2)
    • log10 (base 10)
    • log1p (ln(1 + x))
  • Modulus
    • mod (always positive)
    • rem (same sign as dividend)
  • Rectification
    • abs
    • max
    • min
    • clamp(x, min, max)
    • lerp(t, min, max) (linear interpolation)
    • clampLerp(t, min, max) (clamped linear interpolation)
    • sign (signum)
    • copySign
    • flipSign
    • relu
    • sigmoid
    • rect
  • Rounding
    • round
    • floor
    • ceil
  • Sinc
    • sinc
    • cosc
  • NaN/Infinite
    • isNaN
    • isFinite
    • isInfinite
  • Random
    • rand() (between 0 and 1)
    • rand(d) (between 0 and d)
    • rand(a, b) (between a and b)
    • randGaussian() (mean 0, std 1)
    • randGaussian(std) (mean 0)
    • randGaussian(mean, std)
    • randInt(max) (between 0 and max)
    • randInt(a, b) (between a and b)
  • Interpolation
    • quadInOut
    • quadIn
    • quadOut

Usage

For usage examples, you may see Lazulib's tests for UnicodeMathDoubleExpressionParser.

Syntax Highlighting

Lazulib provides a special built-in Math Parser, which evaluates expressions into formatted text with syntax highlighting. To use it, simply replace the UnicodeMathDoubleExpressionParser by UnicodeMathSyntaxHighlightParser in your code.

The syntax highlighting can be customized with a HighlighterColorTheme

Clone this wiki locally