macro librarylibs/Polynomials/src/Polynomials.xtlm
Polynomials: its macro library -- p_oly<, maths notation compiled. Imported with the functions, under one alias: "py:" u_se< "Polynomials". A macro is a function from the source text written left and right of its call to the source that replaces the call, run before the program is compiled (X_eTaL MC10). Names with m: are macros; those under h: are private to this file.
Parsing
ʰs̲queezed : Char -> Char
The text without spaces.
ʰs̲queezed ← { t → (t ≠ f̲irst " ") r̲eplicate t }
ʰt̲erms : Char -> Box Char
The terms of a sum: a new term at each + or - after the first character; each keeps its sign.
ʰt̲erms ← { t → s ← (t m̲ember? "+-") ∧ (r̲ange t̲ally t) > 1 (1 + '+ s̲\ s) p̲artition t }
ʰs̲ign : Char -> Float
A term's sign and the rest.
ʰs̲ign ← { t → (f̲irst t) = f̲irst "-" ? -1.0◆ 1.0 }
ʰw̲ell? : Truthy a => Char -> a
Whether a term is well formed: digits and at most one point before x, then nothing, x, or x^ and digits.
ʰw̲ell? ← { t → b ← ʰb̲ody t 0 = t̲ally b ? 0 = 1 k ← t̲ally w̲here b = f̲irst "x" k > 1 ? 0 = 1 k = 0 ? ʰn̲umeral? b p ← f̲irst w̲here b = f̲irst "x" c ← (p − 1) t̲ake b e ← p d̲rop b n̲ot (0 = t̲ally c) ∨ ʰn̲umeral? c ? 0 = 1 0 = t̲ally e ? 1 = 1 ⍝ x alone n̲ot "^" m̲atch 1 t̲ake e ? 0 = 1 (1 < t̲ally e) ∧ '∧ r̲/ (1 d̲rop e) m̲ember? ⎕D }
ʰn̲umeral? : Truthy a => Char -> a
Whether a text is a number: digits with at most one point.
ʰn̲umeral? ← { c → (0 < t̲ally c) ∧ ('∧ r̲/ c m̲ember? ⎕D c̲at ".") ∧ 1 ≥ t̲ally w̲here c = f̲irst "." }
ʰp̲ower : Char -> Int
A well-formed term's power of x.
ʰp̲ower ← { t → b ← ʰb̲ody t 0 = t̲ally w̲here b = f̲irst "x" ? 0 e ← (f̲irst w̲here b = f̲irst "x") d̲rop b 0 = t̲ally e ? 1 f̲loor f̲irst n̲umbers 1 d̲rop e }
ʰc̲oefficient : Char -> Float
A well-formed term's coefficient, with its sign.
ʰc̲oefficient ← { t → b ← ʰb̲ody t p ← w̲here b = f̲irst "x" c ← (f̲irst p c̲at 1 + t̲ally b) − 1 c ← c t̲ake b 0 = t̲ally c ? ʰs̲ign t (ʰs̲ign t) × f̲irst n̲umbers c }
The macro
ᵐp̲oly< : Unit -> Char -> Char
@ py:p_oly< "3x^2 - 2x + 1": the polynomial written in maths notation, compiled into its coefficients, highest power first (3.0 -2.0 1.0), when the program is compiled. Notation that is not a polynomial in x stops the compiler at it: error[bad-polynomial]. Nothing goes on the left (@).
ᵐp̲oly< ← { none t → ({ @ → 0 })_ none ⍝ the left side takes only @ (MC22) s ← ʰs̲queezed t (0 = t̲ally s) ∨ n̲ot '∧ r̲/ s m̲ember? allowed ? "bad-polynomial right" ⎕R̲EJECT t c̲at " is not a polynomial in x: use digits, x, ^, + and -" ts ← ʰt̲erms s n̲ot '∧ r̲/ '{ ʰw̲ell? d̲isclose ⍵ } e̲ach ts ? "bad-polynomial right" ⎕R̲EJECT t c̲at " is not a polynomial in x: each term is a number, x, or x^k" k ← '{ ʰp̲ower d̲isclose ⍵ } e̲ach ts c ← '{ ʰc̲oefficient d̲isclose ⍵ } e̲ach ts d ← 'm̲ax r̲/ k f̲ormat '{ i → '+ r̲/ (k = i) r̲eplicate c } e̲ach r̲ev o̲ffsets d + 1 }